From b83537946e40cf56109d1f530a87379e363b056d Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Fri, 15 Feb 2008 15:22:21 -0800 Subject: [PATCH] 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. Reviewed-by: Pekka Enberg Signed-off-by: Christoph Lameter --- mm/slub.c | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) Index: linux-2.6/mm/slub.c =================================================================== --- linux-2.6.orig/mm/slub.c 2008-02-28 18:15:10.499972467 -0800 +++ linux-2.6/mm/slub.c 2008-02-28 18:16:11.212540436 -0800 @@ -291,6 +291,12 @@ static inline struct kmem_cache_cpu *get #endif } +/* Determine the maximum number of objects that a slab page can hold */ +static inline unsigned long slab_objects(struct kmem_cache *s, struct page *page) +{ + return s->objects; +} + /* Verify that a pointer has an address that is valid within a slab page */ static inline int check_valid_pointer(struct kmem_cache *s, struct page *page, const void *object) @@ -301,9 +307,10 @@ static inline int check_valid_pointer(st return 1; base = page_address(page); - if (object < base || object >= base + s->objects * s->size || - (object - base) % s->size) { - return 0; + if (object < base + || object >= base + slab_objects(s, page) * s->size + || (object - base) % s->size) { + return 0; } return 1; @@ -665,7 +672,7 @@ static int slab_pad_check(struct kmem_ca start = page_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; @@ -745,9 +752,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 */ @@ -764,8 +771,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 && nr <= s->objects) { + while (fp && nr <= objects) { if (fp == search) return 1; if (!check_valid_pointer(s, page, fp)) { @@ -777,7 +785,7 @@ static int on_freelist(struct kmem_cache } else { slab_err(s, page, "Freepointer corrupt"); page->freelist = NULL; - page->inuse = s->objects; + page->inuse = objects; slab_fix(s, "Freelist cleared"); return 0; } @@ -788,10 +796,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; @@ -881,7 +889,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 = NULL; } return 0; @@ -1488,7 +1496,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 = NULL; c->node = page_to_nid(c->page); unlock_out: