With this patch, it is now possible for one to explicitly specify a range of CPU-specific slab data to list. For example: Note: This is only applicable to a Linux kernel with Kconfig CONFIG_SLUB enabled. The optional argument GNU extension for getopt(3) is utilised; and, the CPU range must be specified as expected crash> kmem -S=1,4 kmalloc-512 CACHE OBJSIZE ALLOCATED TOTAL SLABS SSIZE NAME ffff8d3f07c06c00 512 1916 3680 115 16k kmalloc-512 CPU 1 KMEM_CACHE_CPU: ffff8d461fa6f140 CPU 1 SLAB: SLAB MEMORY NODE TOTAL ALLOCATED FREE fffff540df7c4000 ffff8d45df100000 0 32 8 24 FREE / [ALLOCATED] ffff8d45df100000 (cpu 1 cache) [ffff8d45df100200] ffff8d45df100400 (cpu 1 cache) [ffff8d45df100600] ffff8d45df100800 (cpu 1 cache) ffff8d45df100a00 (cpu 1 cache) ffff8d45df100c00 (cpu 1 cache) ffff8d45df100e00 (cpu 1 cache) ffff8d45df101000 (cpu 1 cache) [ffff8d45df101200] ...skipped ... CPU 4 KMEM_CACHE_CPU: ffff8d461fb2f140 CPU 4 SLAB: SLAB MEMORY NODE TOTAL ALLOCATED FREE fffff540dfde3800 ffff8d45f78e0000 0 32 8 24 FREE / [ALLOCATED] [ffff8d45f78e0000] ffff8d45f78e0200 (cpu 4 cache) ffff8d45f78e0400 (cpu 4 cache) [ffff8d45f78e0600] ffff8d45f78e0800 (cpu 4 cache) ffff8d45f78e0a00 (cpu 4 cache) ffff8d45f78e0c00 (cpu 4 cache) ffff8d45f78e0e00 (cpu 4 cache) ffff8d45f78e1000 (cpu 4 cache) ffff8d45f78e1200 (cpu 4 cache) ffff8d45f78e1400 (cpu 4 cache) [ffff8d45f78e1600] ...skipped ... Signed-off-by: Aaron Tomlin <atomlin@xxxxxxxxxx> --- Changes since v1: - Do not explicitly exclude an offline CPU as this is handled via hide_offline_cpu() logic (Kazu) --- help.c | 5 ++++- memory.c | 41 ++++++++++++++++++++++++++++++++++++++--- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/help.c b/help.c index 99be7cb..6c262a3 100644 --- a/help.c +++ b/help.c @@ -6601,7 +6601,7 @@ char *help_kmem[] = { "kmem", "kernel memory", "[-f|-F|-c|-C|-i|-v|-V|-n|-z|-o|-h] [-p | -m member[,member]]\n" -" [[-s|-S|-r] [slab] [-I slab[,slab]]] [-g [flags]] [[-P] address]]", +" [[-s|-S|-S=cpu[s]|-r] [slab] [-I slab[,slab]]] [-g [flags]] [[-P] address]]", " This command displays information about the use of kernel memory.\n", " -f displays the contents of the system free memory headers.", " also verifies that the page count equals nr_free_pages.", @@ -6649,6 +6649,9 @@ char *help_kmem[] = { " slab data for each per-cpu slab is displayed, along with the", " address of each kmem_cache_node, its count of full and partial", " slabs, and a list of all tracked slabs.", +" Note: one can specify the per-cpu slab data to be displayed;", +" the cpu[s] can be given as \"1,3,5\", \"1-3\", \"1,3,5-7,10\",", +" \"all\", or \"a\" (shortcut for \"all\").", " -r displays the accumulated basic kmalloc() slab data of each", " root slab cache and its children. The kernel must contain the", " \"slab_root_caches\" list_head. (currently only available if", diff --git a/memory.c b/memory.c index cbe90ee..d59784c 100644 --- a/memory.c +++ b/memory.c @@ -48,6 +48,7 @@ struct meminfo { /* general purpose memory information structure */ int slab_offset; char *reqname; char *curname; + ulong *spec_cpumask; ulong *addrlist; int *kmem_bufctl; ulong *cpudata[NR_CPUS]; @@ -4851,10 +4852,13 @@ cmd_kmem(void) struct meminfo meminfo; ulonglong value[MAXARGS]; char buf[BUFSIZE]; + char arg_buf[BUFSIZE]; char *p1; - int spec_addr, escape; + ulong *cpus; + int spec_addr, escape, choose_cpu; - spec_addr = 0; + cpus = NULL; + spec_addr = choose_cpu = 0; sflag = Sflag = pflag = fflag = Fflag = Pflag = zflag = oflag = 0; vflag = Cflag = cflag = iflag = nflag = lflag = Lflag = Vflag = 0; gflag = hflag = rflag = 0; @@ -4863,7 +4867,7 @@ cmd_kmem(void) BZERO(&value[0], sizeof(ulonglong)*MAXARGS); pc->curcmd_flags &= ~HEADER_PRINTED; - while ((c = getopt(argcnt, args, "gI:sSrFfm:pvczCinl:L:PVoh")) != EOF) { + while ((c = getopt(argcnt, args, "gI:sS::rFfm:pvczCinl:L:PVoh")) != EOF) { switch(c) { case 'V': @@ -4903,6 +4907,33 @@ cmd_kmem(void) break; case 'S': + if (choose_cpu) + error(FATAL, "only one -S option allowed\n"); + /* Use the GNU extension with getopt(3) ... */ + if (optarg) { + if (!(vt->flags & KMALLOC_SLUB)) + error(FATAL, + "can only use -S=cpu(s) with a kernel \n" + "that is built with CONFIG_SLUB support.\n"); + if (optarg[0] != '=') + error(FATAL, + "CPU-specific slab data to be displayed " + "must be written as expected only e.g. -S=1,45.\n"); + /* Skip = ... */ + optarg++; + + choose_cpu = 1; + BZERO(arg_buf, BUFSIZE); + strcpy(arg_buf, optarg); + + cpus = get_cpumask_buf(); + make_cpumask(arg_buf, cpus, FAULT_ON_ERROR, NULL); + meminfo.spec_cpumask = cpus; + + for (i = 0; i < kt->cpus; i++) + if (NUM_IN_BITMAP(cpus, i) && check_offline_cpu(i)) + error(INFO, "CPU %d is OFFLINE.\n", i); + } Sflag = 1; sflag = rflag = 0; break; @@ -5185,6 +5216,8 @@ cmd_kmem(void) meminfo.flags = VERBOSE; vt->dump_kmem_cache(&meminfo); } + if (choose_cpu) + FREEBUF(cpus); } if (vflag == 1) @@ -19083,6 +19116,8 @@ do_kmem_cache_slub(struct meminfo *si) per_cpu = (ulong *)GETBUF(sizeof(ulong) * vt->numnodes); for (i = 0; i < kt->cpus; i++) { + if (si->spec_cpumask && !NUM_IN_BITMAP(si->spec_cpumask, i)) + continue; if (hide_offline_cpu(i)) { fprintf(fp, "CPU %d [OFFLINE]\n", i); continue; -- 2.31.1 -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://listman.redhat.com/mailman/listinfo/crash-utility