From: Christoph Lameter Object counting did not take into account that the number of full slabs is the total number of slabs - number of partial - number of cpu slabs. As a results the counts were off a bit. This issue surfaced when slab validation was implemented. Signed-off-by: Christoph Lameter Signed-off-by: Andrew Morton --- mm/slub.c | 61 ++++++++++++++++++++++++++++------------------------ 1 files changed, 34 insertions(+), 27 deletions(-) diff -puN mm/slub.c~slub-core-fix-object-counting mm/slub.c --- a/mm/slub.c~slub-core-fix-object-counting +++ a/mm/slub.c @@ -2348,23 +2348,34 @@ static unsigned long slab_objects(struct int node; int x; unsigned long *nodes; + unsigned long *per_cpu; - nodes = kmalloc(sizeof(unsigned long) * nr_node_ids, GFP_KERNEL); + nodes = kzalloc(2 * sizeof(unsigned long) * nr_node_ids, GFP_KERNEL); + per_cpu = nodes + nr_node_ids; + + for_each_possible_cpu(cpu) { + struct page *page = s->cpu_slab[cpu]; + int node; + + if (page) { + node = page_to_nid(page); + if (flags & SO_CPU) { + int x = 0; + + if (flags & SO_OBJECTS) + x = page->inuse; + else + x = 1; + total += x; + nodes[node] += x; + } + per_cpu[node]++; + } + } for_each_online_node(node) { struct kmem_cache_node *n = get_node(s, node); - nodes[node] = 0; - - if (flags & SO_FULL) { - if (flags & SO_OBJECTS) - x = atomic_read(&n->nr_slabs) - * s->objects; - else - x = atomic_read(&n->nr_slabs); - total += x; - nodes[node] += x; - } if (flags & SO_PARTIAL) { if (flags & SO_OBJECTS) x = count_partial(n); @@ -2373,24 +2384,20 @@ static unsigned long slab_objects(struct total += x; nodes[node] += x; } - } - - if (flags & SO_CPU) - for_each_possible_cpu(cpu) { - struct page *page = s->cpu_slab[cpu]; - if (page) { - int x = 0; - int node = page_to_nid(page); + if (flags & SO_FULL) { + int full_slabs = atomic_read(&n->nr_slabs) + - per_cpu[node] + - n->nr_partial; - if (flags & SO_OBJECTS) - x = page->inuse; - else - x = 1; - total += x; - nodes[node] += x; - } + if (flags & SO_OBJECTS) + x = full_slabs * s->objects; + else + x = full_slabs; + total += x; + nodes[node] += x; } + } x = sprintf(buf, "%lu", total); #ifdef CONFIG_NUMA _