[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