From: Vlastimil Babka <vbabka@suse.cz>
To: linux-mm@kvack.org
Cc: Andrew Morton <akpm@linux-foundation.org>,
Christoph Lameter <cl@gentwo.org>,
David Rientjes <rientjes@google.com>,
Roman Gushchin <roman.gushchin@linux.dev>,
Harry Yoo <harry.yoo@oracle.com>,
linux-kernel@vger.kernel.org, Vlastimil Babka <vbabka@suse.cz>
Subject: [PATCH 2/4] slab: turn freelist_aba_t to a struct and fully define counters there
Date: Fri, 07 Nov 2025 14:51:24 +0100 [thread overview]
Message-ID: <20251107-slab-fms-cleanup-v1-2-650b1491ac9e@suse.cz> (raw)
In-Reply-To: <20251107-slab-fms-cleanup-v1-0-650b1491ac9e@suse.cz>
In struct slab we currently have freelist and counters pair, where
counters itself is a union of unsigned long with a sub-struct of
several smaller fields. Then for the usage with double cmpxchg we have
freelist_aba_t that duplicates the definition of the freelist+counters
with implicitly the same layout as the full definition in struct slab.
Thanks to -fms-extension we can now move the full counters definition to
freelist_aba_t (while changing it to struct freelist_counters as a
typedef is unnecessary and discouraged) and replace the relevant part in
struct slab to an unnamed reference to it.
The immediate benefit is the removal of duplication and no longer
relying on the same layout implicitly. It also allows further cleanups
thanks to having the full definition of counters in struct
freelist_counters.
Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
---
mm/slab.h | 52 ++++++++++++++++++++++++----------------------------
mm/slub.c | 8 +++++---
2 files changed, 29 insertions(+), 31 deletions(-)
diff --git a/mm/slab.h b/mm/slab.h
index 078daecc7cf5..42627b87d50c 100644
--- a/mm/slab.h
+++ b/mm/slab.h
@@ -40,13 +40,29 @@ typedef u64 freelist_full_t;
* Freelist pointer and counter to cmpxchg together, avoids the typical ABA
* problems with cmpxchg of just a pointer.
*/
-typedef union {
- struct {
- void *freelist;
- unsigned long counter;
+struct freelist_counters {
+ union {
+ struct {
+ void *freelist;
+ union {
+ unsigned long counters;
+ struct {
+ unsigned inuse:16;
+ unsigned objects:15;
+ /*
+ * If slab debugging is enabled then the
+ * frozen bit can be reused to indicate
+ * that the slab was corrupted
+ */
+ unsigned frozen:1;
+ };
+ };
+ };
+#ifdef system_has_freelist_aba
+ freelist_full_t freelist_counters;
+#endif
};
- freelist_full_t full;
-} freelist_aba_t;
+};
/* Reuses the bits in struct page */
struct slab {
@@ -69,27 +85,7 @@ struct slab {
#endif
};
/* Double-word boundary */
- union {
- struct {
- void *freelist; /* first free object */
- union {
- unsigned long counters;
- struct {
- unsigned inuse:16;
- unsigned objects:15;
- /*
- * If slab debugging is enabled then the
- * frozen bit can be reused to indicate
- * that the slab was corrupted
- */
- unsigned frozen:1;
- };
- };
- };
-#ifdef system_has_freelist_aba
- freelist_aba_t freelist_counter;
-#endif
- };
+ struct freelist_counters;
};
struct rcu_head rcu_head;
};
@@ -114,7 +110,7 @@ SLAB_MATCH(_unused_slab_obj_exts, obj_exts);
#undef SLAB_MATCH
static_assert(sizeof(struct slab) <= sizeof(struct page));
#if defined(system_has_freelist_aba)
-static_assert(IS_ALIGNED(offsetof(struct slab, freelist), sizeof(freelist_aba_t)));
+static_assert(IS_ALIGNED(offsetof(struct slab, freelist), sizeof(struct freelist_counters)));
#endif
/**
diff --git a/mm/slub.c b/mm/slub.c
index 5f6408c9e0fd..8330e4f8b3b2 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -764,10 +764,12 @@ __update_freelist_fast(struct slab *slab,
void *freelist_new, unsigned long counters_new)
{
#ifdef system_has_freelist_aba
- freelist_aba_t old = { .freelist = freelist_old, .counter = counters_old };
- freelist_aba_t new = { .freelist = freelist_new, .counter = counters_new };
+ struct freelist_counters old = { .freelist = freelist_old, .counters = counters_old };
+ struct freelist_counters new = { .freelist = freelist_new, .counters = counters_new };
- return try_cmpxchg_freelist(&slab->freelist_counter.full, &old.full, new.full);
+ return try_cmpxchg_freelist(&slab->freelist_counters,
+ &old.freelist_counters,
+ new.freelist_counters);
#else
return false;
#endif
--
2.51.1
next prev parent reply other threads:[~2025-11-07 13:51 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-11-07 13:51 [PATCH 0/4] slab: cmpxchg cleanups enabled by -fms-extensions Vlastimil Babka
2025-11-07 13:51 ` [PATCH 1/4] slab: separate struct freelist_tid from kmem_cache_cpu Vlastimil Babka
2025-11-13 7:22 ` Harry Yoo
2025-11-07 13:51 ` Vlastimil Babka [this message]
2025-11-13 7:34 ` [PATCH 2/4] slab: turn freelist_aba_t to a struct and fully define counters there Harry Yoo
2025-11-07 13:51 ` [PATCH 3/4] slab: use struct freelist_counters for local variables instead of struct slab Vlastimil Babka
2025-11-13 7:45 ` Harry Yoo
2025-11-07 13:51 ` [PATCH 4/4] slab: use struct freelist_counters as parameters in relevant functions Vlastimil Babka
2025-11-13 8:32 ` Harry Yoo
2025-11-13 9:13 ` Vlastimil Babka
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=20251107-slab-fms-cleanup-v1-2-650b1491ac9e@suse.cz \
--to=vbabka@suse.cz \
--cc=akpm@linux-foundation.org \
--cc=cl@gentwo.org \
--cc=harry.yoo@oracle.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=rientjes@google.com \
--cc=roman.gushchin@linux.dev \
/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