[Crash-utility] [PATCH] fix vmstat handling

Dave Anderson anderson at redhat.com
Thu Nov 2 15:28:07 UTC 2017



----- Original Message -----
> From: Vinayak Menon <vinayakm.list at gmail.com>
> 
> With kernels where LRUs are moved to node and thus vm_stat is
> split into zone and node, crash utility fails to show the vmstat with "kmem
> -V", and the "CACHED" of kmem -i is shown as zero.
> 
> Signed-off-by: Vinayak Menon <vinayakm.list at gmail.com>

Nice -- thanks for catching this!

But can you re-send the patch as an attachment?  It appears that the
inlined patch below has all tabs replaced with spaces:

  $ patch -p1 < $dl/vmstat.patch
  patching file memory.c
  Hunk #1 FAILED at 17340.
  Hunk #2 succeeded at 17372 with fuzz 1.
  Hunk #3 FAILED at 17391.
  Hunk #4 FAILED at 17417.
  Hunk #5 FAILED at 17451.
  4 out of 5 hunks FAILED -- saving rejects to file memory.c.rej
  $

Hunk 2 succeeded because the code section it's changing has no tabs! 

Thanks again,
  Dave



> ---
>  memory.c | 97
>  ++++++++++++++++++++++++++++++++++++++++++++++++++--------------
>  1 file changed, 76 insertions(+), 21 deletions(-)
> 
> diff --git a/memory.c b/memory.c
> index ebd671a..3097558 100644
> --- a/memory.c
> +++ b/memory.c
> @@ -17340,30 +17340,43 @@ vm_stat_init(void)
>         int c ATTRIBUTE_UNUSED;
>          struct gnu_request *req;
>         char *start;
> -       long enum_value;
> +       long enum_value, zc = -1;
> +       int split_vmstat = 0, ni = 0;
> 
>         if (vt->flags & VM_STAT)
>                 return TRUE;
> 
> -       if ((vt->nr_vm_stat_items == -1) || !symbol_exists("vm_stat"))
> +       if ((vt->nr_vm_stat_items == -1) ||
> +               (!symbol_exists("vm_stat") &&
> !symbol_exists("vm_zone_stat")))
>                 goto bailout;
> 
>          /*
>           *  look for type: type = atomic_long_t []
>           */
>         if (LKCD_KERNTYPES()) {
> -               if (!symbol_exists("vm_stat"))
> +               if ((!symbol_exists("vm_stat") &&
> +                               !symbol_exists("vm_zone_stat")))
>                         goto bailout;
>                 /*
>                  *  Just assume that vm_stat is an array; there is
>                  *  no symbol info in a kerntypes file.
>                  */
>         } else {
> -               if (!symbol_exists("vm_stat") ||
> -                   get_symbol_type("vm_stat", NULL, NULL) !=
> TYPE_CODE_ARRAY)
> +               if (symbol_exists("vm_stat") &&
> +                   get_symbol_type("vm_stat", NULL, NULL) ==
> TYPE_CODE_ARRAY) {
> +                       vt->nr_vm_stat_items =
> +                               get_array_length("vm_stat", NULL, 0);
> +               } else if (symbol_exists("vm_zone_stat") &&
> +                       get_symbol_type("vm_zone_stat",
> +                       NULL, NULL) == TYPE_CODE_ARRAY) {
> +                       vt->nr_vm_stat_items =
> +                               get_array_length("vm_zone_stat", NULL, 0)
> +                               + get_array_length("vm_node_stat", NULL, 0);
> +                       split_vmstat = 1;
> +                       enumerator_value("NR_VM_ZONE_STAT_ITEMS", &zc);
> +               } else {
>                         goto bailout;
> -
> -               vt->nr_vm_stat_items = get_array_length("vm_stat", NULL, 0);
> +               }
>         }
> 
>          open_tmpfile();
> @@ -17372,6 +17385,14 @@ vm_stat_init(void)
>          req->name = "zone_stat_item";
>          req->flags = GNU_PRINT_ENUMERATORS;
>          gdb_interface(req);
> +
> +       if (split_vmstat) {
> +               req->command = GNU_GET_DATATYPE;
> +               req->name = "node_stat_item";
> +               req->flags = GNU_PRINT_ENUMERATORS;
> +               gdb_interface(req);
> +       }
> +
>          FREEBUF(req);
> 
>         stringlen = 1;
> @@ -17383,11 +17404,17 @@ vm_stat_init(void)
>                         continue;
>                 clean_line(buf);
>                 c = parse_line(buf, arglist);
> -               if (STREQ(arglist[0], "NR_VM_ZONE_STAT_ITEMS")) {
> +               if ((!split_vmstat &&
> +                       STREQ(arglist[0], "NR_VM_ZONE_STAT_ITEMS")) ||
> +                       (split_vmstat &&
> +                       STREQ(arglist[0], "NR_VM_NODE_STAT_ITEMS"))) {
>                         if (LKCD_KERNTYPES())
>                                 vt->nr_vm_stat_items =
>                                         MAX(atoi(arglist[2]), count);
>                         break;
> +               } else if (split_vmstat &&
> +                       STREQ(arglist[0], "NR_VM_ZONE_STAT_ITEMS")) {
> +                       continue;
>                 } else {
>                         stringlen += strlen(arglist[0]);
>                         count++;
> @@ -17409,18 +17436,24 @@ vm_stat_init(void)
>                  if (strstr(buf, "{") || strstr(buf, "}"))
>                          continue;
>                 c = parse_line(buf, arglist);
> -               if (enumerator_value(arglist[0], &enum_value))
> -                       i = enum_value;
> -               else {
> +               if (!enumerator_value(arglist[0], &enum_value)) {
>                         close_tmpfile();
>                         goto bailout;
>                 }
> +
> +               i = ni + enum_value;
> +               if (!ni && (enum_value == zc)) {
> +                       ni = zc;
> +                       continue;
> +               }
> +
>                 if (i < vt->nr_vm_stat_items) {
>                         vt->vm_stat_items[i] = start;
>                         strcpy(start, arglist[0]);
>                         start += strlen(arglist[0]) + 1;
>                 }
>          }
> +
>         close_tmpfile();
> 
>         vt->flags |= VM_STAT;
> @@ -17443,39 +17476,61 @@ dump_vm_stat(char *item, long *retval, ulong zone)
>         ulong *vp;
>         ulong location;
>         int i, maxlen, len;
> +       long tc, zc = 0, nc = 0;
> +       int split_vmstat = 0;
> 
>         if (!vm_stat_init()) {
>                 if (!item)
>                         if (CRASHDEBUG(1))
> -                               error(INFO,
> +                               error(INFO,
>                                     "vm_stat not available in this
>                                     kernel\n");
>                 return FALSE;
>         }
> 
>         buf = GETBUF(sizeof(ulong) * vt->nr_vm_stat_items);
> 
> -       location = zone ? zone : symbol_value("vm_stat");
> -
> -       readmem(location, KVADDR, buf,
> -           sizeof(ulong) * vt->nr_vm_stat_items,
> -           "vm_stat", FAULT_ON_ERROR);
> +       if (symbol_exists("vm_node_stat") && symbol_exists("vm_zone_stat"))
> +               split_vmstat = 1;
> +       else
> +               location = zone ? zone : symbol_value("vm_stat");
> +
> +       if (split_vmstat) {
> +               enumerator_value("NR_VM_ZONE_STAT_ITEMS", &zc);
> +               location = zone ? zone : symbol_value("vm_zone_stat");
> +               readmem(location, KVADDR, buf,
> +                       sizeof(ulong) * zc,
> +                       "vm_zone_stat", FAULT_ON_ERROR);
> +               if (!zone) {
> +                       location = symbol_value("vm_node_stat");
> +                       enumerator_value("NR_VM_NODE_STAT_ITEMS", &nc);
> +                       readmem(location, KVADDR, buf + (sizeof(ulong) * zc),
> +                               sizeof(ulong) * nc,
> +                               "vm_node_stat", FAULT_ON_ERROR);
> +               }
> +               tc = zc + nc;
> +       } else {
> +               readmem(location, KVADDR, buf,
> +                       sizeof(ulong) * vt->nr_vm_stat_items,
> +                       "vm_stat", FAULT_ON_ERROR);
> +               tc = vt->nr_vm_stat_items;
> +       }
> 
>         if (!item) {
>                 if (!zone)
>                         fprintf(fp, "  VM_STAT:\n");
> -               for (i = maxlen = 0; i < vt->nr_vm_stat_items; i++)
> +               for (i = maxlen = 0; i < tc; i++)
>                         if ((len = strlen(vt->vm_stat_items[i])) > maxlen)
>                                 maxlen = len;
>                 vp = (ulong *)buf;
> -               for (i = 0; i < vt->nr_vm_stat_items; i++)
> -                       fprintf(fp, "%s%s: %ld\n",
> +               for (i = 0; i < tc; i++)
> +                       fprintf(fp, "%s%s: %ld\n",
>                                 space(maxlen - strlen(vt->vm_stat_items[i])),
>                                  vt->vm_stat_items[i], vp[i]);
>                 return TRUE;
>         }
> 
>         vp = (ulong *)buf;
> -       for (i = 0; i < vt->nr_vm_stat_items; i++) {
> +       for (i = 0; i < tc; i++) {
>                 if (STREQ(vt->vm_stat_items[i], item)) {
>                         *retval = vp[i];
>                         return TRUE;
> 




More information about the Crash-utility mailing list