[Crash-utility] [PATCH] kmem: Add support to -S option to specify a range of CPU-specific slab data

Aaron Tomlin atomlin at redhat.com
Thu Jul 1 19:53:56 UTC 2021


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 at redhat.com>
---
 help.c   |  5 ++++-
 memory.c | 47 +++++++++++++++++++++++++++++++++++++++++++----
 2 files changed, 47 insertions(+), 5 deletions(-)

diff --git a/help.c b/help.c
index e0c8408..8d40204 100644
--- a/help.c
+++ b/help.c
@@ -6571,7 +6571,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.",
@@ -6616,6 +6616,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 8c6bbe4..ef7c3ec 100644
--- a/memory.c
+++ b/memory.c
@@ -47,6 +47,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];
@@ -4850,10 +4851,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;
@@ -4862,7 +4866,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':
@@ -4902,6 +4906,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;
 
@@ -5184,6 +5215,8 @@ cmd_kmem(void)
 			meminfo.flags = VERBOSE;
 			vt->dump_kmem_cache(&meminfo);
 		}
+		if (choose_cpu)
+			FREEBUF(cpus);
 	}
 
 	if (vflag == 1)
@@ -19079,7 +19112,13 @@ do_kmem_cache_slub(struct meminfo *si)
 	per_cpu = (ulong *)GETBUF(sizeof(ulong) * vt->numnodes);
 
         for (i = 0; i < kt->cpus; i++) {
-		if (hide_offline_cpu(i)) {
+		if (si->spec_cpumask) {
+			if (!(NUM_IN_BITMAP(si->spec_cpumask, i)))
+				continue;
+			else
+				if (check_offline_cpu(i))
+					continue;
+		} else if (hide_offline_cpu(i)) {
 			fprintf(fp, "CPU %d [OFFLINE]\n", i);
 			continue;
 		}
-- 
2.31.1




More information about the Crash-utility mailing list