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