----- Original Message -----
Hi Dave,
Looks like this is because of counting the per cpu objects twice. They
are already included in kmem_cache_node.total_objects. This should fix
that. New patch attached.
diff --git a/memory.c b/memory.c
index 7b645b8..1343a11 100644
--- a/memory.c
+++ b/memory.c
@@ -17939,6 +17939,9 @@ get_kmem_cache_slub_data(long cmd, struct meminfo
*si)
total_slabs = total_objects = free_objects = 0;
+ if (VALID_MEMBER(kmem_cache_node_total_objects))
+ node_total_avail = 1;
+
for (i = 0; i < kt->cpus; i++) {
cpu_slab_ptr = get_cpu_slab_ptr(si, i, NULL);
@@ -17955,7 +17958,8 @@ get_kmem_cache_slub_data(long cmd, struct meminfo
*si)
KVADDR, &inuse, sizeof(short),
"page inuse", RETURN_ON_ERROR))
return FALSE;
- total_objects += inuse;
+ if (!node_total_avail)
+ total_objects += inuse;
total_slabs++;
break;
@@ -17992,7 +17996,6 @@ get_kmem_cache_slub_data(long cmd, struct meminfo
*si)
KVADDR, &node_total_objects, sizeof(ulong),
"kmem_cache_node total_objects", RETURN_ON_ERROR))
goto bailout;
- node_total_avail = 1;
}
switch (cmd)
(END)
Vinayak,
I still see values generated by your patch that don't make sense.
For example, take this "mm_struct" cache, which has 10 32K slabs. Each
slab has 20 objects per slab, or 200 total.
Without your patch, it shows 158 of 200 objects as allocated:
crash> kmem -s mm_struct
CACHE NAME OBJSIZE ALLOCATED TOTAL SLABS SSIZE
ffff880127c80600 mm_struct 1576 158 200 10 32k
crash>
With your patch applied, it shows all 200 of 200 objects allocated:
crash> kmem -s mm_struct
CACHE NAME OBJSIZE ALLOCATED TOTAL SLABS SSIZE
ffff880127c80600 mm_struct 1576 200 200 10 32k
crash>
But that's clearly not the case. If I run "kmem -S mm_struct" to dump the
contents of the accessible slabs, and then dump just the relevant header data,
note that there are many FREE objects that are either on a cpu cache or just
plain free:
crash> kmem -S mm_struct | grep -e SSIZE -e TOTAL -e " ffffea" -e
"k$"
CACHE NAME OBJSIZE ALLOCATED TOTAL SLABS SSIZE
ffff880127c80600 mm_struct 1576 200 200 10 32k
SLAB MEMORY NODE TOTAL ALLOCATED FREE
ffffea0004893200 ffff8801224c8000 0 20 18 2
SLAB MEMORY NODE TOTAL ALLOCATED FREE
ffffea0000d72000 ffff880035c80000 0 20 19 1
SLAB MEMORY NODE TOTAL ALLOCATED FREE
ffffea0004897000 ffff8801225c0000 0 20 15 5
SLAB MEMORY NODE TOTAL ALLOCATED FREE
ffffea00002f9400 ffff88000be50000 0 20 17 3
SLAB MEMORY NODE TOTAL ALLOCATED FREE
ffffea0002d38000 ffff8800b4e00000 0 20 12 8
SLAB MEMORY NODE TOTAL ALLOCATED FREE
ffffea0002c56a00 ffff8800b15a8000 0 20 14 6
SLAB MEMORY NODE TOTAL ALLOCATED FREE
ffffea0001925c00 ffff880064970000 0 20 15 5
SLAB MEMORY NODE TOTAL ALLOCATED FREE
ffffea0000d70c00 ffff880035c30000 0 20 13 7
SLAB MEMORY NODE TOTAL ALLOCATED FREE
ffffea0002a9f600 ffff8800aa7d8000 0 20 13 7
SLAB MEMORY NODE TOTAL ALLOCATED FREE
ffffea0002b4cc00 ffff8800ad330000 0 20 13 7
crash>
I haven't looked at the crash utility details for quite some time, but as I
recall it was trying to emulate the kernel's /proc/slabinfo determination of
the number of free objects, done here in get_slabinfo():
for_each_online_node(node) {
struct kmem_cache_node *n = get_node(s, node);
if (!n)
continue;
nr_partials += n->nr_partial;
nr_slabs += atomic_long_read(&n->nr_slabs);
nr_objs += atomic_long_read(&n->total_objects);
nr_free += count_partial(n, count_free);
}
where count_partial() uses count_free():
static int count_free(struct page *page)
{
return page->objects - page->inuse;
}
Although looking at it now, get_slabinfo() doesn't seem to take into account
the objects in the per_cpu caches?
Anyway, 200 of 200 is clearly wrong.
Dave