@@ -44,6 +44,12 @@ struct slabinfo {
unsigned long cmpxchg_double_cpu_fail, cmpxchg_double_fail;
unsigned long alloc_node_mismatch, deactivate_bypass;
unsigned long cpu_partial_alloc, cpu_partial_free;
+ unsigned int sheaves_enabled;
+ unsigned long alloc_cpu_sheaf, free_cpu_sheaf;
+ unsigned long free_rcu_sheaf, free_rcu_sheaf_fail;
+ unsigned long sheaf_flush_main, sheaf_flush_other;
+ unsigned long sheaf_refill, sheaf_swap;
+ unsigned long sheaf_alloc, sheaf_free;
int numa[MAX_NODES];
int numa_partial[MAX_NODES];
} slabinfo[MAX_SLABS];
@@ -472,6 +478,7 @@ static void slab_stats(struct slabinfo *s)
unsigned long total_alloc;
unsigned long total_free;
unsigned long total;
+ const char *not_avail = "N/A";
if (!s->alloc_slab)
return;
@@ -484,7 +491,7 @@ static void slab_stats(struct slabinfo *s)
printf("\n");
printf("Slab Perf Counter Alloc Free %%Al %%Fr\n");
- printf("--------------------------------------------------\n");
+ printf("----------------------------------------------\n");
printf("Fastpath %8lu %8lu %3lu %3lu\n",
s->alloc_fastpath, s->free_fastpath,
s->alloc_fastpath * 100 / total_alloc,
@@ -525,9 +532,47 @@ static void slab_stats(struct slabinfo *s)
total = s->deactivate_full + s->deactivate_empty +
s->deactivate_to_head + s->deactivate_to_tail + s->deactivate_bypass;
+ if (s->sheaves_enabled) {
+ unsigned long sheaves_total_alloc = s->alloc_cpu_sheaf;
+ unsigned long sheaves_total_free = s->free_cpu_sheaf + s->free_rcu_sheaf;
+
+ total_alloc += sheaves_total_alloc;
+ total_free += sheaves_total_free;
+
+ printf("\n");
+ printf("Slab Sheaves Counter Alloc Free %%Al %%Fr %%Fa\n");
+ printf("-------------------------------------------------------\n");
+ printf("Served from sheaves %8lu %8lu %4lu %4lu %4s\n",
+ s->alloc_cpu_sheaf, s->free_cpu_sheaf,
+ total_alloc ? sheaves_total_alloc * 100 / total_alloc : 0,
+ total_free ? sheaves_total_free * 100 / total_free : 0,
+ not_avail);
+ printf("Sheaves refill %8lu %8s %4lu %4s %4s\n",
+ s->sheaf_refill, not_avail,
+ sheaves_total_alloc ? s->sheaf_refill * 100 / sheaves_total_alloc : 0,
+ not_avail, not_avail);
+ printf("Sheaves alloc %8lu %8lu %4lu %4lu %4s\n",
+ s->sheaf_alloc, s->sheaf_free,
+ sheaves_total_alloc ? s->sheaf_alloc * 100 / sheaves_total_alloc : 0,
+ sheaves_total_free ? s->sheaf_free * 100 / sheaves_total_free : 0,
+ not_avail);
+ printf("Free to RCU sheaves %8s %8lu %4s %4lu %4lu\n",
+ not_avail, s->free_rcu_sheaf, not_avail,
+ sheaves_total_free ? s->free_rcu_sheaf * 100 / sheaves_total_free : 0,
+ s->free_rcu_sheaf ? s->free_rcu_sheaf_fail * 100 / s->free_rcu_sheaf : 0);
+ printf("Main sheaf flush %8s %8lu %4s %4lu %4s\n",
+ not_avail, s->sheaf_flush_main, not_avail,
+ sheaves_total_free ? s->sheaf_flush_main * 100 / sheaves_total_free : 0,
+ not_avail);
+ printf("Other sheaves flush %8s %8lu %4s %4lu %4s\n",
+ not_avail, s->sheaf_flush_other, not_avail,
+ sheaves_total_free ? s->sheaf_flush_other * 100 / sheaves_total_free : 0,
+ not_avail);
+ }
+
if (total) {
printf("\nSlab Deactivation Occurrences %%\n");
- printf("-------------------------------------------------\n");
+ printf("-------------------------------------------\n");
printf("Slab full %7lu %3lu%%\n",
s->deactivate_full, (s->deactivate_full * 100) / total);
printf("Slab empty %7lu %3lu%%\n",
@@ -1301,6 +1346,19 @@ static void read_slab_dir(void)
slab->cpu_partial_free = get_obj("cpu_partial_free");
slab->alloc_node_mismatch = get_obj("alloc_node_mismatch");
slab->deactivate_bypass = get_obj("deactivate_bypass");
+ slab->sheaves_enabled = get_obj("sheaves_enabled");
+ if (slab->sheaves_enabled) {
+ slab->alloc_cpu_sheaf = get_obj("alloc_cpu_sheaf");
+ slab->free_cpu_sheaf = get_obj("free_cpu_sheaf");
+ slab->free_rcu_sheaf = get_obj("free_rcu_sheaf");
+ slab->free_rcu_sheaf_fail = get_obj("free_rcu_sheaf_fail");
+ slab->sheaf_flush_main = get_obj("sheaf_flush_main");
+ slab->sheaf_flush_other = get_obj("sheaf_flush_other");
+ slab->sheaf_refill = get_obj("sheaf_refill");
+ slab->sheaf_swap = get_obj("sheaf_swap");
+ slab->sheaf_alloc = get_obj("sheaf_alloc");
+ slab->sheaf_free = get_obj("sheaf_free");
+ }
if (chdir(".."))
fatal("Unable to chdir from slab ../%s\n",
slab->name);
Add sheaves stats support to the slabinfo tool to make it easier to investigate sheaves statistics. "Served from sheaves" indicates the number of allocations and frees that were served from sheaves, out of the total number of allocations and frees (including those not using sheaves). The other sheaves statistics reflect only the number of events among allocations and frees that were served from sheaves. Before: $ sudo ./slabinfo -r maple_node Slabcache: maple_node Aliases: 0 Order : 1 Objects: 8433 [... snip ...] Slab Perf Counter Alloc Free %Al %Fr -------------------------------------------------- Fastpath 177539 3150 94 4 Slowpath 10841 72067 5 95 Page Alloc 903 519 0 0 Add partial 0 8729 0 11 Remove partial 2007 420 1 0 Cpu partial list 7124 9999 3 13 RemoteObj/SlabFrozen 0 3041 0 4 Total 188380 75217 Slab Deactivation Occurrences % ------------------------------------------------- Slab full 0 0% Slab empty 99 0% Moved to head of partial list 0 0% Moved to tail of partial list 0 0% Deactivation bypass 10012 99% Refilled from foreign frees 807 7% Node mismatch 0 0% After: $ sudo ./slabinfo -r maple_node Slabcache: maple_node Aliases: 0 Order : 1 Objects: 8268 [... snip ...] Slab Perf Counter Alloc Free %Al %Fr ---------------------------------------------- Fastpath 258760 5109 93 3 Slowpath 18205 126605 6 96 Page Alloc 903 520 0 0 Add partial 0 14600 0 11 Remove partial 3472 420 1 0 Cpu partial list 12235 16577 4 12 RemoteObj/SlabFrozen 0 5969 0 4 Total 276965 131714 Slab Sheaves Counter Alloc Free %Al %Fr %Fa ------------------------------------------------------- Served from sheaves 1805673 580161 86 93 N/A Sheaves refill 236384 N/A 13 N/A N/A Sheaves alloc 3872 3794 0 0 N/A Free to RCU sheaves N/A 1255815 N/A 68 0 Main sheaf flush N/A 0 N/A 0 N/A Other sheaves flush N/A 265600 N/A 14 N/A Slab Deactivation Occurrences % ------------------------------------------- Slab full 0 0% Slab empty 100 0% Moved to head of partial list 0 0% Moved to tail of partial list 0 0% Deactivation bypass 16588 99% Refilled from foreign frees 1595 9% Node mismatch 0 0% Signed-off-by: Harry Yoo <harry.yoo@oracle.com> --- tools/mm/slabinfo.c | 62 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 2 deletions(-)