debug - Sync debug utilites, add a few more
authorMatthew Dillon <dillon@apollo.backplane.com>
Thu, 7 Nov 2013 19:51:34 +0000 (11:51 -0800)
committerMatthew Dillon <dillon@apollo.backplane.com>
Thu, 7 Nov 2013 19:51:34 +0000 (11:51 -0800)
* Sync debug utilites to recent changes and add a few more.

* Enhance zallocinfo

test/debug/checkhammer.c [new file with mode: 0644]
test/debug/crc32.c [new file with mode: 0644]
test/debug/ksyscalls.c [copied from test/debug/zallocinfo.c with 60% similarity]
test/debug/slabinfo.c [copied from test/debug/zallocinfo.c with 65% similarity]
test/debug/vmobjinfo.c [copied from test/debug/zallocinfo.c with 61% similarity]
test/debug/vmpageinfo.c
test/debug/zallocinfo.c

diff --git a/test/debug/checkhammer.c b/test/debug/checkhammer.c
new file mode 100644 (file)
index 0000000..a2a595c
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * checkhammer.c
+ *
+ * checkhammer blockmapdump btreedump
+ */
+
+#include <sys/types.h>
+#include <sys/tree.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+struct rbmap_tree;
+struct rbmap;
+
+static void parseBlockMap(FILE *fp);
+static void parseBTree(FILE *fp);
+static void dumpResults(void);
+static int rbmap_cmp(struct rbmap *, struct rbmap *);
+
+typedef u_int64_t hammer_off_t;
+typedef struct rbmap *rbmap_t;
+
+RB_HEAD(rbmap_tree, rbmap);
+RB_PROTOTYPE2(rbmap_tree, rbmap, rbentry, rbmap_cmp, hammer_off_t);
+
+struct rbmap {
+       RB_ENTRY(rbmap) rbentry;
+       hammer_off_t    base;
+       long            app;
+       long            free;
+       long            bytes;
+       int             zone;
+};
+
+RB_GENERATE2(rbmap_tree, rbmap, rbentry, rbmap_cmp, hammer_off_t, base);
+
+struct rbmap_tree rbroot;
+
+static
+int
+rbmap_cmp(struct rbmap *rb1, struct rbmap *rb2)
+{
+       if (rb1->base < rb2->base)
+               return(-1);
+       if (rb1->base > rb2->base)
+               return(1);
+       return(0);
+}
+
+int
+main(int ac, char **av)
+{
+       FILE *fp;
+
+       if (ac != 3) {
+               fprintf(stderr, "checkhammer blockmapdump btreedump\n");
+               exit(1);
+       }
+       if ((fp = fopen(av[1], "r")) == NULL) {
+               fprintf(stderr, "Unable to open %s\n", av[1]);
+               exit(1);
+       }
+
+       RB_INIT(&rbroot);
+       parseBlockMap(fp);
+       fclose(fp);
+       if ((fp = fopen(av[2], "r")) == NULL) {
+               fprintf(stderr, "Unable to open %s\n", av[1]);
+               exit(1);
+       }
+       parseBTree(fp);
+       fclose(fp);
+
+       dumpResults();
+       return(0);
+}
+
+static void
+parseBlockMap(FILE *fp)
+{
+       char buf[1024];
+       rbmap_t map;
+       int zone;
+       long long base;
+       long long app;
+       long long free;
+
+       while (fgets(buf, sizeof(buf), fp) != NULL) {
+               if (sscanf(buf, "        4%llx zone=%d app=%lld free=%lld",
+                          &base, &zone, &app, &free) != 4)
+                       continue;
+               if (RB_LOOKUP(rbmap_tree, &rbroot, (hammer_off_t)base))
+                       continue;
+               map = malloc(sizeof(*map));
+               map->base = (hammer_off_t)base;
+               map->app = (long)app;
+               map->free = (long)free;
+               map->zone = zone;
+               map->bytes = 0;
+               RB_INSERT(rbmap_tree, &rbroot, map);
+       }
+}
+
+static void
+parseBTree(FILE *fp)
+{
+       char buf[1024];
+       rbmap_t map;
+       long long base;
+       long long bytes;
+
+       while (fgets(buf, sizeof(buf), fp) != NULL) {
+               if (sscanf(buf, "     NODE 8%llx", &base) == 1) {
+                       base &= 0x0FFFFFFFFF800000LLU;
+                       map = RB_LOOKUP(rbmap_tree, &rbroot, base);
+                       if (map == NULL) {
+                               printf("(not in blockmap): %s", buf);
+                               continue;
+                       }
+                       map->bytes += 4096;
+               }
+               if (sscanf(buf, "                 dataoff=%llx/%lld",
+                          &base, &bytes) == 2) {
+                       base &= 0x0FFFFFFFFF800000LLU;
+                       map = RB_LOOKUP(rbmap_tree, &rbroot, base);
+                       if (map == NULL) {
+                               printf("(not in blockmap): %s", buf);
+                               continue;
+                       }
+                       map->bytes += (bytes + 15) & ~15;
+               }
+       }
+}
+
+static void
+dumpResults(void)
+{
+       rbmap_t map;
+       hammer_off_t bfree;
+
+       printf("mismatches: (blockmap, actual)\n");
+       RB_FOREACH(map, rbmap_tree, &rbroot) {
+               bfree = 8192 * 1024 - (int64_t)map->bytes;
+
+               /*
+                * Ignore matches
+                */
+               if (map->free == bfree)
+                       continue;
+
+               /*
+                * If the block is completely allocated but our calculations
+                * show nobody is referencing it it is probably an undo,
+                * blockmap, or unavailable reserved area.
+                */
+               if (map->free == 0 && bfree == 8192 * 1024) {
+                       if (map->zone == 3 || map->zone == 4 ||
+                           map->zone == 15)
+                               continue;
+               }
+
+               printf(" bmap %016jx %jd %jd\n",
+                       map->base,
+                       (intmax_t)(int64_t)map->free,
+                       (intmax_t)(int64_t)bfree);
+       }
+}
diff --git a/test/debug/crc32.c b/test/debug/crc32.c
new file mode 100644 (file)
index 0000000..cf7b275
--- /dev/null
@@ -0,0 +1,22 @@
+
+/*
+ * cc crc32.c /usr/src/sys/libkern/crc32.c -o /usr/local/bin/crc32
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+int
+main(int ac, char **av)
+{
+    char buf[256];
+    int n;
+    u_int32_t crc = crc32(NULL, 0);
+
+    while ((n = read(0, buf, sizeof(buf))) > 0)
+       crc = crc32_ext(buf, n, crc);
+    printf("crc %08x\n", crc);
+    return(0);
+}
similarity index 60%
copy from test/debug/zallocinfo.c
copy to test/debug/ksyscalls.c
index f17f8bf..11250d1 100644 (file)
@@ -1,13 +1,11 @@
 /*
- * ZALLOCINFO.C
+ * KSYSCALLS.C
  *
- * cc -I/usr/src/sys zallocinfo.c -o /usr/local/bin/zallocinfo -lkvm
+ * cc -I/usr/src/sys ksyscalls.c -o /usr/local/bin/ksyscalls -lkvm
  *
- * zallocinfo
+ * Dump syscall debugging info
  *
- * Print the slab structure and chains for all cpus.
- *
- * Copyright (c) 2010 The DragonFly Project.  All rights reserved.
+ * Copyright (c) 2011 The DragonFly Project.  All rights reserved.
  *
  * This code is derived from software contributed to The DragonFly Project
  * by Matthew Dillon <dillon@backplane.com>
 #include <sys/param.h>
 #include <sys/user.h>
 #include <sys/malloc.h>
-#include <sys/slaballoc.h>
 #include <sys/signalvar.h>
-#include <sys/globaldata.h>
-#include <machine/globaldata.h>
+#include <sys/vnode.h>
+#include <sys/namecache.h>
+#include <sys/syscall.h>
 
 #include <vm/vm.h>
 #include <vm/vm_page.h>
 #include <vm/vm_kern.h>
 #include <vm/vm_page.h>
 #include <vm/vm_object.h>
+#include <vm/vm_map.h>
 #include <vm/swap_pager.h>
 #include <vm/vnode_pager.h>
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <stddef.h>
 #include <fcntl.h>
 #include <kvm.h>
 #include <nlist.h>
 #include <getopt.h>
 
 struct nlist Nl[] = {
-    { "_CPU_prvspace" },
-    { "_ncpus" },
+    { "_SysCallsWorstCase" },
     { NULL }
 };
 
-int debugopt;
-int verboseopt;
-
-static void dumpslab(kvm_t *kd, int cpu, struct SLGlobalData *slab);
 static void kkread(kvm_t *kd, u_long addr, void *buf, size_t nbytes);
 
 int
@@ -83,21 +76,13 @@ main(int ac, char **av)
 {
     const char *corefile = NULL;
     const char *sysfile = NULL;
-    struct SLGlobalData slab;
     kvm_t *kd;
-    int offset;
-    int ncpus;
     int ch;
     int i;
+    uint64_t syscallsworstcase[SYS_MAXSYSCALL];
 
-    while ((ch = getopt(ac, av, "M:N:dv")) != -1) {
+    while ((ch = getopt(ac, av, "M:N:")) != -1) {
        switch(ch) {
-       case 'd':
-           ++debugopt;
-           break;
-       case 'v':
-           ++verboseopt;
-           break;
        case 'M':
            corefile = optarg;
            break;
@@ -120,58 +105,19 @@ main(int ac, char **av)
        perror("kvm_nlist");
        exit(1);
     }
+    kkread(kd, Nl[0].n_value, syscallsworstcase, sizeof(syscallsworstcase));
 
-    kkread(kd, Nl[1].n_value, &ncpus, sizeof(ncpus));
-    offset = offsetof(struct privatespace, mdglobaldata.mi.gd_slab);
-    for (i = 0; i < ncpus; ++i) {
-           kkread(kd, Nl[0].n_value + sizeof(struct privatespace) * i + offset, &slab, sizeof(slab));
-           dumpslab(kd, i, &slab);
-    }
-    printf("Done\n");
-    return(0);
-}
-
-static void
-dumpslab(kvm_t *kd, int cpu, struct SLGlobalData *slab)
-{
-    struct SLZone *zonep;
-    struct SLZone zone;
-    int i;
-    int first;
-    int64_t save;
-    int64_t extra = 0;
-
-    printf("cpu %d NFreeZones=%d\n", cpu, slab->NFreeZones);
-
-    for (i = 0; i < NZONES; ++i) {
-       if ((zonep = slab->ZoneAry[i]) == NULL)
-               continue;
-       printf("    zone %2d", i);
-       first = 1;
-       save = extra;
-       while (zonep) {
-               kkread(kd, (u_long)zonep, &zone, sizeof(zone));
-               if (first) {
-                       printf(" chunk=%-5d elms=%-4d free:",
-                               zone.z_ChunkSize, zone.z_NMax);
-               }
-               if (first == 0)
-                       printf(",");
-               printf(" %d", zone.z_NFree);
-               extra += zone.z_NFree * zone.z_ChunkSize;
-               zonep = zone.z_Next;
-               first = 0;
-       }
-       printf(" (%jdK free)\n", (intmax_t)(extra - save) / 1024);
+    for (i = 0; i < SYS_MAXSYSCALL; ++i) {
+       if (syscallsworstcase[i])
+               printf("call %3d %6jduS\n", i, (intmax_t)syscallsworstcase[i]);
     }
-    printf("    TotalUnused %jdM\n", (intmax_t)extra / 1024 / 1024);
 }
 
 static void
 kkread(kvm_t *kd, u_long addr, void *buf, size_t nbytes)
 {
     if (kvm_read(kd, addr, buf, nbytes) != nbytes) {
-           perror("kvm_read");
-           exit(1);
+        perror("kvm_read");
+        exit(1);
     }
 }
similarity index 65%
copy from test/debug/zallocinfo.c
copy to test/debug/slabinfo.c
index f17f8bf..47a9ca5 100644 (file)
@@ -1,13 +1,13 @@
 /*
- * ZALLOCINFO.C
+ * SLABINFO.C
  *
- * cc -I/usr/src/sys zallocinfo.c -o /usr/local/bin/zallocinfo -lkvm
+ * cc -I/usr/src/sys slabinfo.c -o /usr/local/bin/slabinfo -lkvm
  *
- * zallocinfo
+ * slabinfo
  *
- * Print the slab structure and chains for all cpus.
+ * dump kernel slab allocator pcpu data and chains
  *
- * Copyright (c) 2010 The DragonFly Project.  All rights reserved.
+ * Copyright (c) 2012 The DragonFly Project.  All rights reserved.
  *
  * This code is derived from software contributed to The DragonFly Project
  * by Matthew Dillon <dillon@backplane.com>
  * SUCH DAMAGE.
  */
 
-#define _KERNEL_STRUCTURES_
+#define _KERNEL_STRUCTURES
 #include <sys/param.h>
 #include <sys/user.h>
 #include <sys/malloc.h>
-#include <sys/slaballoc.h>
 #include <sys/signalvar.h>
+#include <sys/vnode.h>
+#include <sys/namecache.h>
 #include <sys/globaldata.h>
 #include <machine/globaldata.h>
+#include <sys/slaballoc.h>
 
 #include <vm/vm.h>
 #include <vm/vm_page.h>
@@ -60,7 +62,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <stddef.h>
 #include <fcntl.h>
 #include <kvm.h>
 #include <nlist.h>
@@ -75,20 +76,22 @@ struct nlist Nl[] = {
 int debugopt;
 int verboseopt;
 
-static void dumpslab(kvm_t *kd, int cpu, struct SLGlobalData *slab);
-static void kkread(kvm_t *kd, u_long addr, void *buf, size_t nbytes);
+int slzonedump(kvm_t *kd, SLZone *kslz);
+void kkread(kvm_t *kd, u_long addr, void *buf, size_t nbytes);
 
 int
 main(int ac, char **av)
 {
     const char *corefile = NULL;
     const char *sysfile = NULL;
-    struct SLGlobalData slab;
     kvm_t *kd;
-    int offset;
-    int ncpus;
     int ch;
     int i;
+    int j;
+    int ncpus;
+    int totalzones;
+    int totalfree;
+    struct globaldata gd;
 
     while ((ch = getopt(ac, av, "M:N:dv")) != -1) {
        switch(ch) {
@@ -121,57 +124,60 @@ main(int ac, char **av)
        exit(1);
     }
 
-    kkread(kd, Nl[1].n_value, &ncpus, sizeof(ncpus));
-    offset = offsetof(struct privatespace, mdglobaldata.mi.gd_slab);
+    kkread(kd, Nl[1].n_value, &ncpus, sizeof(int));
+    totalzones = 0;
+    totalfree = 0;
     for (i = 0; i < ncpus; ++i) {
-           kkread(kd, Nl[0].n_value + sizeof(struct privatespace) * i + offset, &slab, sizeof(slab));
-           dumpslab(kd, i, &slab);
+       kkread(kd, Nl[0].n_value + i * sizeof(struct privatespace), &gd, sizeof(gd));
+       printf("CPU %02d (NFreeZones=%d) {\n",
+               i, gd.gd_slab.NFreeZones);
+       totalfree += gd.gd_slab.NFreeZones;
+
+       for (j = 0; j < NZONES; ++j) {
+               printf("    Zone %02d {\n", j);
+               totalzones += slzonedump(kd, gd.gd_slab.ZoneAry[j]);
+               printf("    }\n");
+       }
+
+       printf("    FreeZone {\n");
+       totalzones += slzonedump(kd, gd.gd_slab.FreeZones);
+       printf("    }\n");
+
+       printf("    FreeOVZon {\n");
+       totalzones += slzonedump(kd, gd.gd_slab.FreeOvZones);
+       printf("    }\n");
+
+       printf("}\n");
     }
-    printf("Done\n");
+    printf("TotalZones %d x 131072 = %jd\n",
+       totalzones, (intmax_t)totalzones * 131072LL);
+    printf("TotalFree  %d x 131072 = %jd\n",
+       totalfree, (intmax_t)totalfree * 131072LL);
     return(0);
 }
 
-static void
-dumpslab(kvm_t *kd, int cpu, struct SLGlobalData *slab)
+int
+slzonedump(kvm_t *kd, SLZone *kslz)
 {
-    struct SLZone *zonep;
-    struct SLZone zone;
-    int i;
-    int first;
-    int64_t save;
-    int64_t extra = 0;
-
-    printf("cpu %d NFreeZones=%d\n", cpu, slab->NFreeZones);
-
-    for (i = 0; i < NZONES; ++i) {
-       if ((zonep = slab->ZoneAry[i]) == NULL)
-               continue;
-       printf("    zone %2d", i);
-       first = 1;
-       save = extra;
-       while (zonep) {
-               kkread(kd, (u_long)zonep, &zone, sizeof(zone));
-               if (first) {
-                       printf(" chunk=%-5d elms=%-4d free:",
-                               zone.z_ChunkSize, zone.z_NMax);
-               }
-               if (first == 0)
-                       printf(",");
-               printf(" %d", zone.z_NFree);
-               extra += zone.z_NFree * zone.z_ChunkSize;
-               zonep = zone.z_Next;
-               first = 0;
-       }
-       printf(" (%jdK free)\n", (intmax_t)(extra - save) / 1024);
+    SLZone slz;
+    int count = 0;
+
+    while (kslz) {
+       kkread(kd, (u_long)kslz, &slz, sizeof(slz));
+       printf("\t{ magic=%08x cpu=%d chunking=%d NFree=%d/%d RCnt=%d}\n",
+               slz.z_Magic, slz.z_Cpu, slz.z_ChunkSize,
+               slz.z_NFree, slz.z_NMax, slz.z_RCount);
+       kslz = slz.z_Next;
+       ++count;
     }
-    printf("    TotalUnused %jdM\n", (intmax_t)extra / 1024 / 1024);
+    return(count);
 }
 
-static void
+void
 kkread(kvm_t *kd, u_long addr, void *buf, size_t nbytes)
 {
     if (kvm_read(kd, addr, buf, nbytes) != nbytes) {
-           perror("kvm_read");
-           exit(1);
+        perror("kvm_read");
+        exit(1);
     }
 }
similarity index 61%
copy from test/debug/zallocinfo.c
copy to test/debug/vmobjinfo.c
index f17f8bf..796aa6d 100644 (file)
@@ -1,11 +1,9 @@
 /*
- * ZALLOCINFO.C
+ * VMOBJINFO.C
  *
- * cc -I/usr/src/sys zallocinfo.c -o /usr/local/bin/zallocinfo -lkvm
+ * cc -I/usr/src/sys vmobjinfo.c -o /usr/local/bin/vmobjinfo -lkvm
  *
- * zallocinfo
- *
- * Print the slab structure and chains for all cpus.
+ * Dump all vm_object's in the system
  *
  * Copyright (c) 2010 The DragonFly Project.  All rights reserved.
  *
  * SUCH DAMAGE.
  */
 
-#define _KERNEL_STRUCTURES_
+#define _KERNEL_STRUCTURES
 #include <sys/param.h>
 #include <sys/user.h>
 #include <sys/malloc.h>
-#include <sys/slaballoc.h>
 #include <sys/signalvar.h>
-#include <sys/globaldata.h>
-#include <machine/globaldata.h>
+#include <sys/namecache.h>
+#include <sys/mount.h>
+#include <sys/vnode.h>
+#include <sys/buf.h>
 
 #include <vm/vm.h>
 #include <vm/vm_page.h>
 #include <vm/vm_kern.h>
-#include <vm/vm_page.h>
 #include <vm/vm_object.h>
 #include <vm/swap_pager.h>
 #include <vm/vnode_pager.h>
 
+#include <vfs/ufs/quota.h>
+#include <vfs/ufs/inode.h>
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <stddef.h>
 #include <fcntl.h>
 #include <kvm.h>
 #include <nlist.h>
 #include <getopt.h>
 
+TAILQ_HEAD(object_q, vm_object);
+
 struct nlist Nl[] = {
-    { "_CPU_prvspace" },
-    { "_ncpus" },
+    { "_vm_object_list" },
     { NULL }
 };
 
-int debugopt;
-int verboseopt;
-
-static void dumpslab(kvm_t *kd, int cpu, struct SLGlobalData *slab);
+static void scan_vmobjs(kvm_t *kd, struct object_q *obj_list);
 static void kkread(kvm_t *kd, u_long addr, void *buf, size_t nbytes);
 
 int
 main(int ac, char **av)
 {
-    const char *corefile = NULL;
-    const char *sysfile = NULL;
-    struct SLGlobalData slab;
+    struct object_q obj_list;
     kvm_t *kd;
-    int offset;
-    int ncpus;
-    int ch;
     int i;
+    int ch;
+    const char *corefile = NULL;
+    const char *sysfile = NULL;
 
-    while ((ch = getopt(ac, av, "M:N:dv")) != -1) {
+    while ((ch = getopt(ac, av, "M:N:")) != -1) {
        switch(ch) {
-       case 'd':
-           ++debugopt;
-           break;
-       case 'v':
-           ++verboseopt;
-           break;
        case 'M':
            corefile = optarg;
            break;
@@ -109,8 +99,6 @@ main(int ac, char **av)
            exit(1);
        }
     }
-    ac -= optind;
-    av += optind;
 
     if ((kd = kvm_open(sysfile, corefile, NULL, O_RDONLY, "kvm:")) == NULL) {
        perror("kvm_open");
@@ -120,58 +108,34 @@ main(int ac, char **av)
        perror("kvm_nlist");
        exit(1);
     }
-
-    kkread(kd, Nl[1].n_value, &ncpus, sizeof(ncpus));
-    offset = offsetof(struct privatespace, mdglobaldata.mi.gd_slab);
-    for (i = 0; i < ncpus; ++i) {
-           kkread(kd, Nl[0].n_value + sizeof(struct privatespace) * i + offset, &slab, sizeof(slab));
-           dumpslab(kd, i, &slab);
-    }
-    printf("Done\n");
+    kkread(kd, Nl[0].n_value, &obj_list, sizeof(obj_list));
+    scan_vmobjs(kd, &obj_list);
     return(0);
 }
 
 static void
-dumpslab(kvm_t *kd, int cpu, struct SLGlobalData *slab)
+scan_vmobjs(kvm_t *kd, struct object_q *obj_list)
 {
-    struct SLZone *zonep;
-    struct SLZone zone;
-    int i;
-    int first;
-    int64_t save;
-    int64_t extra = 0;
+    struct vm_object *op;
+    struct vm_object obj;
 
-    printf("cpu %d NFreeZones=%d\n", cpu, slab->NFreeZones);
+    op = TAILQ_FIRST(obj_list);
+    while (op) {
+       kkread(kd, (long)op, &obj, sizeof(obj));
 
-    for (i = 0; i < NZONES; ++i) {
-       if ((zonep = slab->ZoneAry[i]) == NULL)
-               continue;
-       printf("    zone %2d", i);
-       first = 1;
-       save = extra;
-       while (zonep) {
-               kkread(kd, (u_long)zonep, &zone, sizeof(zone));
-               if (first) {
-                       printf(" chunk=%-5d elms=%-4d free:",
-                               zone.z_ChunkSize, zone.z_NMax);
-               }
-               if (first == 0)
-                       printf(",");
-               printf(" %d", zone.z_NFree);
-               extra += zone.z_NFree * zone.z_ChunkSize;
-               zonep = zone.z_Next;
-               first = 0;
-       }
-       printf(" (%jdK free)\n", (intmax_t)(extra - save) / 1024);
+       printf("%p type=%d size=%016jx handle=%p swblocks=%d\n",
+               op, obj.type, (intmax_t)obj.size, obj.handle,
+               obj.swblock_count);
+
+       op = TAILQ_NEXT(&obj, object_list);
     }
-    printf("    TotalUnused %jdM\n", (intmax_t)extra / 1024 / 1024);
 }
 
 static void
 kkread(kvm_t *kd, u_long addr, void *buf, size_t nbytes)
 {
     if (kvm_read(kd, addr, buf, nbytes) != nbytes) {
-           perror("kvm_read");
-           exit(1);
+        perror("kvm_read");
+        exit(1);
     }
 }
index 049931f..349ef17 100644 (file)
@@ -246,11 +246,15 @@ main(int ac, char **av)
                printf(" RAM");
            if (m.flags & PG_SWAPPED)
                printf(" SWAPPED");
+#if 0
            if (m.flags & PG_SLAB)
                printf(" SLAB");
+#endif
            printf("\n");
+#if 0
            if (m.flags & PG_SLAB)
                addsltrack(&m);
+#endif
        }
     }
     if (debugopt || verboseopt)
index f17f8bf..c369230 100644 (file)
@@ -136,7 +136,10 @@ dumpslab(kvm_t *kd, int cpu, struct SLGlobalData *slab)
 {
     struct SLZone *zonep;
     struct SLZone zone;
+    SLChunk *chunkp;
+    SLChunk chunk;
     int i;
+    int rcount;
     int first;
     int64_t save;
     int64_t extra = 0;
@@ -161,6 +164,29 @@ dumpslab(kvm_t *kd, int cpu, struct SLGlobalData *slab)
                extra += zone.z_NFree * zone.z_ChunkSize;
                zonep = zone.z_Next;
                first = 0;
+
+               chunkp = zone.z_RChunks;
+               rcount = 0;
+               while (chunkp) {
+                       kkread(kd, (u_long)chunkp, &chunk, sizeof(chunk));
+                       chunkp = chunk.c_Next;
+                       ++rcount;
+               }
+               if (rcount) {
+                       printf(" rchunks=%d", rcount);
+                       extra += rcount * zone.z_ChunkSize;
+               }
+               chunkp = zone.z_LChunks;
+               rcount = 0;
+               while (chunkp) {
+                       kkread(kd, (u_long)chunkp, &chunk, sizeof(chunk));
+                       chunkp = chunk.c_Next;
+                       ++rcount;
+               }
+               if (rcount) {
+                       printf(" lchunks=%d", rcount);
+                       extra += rcount * zone.z_ChunkSize;
+               }
        }
        printf(" (%jdK free)\n", (intmax_t)(extra - save) / 1024);
     }