From: Hao Li <hao.li@linux.dev>
To: vbabka@kernel.org, harry@kernel.org
Cc: akpm@linux-foundation.org, cl@gentwo.org, rientjes@google.com,
roman.gushchin@linux.dev, linux-mm@kvack.org,
linux-kernel@vger.kernel.org, Hao Li <hao.li@linux.dev>
Subject: [PATCH] mm/slub: unify slub stat definitions to simplify metric additions
Date: Fri, 14 Aug 2026 15:17:02 +0800 [thread overview]
Message-ID: <20260814071848.46922-1-hao.li@linux.dev> (raw)
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
reply other threads:[~2026-08-14 7:19 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260814071848.46922-1-hao.li@linux.dev \
--to=hao.li@linux.dev \
--cc=akpm@linux-foundation.org \
--cc=cl@gentwo.org \
--cc=harry@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=rientjes@google.com \
--cc=roman.gushchin@linux.dev \
--cc=vbabka@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).