From: Christoph Lameter Subject: slub: Add function to determine the amount of objects that can reside in a given slab Add a new function that determines the maximum number of objects that a given slab can accomodate. At this stage the function always returns the maximum number of objects since fallback is not available yet. Signed-off-by: Christoph Lameter --- mm/slub.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) Index: linux-2.6/mm/slub.c =================================================================== --- linux-2.6.orig/mm/slub.c 2008-02-15 11:06:38.237227456 -0800 +++ linux-2.6/mm/slub.c 2008-02-15 11:07:48.669585330 -0800 @@ -315,6 +315,11 @@ static void *slab_address(struct page *p return page->end - PAGE_MAPPING_ANON; } +static inline unsigned long slab_objects(struct kmem_cache *s, struct page *page) +{ + return s->objects; +} + static inline int check_valid_pointer(struct kmem_cache *s, struct page *page, const void *object) { @@ -324,8 +329,9 @@ static inline int check_valid_pointer(st return 1; base = slab_address(page); - if (object < base || object >= base + s->objects * s->size || - (object - base) % s->size) { + if (object < base + || object >= base + slab_objects(s, page) * s->size + || (object - base) % s->size) { return 0; } @@ -689,7 +695,7 @@ static int slab_pad_check(struct kmem_ca start = slab_address(page); end = start + (PAGE_SIZE << s->order); - length = s->objects * s->size; + length = slab_objects(s, page) * s->size; remainder = end - (start + length); if (!remainder) return 1; @@ -769,9 +775,9 @@ static int check_slab(struct kmem_cache slab_err(s, page, "Not a valid slab page"); return 0; } - if (page->inuse > s->objects) { + if (page->inuse > slab_objects(s, page)) { slab_err(s, page, "inuse %u > max %u", - s->name, page->inuse, s->objects); + s->name, page->inuse, slab_objects(s, page)); return 0; } /* Slab_pad_check fixes things up after itself */ @@ -788,8 +794,9 @@ static int on_freelist(struct kmem_cache int nr = 0; void *fp = page->freelist; void *object = NULL; + int objects = slab_objects(s, page); - while (fp != page->end && nr <= s->objects) { + while (fp != page->end && nr <= objects) { if (fp == search) return 1; if (!check_valid_pointer(s, page, fp)) { @@ -801,7 +808,7 @@ static int on_freelist(struct kmem_cache } else { slab_err(s, page, "Freepointer corrupt"); page->freelist = page->end; - page->inuse = s->objects; + page->inuse = objects; slab_fix(s, "Freelist cleared"); return 0; } @@ -812,10 +819,10 @@ static int on_freelist(struct kmem_cache nr++; } - if (page->inuse != s->objects - nr) { + if (page->inuse != objects - nr) { slab_err(s, page, "Wrong object count. Counter is %d but " - "counted were %d", page->inuse, s->objects - nr); - page->inuse = s->objects - nr; + "counted were %d", page->inuse, objects - nr); + page->inuse = objects - nr; slab_fix(s, "Object count adjusted."); } return search == NULL; @@ -905,7 +912,7 @@ bad: * as used avoids touching the remaining objects. */ slab_fix(s, "Marking all objects used"); - page->inuse = s->objects; + page->inuse = slab_objects(s, page); page->freelist = page->end; } return 0; @@ -1535,7 +1542,7 @@ load_freelist: object = c->page->freelist; c->freelist = object[c->offset]; - c->page->inuse = s->objects; + c->page->inuse = slab_objects(s, c->page); c->page->freelist = c->page->end; c->node = page_to_nid(c->page); unlock_out: