[PATCH] fix vmstat handling
                                
                                
                                
                                    
                                        by vinayak menon
                                    
                                
                                
                                        From: Vinayak Menon <vinayakm.list(a)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(a)gmail.com>
---
 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;
                                
                         
                        
                                
                                7 years, 12 months
                        
                        
                 
         
 
        
            
        
        
        
                
                        
                        
                                
                                
                                        
                                                
                                        
                                        
                                        [PATCH] fix "ps -l"
                                
                                
                                
                                    
                                        by vinayak menon
                                    
                                
                                
                                        fix segfault when executing "ps -l".
Signed-off-by: Vinayak Menon <vinayakm.list(a)gmail.com>
---
 task.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/task.c b/task.c
index 5754159..f2628b7 100644
--- a/task.c
+++ b/task.c
@@ -3485,7 +3485,7 @@ show_last_run(struct task_context *tc, struct psinfo *psi)
        sprintf(format, "[%c%dll%c] ", '%', c,
                pc->output_radix == 10 ? 'u' : 'x');
-       if (psi) {
+       if (psi && psi->cpus) {
                for (c = others = 0; c < kt->cpus; c++) {
                        if (!NUM_IN_BITMAP(psi->cpus, c))
                                continue;
--
                                
                         
                        
                                
                                8 years
                        
                        
                 
         
 
        
            
        
        
        
                
                        
                        
                                
                                
                                        
                                                
                                        
                                        
                                        [PATCH 0/1] Add option to filter disks with no I/O in progress
                                
                                
                                
                                    
                                        by Oleksandr Natalenko
                                    
                                
                                
                                        While analyzing vmcores the first thing that people do when they want
to check disk I/O is something like this:
crash> dev -d | awk '$5 != 0'
Since there might be lots of disks, this makes scrolling through them
much easier.
I think we should have this option implemented for dev command itself.
Oleksandr Natalenko (1):
  dev: add option to filter disks with no I/O
 dev.c  | 27 +++++++++++++++++++--------
 help.c |  1 +
 2 files changed, 20 insertions(+), 8 deletions(-)
-- 
2.15.0
                                
                         
                        
                                
                                8 years
                        
                        
                 
         
 
        
            
        
        
        
                
                        
                                
                                
                                        
                                
                         
                        
                                
                                
                                        
                                                
                                        
                                        
                                        [PATCH RFC 00/14] Minor code cleanups, round zero
                                
                                
                                
                                    
                                        by Oleksandr Natalenko
                                    
                                
                                
                                        I've managed to instigate clang to build some pieces
of crash-utility code, and it showed unpleasant things
which I'd like to bring into your attention.
The patch bomb contains only minor nitpicks to check
whether I should continue with doing this kind of nasty job
further using static analysis tools, various compilers
and common sense.
Oleksandr Natalenko (14):
  tools: fix non-literal NULL conversion
  memory: do not compare unsigned expression with negative value
  memory: use & for a bitwise operation
  task: remove extra parentheses in equality comparison
  x86_64: clarify logical operator precedence
  lkcd_v1: address of an array always evaluates to true
  lkcd_v2_v3: address of an array always evaluates to true
  lkcd_v5: address of an array always evaluates to true
  lkcd_v7: address of an array always evaluates to true
  lkcd_v8: address of an array always evaluates to true
  qemu-load: remove unused function get_le64()
  sadump: block_size is always non-negative
  task: format string should be never empty
  symbols: format string should be never empty
 lkcd_v1.c    |  2 +-
 lkcd_v2_v3.c |  2 +-
 lkcd_v5.c    |  2 +-
 lkcd_v7.c    |  2 +-
 lkcd_v8.c    |  2 +-
 memory.c     |  8 ++++----
 qemu-load.c  |  8 --------
 sadump.c     |  3 ---
 symbols.c    |  9 +++++----
 task.c       | 20 +++++++++++---------
 tools.c      |  2 +-
 x86_64.c     |  4 ++--
 12 files changed, 28 insertions(+), 36 deletions(-)
-- 
2.14.3
                                
                         
                        
                                
                                8 years