[PATCH 2/2] tools: vm: slabinfo: Add numa information for objects

From: Tobin C. Harding
Date: Mon Feb 17 2020 - 03:48:59 EST


Currently we are not handling NUMA information for a bunch of slab
attribute files, files of form `170 N0=170 ...`. These are

objects
objects_partial
total_objects
cpu_slabs

For other attribute files, namely `partial` and `slabs`, we do handle
the NUMA information.

Add a field to the slabinfo struct for the NUMA information and
output it during a NUMA report as is done for `slabs` and `partial`.

reference: /sys/kernel/slab/kmeme_cache_node/

Signed-off-by: Tobin C. Harding <tobin@xxxxxxxxxx>
---
tools/vm/slabinfo.c | 67 +++++++++++++++++++++++++++++++++++++++++----
1 file changed, 62 insertions(+), 5 deletions(-)

diff --git a/tools/vm/slabinfo.c b/tools/vm/slabinfo.c
index 29f8ecb59cf6..65254c051da2 100644
--- a/tools/vm/slabinfo.c
+++ b/tools/vm/slabinfo.c
@@ -46,6 +46,10 @@ struct slabinfo {
unsigned long cpu_partial_alloc, cpu_partial_free;
int numa[MAX_NODES];
int numa_partial[MAX_NODES];
+ int numa_objects[MAX_NODES];
+ int numa_objects_partial[MAX_NODES];
+ int numa_total_objects[MAX_NODES];
+ int numa_cpu_slabs[MAX_NODES];
} slabinfo[MAX_SLABS];

struct aliasinfo {
@@ -394,13 +398,49 @@ static void slab_numa(struct slabinfo *s, int mode)
printf("\n");
if (mode) {
printf("%-21s ", "Partial slabs");
- for(node = 0; node <= highest_node; node++) {
+ for (node = 0; node <= highest_node; node++) {
char b[20];

store_size(b, s->numa_partial[node]);
printf(" %4s", b);
}
printf("\n");
+
+ printf("%-21s ", "CPU slabs");
+ for (node = 0; node <= highest_node; node++) {
+ char b[20];
+
+ store_size(b, s->numa_cpu_slabs[node]);
+ printf(" %4s", b);
+ }
+ printf("\n");
+
+ printf("%-21s ", "Objects");
+ for (node = 0; node <= highest_node; node++) {
+ char b[20];
+
+ store_size(b, s->numa_objects[node]);
+ printf(" %4s", b);
+ }
+ printf("\n");
+
+ printf("%-21s ", "Partial objects");
+ for (node = 0; node <= highest_node; node++) {
+ char b[20];
+
+ store_size(b, s->numa_objects_partial[node]);
+ printf(" %4s", b);
+ }
+ printf("\n");
+
+ printf("%-21s ", "Total objects");
+ for (node = 0; node <= highest_node; node++) {
+ char b[20];
+
+ store_size(b, s->numa_total_objects[node]);
+ printf(" %4s", b);
+ }
+ printf("\n");
}
line++;
}
@@ -1205,6 +1245,7 @@ static void read_slab_dir(void)
alias->ref = strdup(p);
alias++;
break;
+
case DT_DIR:
if (chdir(de->d_name))
fatal("Unable to access slab %s\n", slab->name);
@@ -1214,13 +1255,27 @@ static void read_slab_dir(void)
slab->aliases = get_obj("aliases");
slab->align = get_obj("align");
slab->cache_dma = get_obj("cache_dma");
- slab->cpu_slabs = get_obj("cpu_slabs");
+
+ slab->cpu_slabs = get_obj_and_str("cpu_slabs", &t);
+ decode_numa_list(slab->numa_cpu_slabs, t);
+ free(t);
+
slab->destroy_by_rcu = get_obj("destroy_by_rcu");
slab->hwcache_align = get_obj("hwcache_align");
slab->object_size = get_obj("object_size");
- slab->objects = get_obj("objects");
- slab->objects_partial = get_obj("objects_partial");
- slab->objects_total = get_obj("objects_total");
+
+ slab->objects = get_obj_and_str("objects", &t);
+ decode_numa_list(slab->numa_objects, t);
+ free(t);
+
+ slab->objects_partial = get_obj_and_str("objects_partial", &t);
+ decode_numa_list(slab->numa_objects_partial, t);
+ free(t);
+
+ slab->objects_total = get_obj_and_str("total_objects", &t);
+ decode_numa_list(slab->numa_total_objects, t);
+ free(t);
+
slab->objs_per_slab = get_obj("objs_per_slab");
slab->order = get_obj("order");
slab->partial = get_obj("partial");
@@ -1232,9 +1287,11 @@ static void read_slab_dir(void)
slab->red_zone = get_obj("red_zone");
slab->sanity_checks = get_obj("sanity_checks");
slab->slab_size = get_obj("slab_size");
+
slab->slabs = get_obj_and_str("slabs", &t);
decode_numa_list(slab->numa, t);
free(t);
+
slab->store_user = get_obj("store_user");
slab->trace = get_obj("trace");
slab->alloc_fastpath = get_obj("alloc_fastpath");
--
2.17.1