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

HAGIO KAZUHITO(萩尾 一仁) k-hagio-ab at nec.com
Fri Jul 16 07:32:48 UTC 2021


-----Original Message-----
> 
> 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>
> ---
> Changes since v1:
> 
>   - Do not explicitly exclude an offline CPU
>     as this is handled via hide_offline_cpu()
>     logic (Kazu)

Thanks for the update.

> 
> ---
>  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);

With the offline hide option, "CPU xx [OFFLINE]" is shown as follows and
this error message is not needed.

crash> set offline hide
      offline: hide
crash> kmem -S=15 TCP
kmem: CPU 15 is OFFLINE.
CACHE             OBJSIZE  ALLOCATED     TOTAL  SLABS  SSIZE  NAME
ffff916f6798b2c0     2440         17       208     16    32k  TCP
CPU 15 [OFFLINE]
...

And the other commands do not say anything by default (offline show),
it should be the same behavior with them.

So with removing the for block above, (but you don't need to repost)
Acked-by: Kazuhito Hagio <k-hagio-ab at nec.com>

Thanks,
Kazu


> +			}
>  			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 at redhat.com
> https://listman.redhat.com/mailman/listinfo/crash-utility





More information about the Crash-utility mailing list