From 6052a76a1877e622b2e6e61f314894a819037d76 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Fri, 16 Dec 2016 19:43:01 -0800 Subject: [PATCH] debug - Update kmapinfo, zallocinfo, slabinfo * Update the kmapinfo, zallocinfo, and slabinfo commands so they work properly with current kernels. * kmapinfo now breaks-down who is using each vm_map_entry in the kernel_map, and prints out aggregate results for each subsystem. --- test/debug/kmapinfo.c | 149 +++++++++++++++++++++++++++++++++++++++++++++++--- test/debug/slabinfo.c | 24 +++++--- 2 files changed, 158 insertions(+), 15 deletions(-) diff --git a/test/debug/kmapinfo.c b/test/debug/kmapinfo.c index f372722765..98575765eb 100644 --- a/test/debug/kmapinfo.c +++ b/test/debug/kmapinfo.c @@ -1,7 +1,7 @@ /* * KMAPINFO.C * - * cc -I/usr/src/sys kmapinfo.c -o /usr/local/bin/kmapinfo -lkvm + * cc -I/usr/src/sys kmapinfo.c -o ~/bin/kmapinfo -lkvm * * Dump the kernel_map * @@ -73,7 +73,10 @@ int verboseopt; struct vm_map kmap; vm_offset_t total_empty; vm_offset_t total_used; +vm_offset_t total_used_byid[VM_SUBSYS_LIMIT]; +static const char *formatnum(int64_t value); +static const char *entryid(vm_subsys_t id); static void kkread(kvm_t *kd, u_long addr, void *buf, size_t nbytes); static void mapscan(kvm_t *kd, vm_map_entry_t entry, vm_offset_t *lastp); @@ -85,6 +88,7 @@ main(int ac, char **av) const char *sysfile = NULL; kvm_t *kd; int ch; + int i; vm_offset_t last; while ((ch = getopt(ac, av, "M:N:dv")) != -1) { @@ -121,16 +125,66 @@ main(int ac, char **av) last = kmap.header.start; mapscan(kd, kmap.rb_root.rbh_root, &last); - printf("%4ldM 0x%016jx %08lx-%08lx (%6ldK) EMPTY\n", + printf("%4ldM 0x%016jx %08lx-%08lx (%6s) EMPTY\n", total_used / 1024 / 1024, (intmax_t)NULL, last, kmap.header.end, - (kmap.header.end - last) / 1024); + formatnum(kmap.header.end - last)); total_empty += kmap.header.end - last; printf("-----------------------------------------------\n"); - printf("Total empty space: %7ldK\n", total_empty / 1024); - printf("Total used space: %7ldK\n", total_used / 1024); + for (i = 0; i < VM_SUBSYS_LIMIT; ++i) + printf("Total-id: %9s %s\n", entryid(i), formatnum(total_used_byid[i])); + + printf("-----------------------------------------------\n"); + printf("Total empty space: %s\n", formatnum(total_empty)); + printf("Total used space: %s\n", formatnum(total_used)); +} + +static const char * +formatnum(int64_t value) +{ + static char buf[64]; + const char *neg; + const char *suffix; + int64_t div = 1; + + if (value < 0) { + value = -value; + neg = "-"; + } else { + neg = ""; + } + if (value < 100000) { + div = 1; + suffix = ""; + } else if (value < 1 * 1024 * 1024) { + div = 1024; + suffix = "K"; + } else if (value < 1024 * 1024 * 1024) { + div = 1024 * 1024; + suffix = "M"; + } else if (value < 1024LL * 1024 * 1024 * 1024) { + div = 1024 * 1024 * 1024; + suffix = "G"; + } else { + div = 1024LL * 1024 * 1024 * 1024; + suffix = "T"; + } + if (value == 0) { + snprintf(buf, sizeof(buf), ""); + } else if (div == 1) { + snprintf(buf, sizeof(buf), "%s%7.0f%s", + neg, + (double)value / (double)div, + suffix); + } else { + snprintf(buf, sizeof(buf), "%s%6.2f%s", + neg, + (double)value / (double)div, + suffix); + } + return buf; } static void @@ -150,18 +204,99 @@ mapscan(kvm_t *kd, vm_map_entry_t entryp, vm_offset_t *lastp) (entry.start - *lastp) / 1024); total_empty += entry.start - *lastp; } - printf("%4ldM %p %08lx-%08lx (%6ldK) type=%d object=%p\n", + printf("%4ldM %p %08lx-%08lx (%6ldK) id=%-8s object=%p\n", total_used / 1024 / 1024, entryp, entry.start, entry.end, (entry.end - entry.start) / 1024, - entry.maptype, + entryid(entry.id), entry.object.map_object); total_used += entry.end - entry.start; + if (entry.id < VM_SUBSYS_LIMIT) + total_used_byid[entry.id] += entry.end - entry.start; + else + total_used_byid[0] += entry.end - entry.start; *lastp = entry.end; mapscan(kd, entry.rb_entry.rbe_right, lastp); } +static +const char * +entryid(vm_subsys_t id) +{ + static char buf[32]; + + switch(id) { + case VM_SUBSYS_UNKNOWN: + return("UNKNOWN"); + case VM_SUBSYS_KMALLOC: + return("KMALLOC"); + case VM_SUBSYS_STACK: + return("STACK"); + case VM_SUBSYS_IMGACT: + return("IMGACT"); + case VM_SUBSYS_EFI: + return("EFI"); + case VM_SUBSYS_RESERVED: + return("RESERVED"); + case VM_SUBSYS_INIT: + return("INIT"); + case VM_SUBSYS_PIPE: + return("PIPE"); + case VM_SUBSYS_PROC: + return("PROC"); + case VM_SUBSYS_SHMEM: + return("SHMEM"); + case VM_SUBSYS_SYSMAP: + return("SYSMAP"); + case VM_SUBSYS_MMAP: + return("MMAP"); + case VM_SUBSYS_BRK: + return("BRK"); + case VM_SUBSYS_BOGUS: + return("BOGUS"); + case VM_SUBSYS_BUF: + return("BUF"); + case VM_SUBSYS_BUFDATA: + return("BUFDATA"); + case VM_SUBSYS_GD: + return("GD"); + case VM_SUBSYS_IPIQ: + return("IPIQ"); + case VM_SUBSYS_PVENTRY: + return("PVENTRY"); + case VM_SUBSYS_PML4: + return("PML4"); + case VM_SUBSYS_MAPDEV: + return("MAPDEV"); + case VM_SUBSYS_ZALLOC: + return("ZALLOC"); + + case VM_SUBSYS_DM: + return("DM"); + case VM_SUBSYS_CONTIG: + return("CONTIG"); + case VM_SUBSYS_DRM: + return("DRM"); + case VM_SUBSYS_DRM_GEM: + return("DRM_GEM"); + case VM_SUBSYS_DRM_SCAT: + return("DRM_SCAT"); + case VM_SUBSYS_DRM_VMAP: + return("DRM_VMAP"); + case VM_SUBSYS_DRM_TTM: + return("DRM_TTM"); + case VM_SUBSYS_HAMMER: + return("HAMMER"); + default: + break; + } + snprintf(buf, sizeof(buf), "%d", (int)id); + + return buf; +} + + static void kkread(kvm_t *kd, u_long addr, void *buf, size_t nbytes) { diff --git a/test/debug/slabinfo.c b/test/debug/slabinfo.c index 47a9ca58ac..eecf2f2992 100644 --- a/test/debug/slabinfo.c +++ b/test/debug/slabinfo.c @@ -1,7 +1,7 @@ /* * SLABINFO.C * - * cc -I/usr/src/sys slabinfo.c -o /usr/local/bin/slabinfo -lkvm + * cc -I/usr/src/sys slabinfo.c -o ~/bin/slabinfo -lkvm * * slabinfo * @@ -76,7 +76,7 @@ struct nlist Nl[] = { int debugopt; int verboseopt; -int slzonedump(kvm_t *kd, SLZone *kslz); +int slzonedump(kvm_t *kd, SLZoneList *list); void kkread(kvm_t *kd, u_long addr, void *buf, size_t nbytes); int @@ -92,6 +92,7 @@ main(int ac, char **av) int totalzones; int totalfree; struct globaldata gd; + struct privatespace **psary; while ((ch = getopt(ac, av, "M:N:dv")) != -1) { switch(ch) { @@ -127,24 +128,28 @@ main(int ac, char **av) kkread(kd, Nl[1].n_value, &ncpus, sizeof(int)); totalzones = 0; totalfree = 0; + + psary = malloc(sizeof(void *) * ncpus); + kkread(kd, Nl[0].n_value, psary, sizeof(void *) * ncpus); + for (i = 0; i < ncpus; ++i) { - kkread(kd, Nl[0].n_value + i * sizeof(struct privatespace), &gd, sizeof(gd)); + kkread(kd, (long)psary[i], &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]); + totalzones += slzonedump(kd, &gd.gd_slab.ZoneAry[j]); printf(" }\n"); } printf(" FreeZone {\n"); - totalzones += slzonedump(kd, gd.gd_slab.FreeZones); + totalzones += slzonedump(kd, &gd.gd_slab.FreeZones); printf(" }\n"); printf(" FreeOVZon {\n"); - totalzones += slzonedump(kd, gd.gd_slab.FreeOvZones); + totalzones += slzonedump(kd, &gd.gd_slab.FreeOvZones); printf(" }\n"); printf("}\n"); @@ -157,17 +162,20 @@ main(int ac, char **av) } int -slzonedump(kvm_t *kd, SLZone *kslz) +slzonedump(kvm_t *kd, SLZoneList *list) { SLZone slz; + SLZone *kslz; int count = 0; + kslz = TAILQ_FIRST(list); + 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; + kslz = TAILQ_NEXT(&slz, z_Entry); ++count; } return(count); -- 2.11.4.GIT