* [PATCH] mm/slub: unify slub stat definitions to simplify metric additions
@ 2026-08-14 7:17 Hao Li
0 siblings, 0 replies; only message in thread
From: Hao Li @ 2026-08-14 7:17 UTC (permalink / raw)
To: vbabka, harry
Cc: akpm, cl, rientjes, roman.gushchin, linux-mm, linux-kernel,
Hao Li
Currently, adding a new slub stat requires modifying three separate
locations: stat_item, STAT_ATTR, and slab_attrs. This is inconvenient,
especially when temporarily adding metrics for debugging during
development.
This patch borrows the approach from SCHED_FEAT by introducing an ITEM_EXP
X-macro, which is then temporarily defined as different operations at the
three locations (stat_item, STAT_ATTR, and slab_attrs) to perform distinct
macro expansions.
Going forward, adding a new metric only requires adding a single line:
ITEM_EXP(XXX, xxx)
Signed-off-by: Hao Li <hao.li@linux.dev>
---
mm/slub.c | 144 ++++++++++++++++++++++++------------------------------
1 file changed, 65 insertions(+), 79 deletions(-)
diff --git a/mm/slub.c b/mm/slub.c
index b0cd0572e2f2..8dd25032fba4 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -359,33 +359,64 @@ enum add_mode {
ADD_TO_TAIL,
};
+#define STAT_ITEMS \
+ /* Allocation from percpu sheaves */ \
+ ITEM_EXP(ALLOC_FASTPATH, alloc_fastpath) \
+ /* Allocation from partial or new slab */ \
+ ITEM_EXP(ALLOC_SLOWPATH, alloc_slowpath) \
+ /* Free to rcu_free sheaf */ \
+ ITEM_EXP(FREE_RCU_SHEAF, free_rcu_sheaf) \
+ /* Failed to free to a rcu_free sheaf */ \
+ ITEM_EXP(FREE_RCU_SHEAF_FAIL, free_rcu_sheaf_fail) \
+ /* Free to percpu sheaves */ \
+ ITEM_EXP(FREE_FASTPATH, free_fastpath) \
+ /* Free to a slab */ \
+ ITEM_EXP(FREE_SLOWPATH, free_slowpath) \
+ /* Freeing moves slab to partial list */ \
+ ITEM_EXP(FREE_ADD_PARTIAL, free_add_partial) \
+ /* Freeing removes last object */ \
+ ITEM_EXP(FREE_REMOVE_PARTIAL, free_remove_partial) \
+ /* New slab acquired from page allocator */ \
+ ITEM_EXP(ALLOC_SLAB, alloc_slab) \
+ /* Requested node different from cpu sheaf */ \
+ ITEM_EXP(ALLOC_NODE_MISMATCH, alloc_node_mismatch) \
+ /* Slab freed to the page allocator */ \
+ ITEM_EXP(FREE_SLAB, free_slab) \
+ /* Number of times fallback was necessary */ \
+ ITEM_EXP(ORDER_FALLBACK, order_fallback) \
+ /* Failures of slab freelist update */ \
+ ITEM_EXP(CMPXCHG_DOUBLE_FAIL, cmpxchg_double_fail) \
+ /* Objects flushed from a sheaf */ \
+ ITEM_EXP(SHEAF_FLUSH, sheaf_flush) \
+ /* Objects refilled to a sheaf */ \
+ ITEM_EXP(SHEAF_REFILL, sheaf_refill) \
+ /* Allocation of an empty sheaf including oversized ones */ \
+ ITEM_EXP(SHEAF_ALLOC, sheaf_alloc) \
+ /* Freeing of an empty sheaf including oversized ones */ \
+ ITEM_EXP(SHEAF_FREE, sheaf_free) \
+ /* Got full sheaf from barn */ \
+ ITEM_EXP(BARN_GET, barn_get) \
+ /* Failed to get full sheaf from barn */ \
+ ITEM_EXP(BARN_GET_FAIL, barn_get_fail) \
+ /* Put full sheaf to barn */ \
+ ITEM_EXP(BARN_PUT, barn_put) \
+ /* Failed to put full sheaf to barn */ \
+ ITEM_EXP(BARN_PUT_FAIL, barn_put_fail) \
+ /* Sheaf prefill grabbed the spare sheaf */ \
+ ITEM_EXP(SHEAF_PREFILL_FAST, sheaf_prefill_fast) \
+ /* Sheaf prefill found no spare sheaf */ \
+ ITEM_EXP(SHEAF_PREFILL_SLOW, sheaf_prefill_slow) \
+ /* Allocation of oversize sheaf for prefill */ \
+ ITEM_EXP(SHEAF_PREFILL_OVERSIZE, sheaf_prefill_oversize) \
+ /* Sheaf return reattached spare sheaf */ \
+ ITEM_EXP(SHEAF_RETURN_FAST, sheaf_return_fast) \
+ /* Sheaf return could not reattach spare */ \
+ ITEM_EXP(SHEAF_RETURN_SLOW, sheaf_return_slow)
+
enum stat_item {
- ALLOC_FASTPATH, /* Allocation from percpu sheaves */
- ALLOC_SLOWPATH, /* Allocation from partial or new slab */
- FREE_RCU_SHEAF, /* Free to rcu_free sheaf */
- FREE_RCU_SHEAF_FAIL, /* Failed to free to a rcu_free sheaf */
- FREE_FASTPATH, /* Free to percpu sheaves */
- FREE_SLOWPATH, /* Free to a slab */
- FREE_ADD_PARTIAL, /* Freeing moves slab to partial list */
- FREE_REMOVE_PARTIAL, /* Freeing removes last object */
- ALLOC_SLAB, /* New slab acquired from page allocator */
- ALLOC_NODE_MISMATCH, /* Requested node different from cpu sheaf */
- FREE_SLAB, /* Slab freed to the page allocator */
- ORDER_FALLBACK, /* Number of times fallback was necessary */
- CMPXCHG_DOUBLE_FAIL, /* Failures of slab freelist update */
- SHEAF_FLUSH, /* Objects flushed from a sheaf */
- SHEAF_REFILL, /* Objects refilled to a sheaf */
- SHEAF_ALLOC, /* Allocation of an empty sheaf including oversized ones */
- SHEAF_FREE, /* Freeing of an empty sheaf including oversized ones */
- BARN_GET, /* Got full sheaf from barn */
- BARN_GET_FAIL, /* Failed to get full sheaf from barn */
- BARN_PUT, /* Put full sheaf to barn */
- BARN_PUT_FAIL, /* Failed to put full sheaf to barn */
- SHEAF_PREFILL_FAST, /* Sheaf prefill grabbed the spare sheaf */
- SHEAF_PREFILL_SLOW, /* Sheaf prefill found no spare sheaf */
- SHEAF_PREFILL_OVERSIZE, /* Allocation of oversize sheaf for prefill */
- SHEAF_RETURN_FAST, /* Sheaf return reattached spare sheaf */
- SHEAF_RETURN_SLOW, /* Sheaf return could not reattach spare */
+#define ITEM_EXP(name, unused) name,
+ STAT_ITEMS
+#undef ITEM_EXP
NR_SLUB_STAT_ITEMS
};
@@ -9512,34 +9543,12 @@ static ssize_t text##_store(struct kmem_cache *s, \
clear_stat(s, si); \
return length; \
} \
-SLAB_ATTR(text); \
+SLAB_ATTR(text);
+
+#define ITEM_EXP(name, text) STAT_ATTR(name, text)
+STAT_ITEMS
+#undef ITEM_EXP
-STAT_ATTR(ALLOC_FASTPATH, alloc_fastpath);
-STAT_ATTR(ALLOC_SLOWPATH, alloc_slowpath);
-STAT_ATTR(FREE_RCU_SHEAF, free_rcu_sheaf);
-STAT_ATTR(FREE_RCU_SHEAF_FAIL, free_rcu_sheaf_fail);
-STAT_ATTR(FREE_FASTPATH, free_fastpath);
-STAT_ATTR(FREE_SLOWPATH, free_slowpath);
-STAT_ATTR(FREE_ADD_PARTIAL, free_add_partial);
-STAT_ATTR(FREE_REMOVE_PARTIAL, free_remove_partial);
-STAT_ATTR(ALLOC_SLAB, alloc_slab);
-STAT_ATTR(ALLOC_NODE_MISMATCH, alloc_node_mismatch);
-STAT_ATTR(FREE_SLAB, free_slab);
-STAT_ATTR(ORDER_FALLBACK, order_fallback);
-STAT_ATTR(CMPXCHG_DOUBLE_FAIL, cmpxchg_double_fail);
-STAT_ATTR(SHEAF_FLUSH, sheaf_flush);
-STAT_ATTR(SHEAF_REFILL, sheaf_refill);
-STAT_ATTR(SHEAF_ALLOC, sheaf_alloc);
-STAT_ATTR(SHEAF_FREE, sheaf_free);
-STAT_ATTR(BARN_GET, barn_get);
-STAT_ATTR(BARN_GET_FAIL, barn_get_fail);
-STAT_ATTR(BARN_PUT, barn_put);
-STAT_ATTR(BARN_PUT_FAIL, barn_put_fail);
-STAT_ATTR(SHEAF_PREFILL_FAST, sheaf_prefill_fast);
-STAT_ATTR(SHEAF_PREFILL_SLOW, sheaf_prefill_slow);
-STAT_ATTR(SHEAF_PREFILL_OVERSIZE, sheaf_prefill_oversize);
-STAT_ATTR(SHEAF_RETURN_FAST, sheaf_return_fast);
-STAT_ATTR(SHEAF_RETURN_SLOW, sheaf_return_slow);
#endif /* CONFIG_SLUB_STATS */
#ifdef CONFIG_KFENCE
@@ -9602,32 +9611,9 @@ static const struct attribute *const slab_attrs[] = {
&remote_node_defrag_ratio_attr.attr,
#endif
#ifdef CONFIG_SLUB_STATS
- &alloc_fastpath_attr.attr,
- &alloc_slowpath_attr.attr,
- &free_rcu_sheaf_attr.attr,
- &free_rcu_sheaf_fail_attr.attr,
- &free_fastpath_attr.attr,
- &free_slowpath_attr.attr,
- &free_add_partial_attr.attr,
- &free_remove_partial_attr.attr,
- &alloc_slab_attr.attr,
- &alloc_node_mismatch_attr.attr,
- &free_slab_attr.attr,
- &order_fallback_attr.attr,
- &cmpxchg_double_fail_attr.attr,
- &sheaf_flush_attr.attr,
- &sheaf_refill_attr.attr,
- &sheaf_alloc_attr.attr,
- &sheaf_free_attr.attr,
- &barn_get_attr.attr,
- &barn_get_fail_attr.attr,
- &barn_put_attr.attr,
- &barn_put_fail_attr.attr,
- &sheaf_prefill_fast_attr.attr,
- &sheaf_prefill_slow_attr.attr,
- &sheaf_prefill_oversize_attr.attr,
- &sheaf_return_fast_attr.attr,
- &sheaf_return_slow_attr.attr,
+#define ITEM_EXP(unused, text) &text##_attr.attr,
+ STAT_ITEMS
+#undef ITEM_EXP
#endif
#ifdef CONFIG_FAILSLAB
&failslab_attr.attr,
--
2.54.0
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2026-08-14 7:19 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-14 7:17 [PATCH] mm/slub: unify slub stat definitions to simplify metric additions Hao Li
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox