-----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(a)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(a)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(a)redhat.com
https://listman.redhat.com/mailman/listinfo/crash-utility