[Crash-utility] wrong values shown by kmem -s

Dave Anderson anderson at redhat.com
Fri Mar 11 20:21:03 UTC 2016



----- 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






More information about the Crash-utility mailing list