From: "Vlastimil Babka (SUSE)" <vbabka@kernel.org>
To: Harry Yoo <harry@kernel.org>
Cc: Hao Li <hao.li@linux.dev>, Christoph Lameter <cl@gentwo.org>,
David Rientjes <rientjes@google.com>,
Roman Gushchin <roman.gushchin@linux.dev>,
Geert Uytterhoeven <geert@linux-m68k.org>,
Conor Dooley <conor@kernel.org>,
Damien Le Moal <damien.lemoal@opensource.wdc.com>,
linux-mm@kvack.org, linux-kernel@vger.kernel.org,
"Vlastimil Babka (SUSE)" <vbabka@kernel.org>
Subject: [PATCH RFC 1/8] mm, slab: refactor slab_min/max_order handling
Date: Wed, 23 Sep 2026 17:45:06 +0200 [thread overview]
Message-ID: <20260923-slub_tiny_rework-v1-1-a0e66d536eb5@kernel.org> (raw)
In-Reply-To: <20260923-slub_tiny_rework-v1-0-a0e66d536eb5@kernel.org>
Setting slab_min_order and slab_max_order as boot-time parameters
currently has several not so great aspects:
- slab_min_order is not checked against MAX_PAGE_ORDER
- slab_min_order can raise slab_max_order
- processing requires custom callbacks, their execution order
depends on the order of boot time parameters specified
- upcoming SLUB_TINY changes would be more complicated
Instead of custom callbacks, introduce __initdata variables that hold
the boot-time parameter values (if given). All inputs are then evaluated
deterministically in kmem_cache_init(). slab_min_order is always capped
at slab_max_order and cannot raise it.
debug_guardpage_minorder() still overrides any given boot time params,
but it could be changed if there's a use case.
While at it, rename the slub_min/max_order variables and
slub_min_objects to have a "slab_" prefix instead, as their values
determine the sizing of slabs, and the "slub_" prefix already became
deprecated also for the boot-time parameters.
Signed-off-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>
---
mm/slub.c | 84 ++++++++++++++++++++++++---------------------------------------
1 file changed, 32 insertions(+), 52 deletions(-)
diff --git a/mm/slub.c b/mm/slub.c
index 96dca4846b4e..a107a111c75e 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -7598,10 +7598,17 @@ EXPORT_SYMBOL(kmem_cache_alloc_bulk_noprof);
* and increases the number of allocations possible without having to
* take the list_lock.
*/
-static unsigned int slub_min_order;
-static unsigned int slub_max_order =
+static unsigned int slab_min_order;
+static unsigned int slab_max_order =
IS_ENABLED(CONFIG_SLUB_TINY) ? 1 : PAGE_ALLOC_COSTLY_ORDER;
-static unsigned int slub_min_objects;
+static unsigned int slab_min_objects;
+
+/*
+ * Store values set by boot-time parameters, to be evaluated in
+ * kmem_cache_init(). UINT_MAX means they were not set, as 0 is a valid value.
+ */
+static unsigned int slab_min_order_param __initdata = UINT_MAX;
+static unsigned int slab_max_order_param __initdata = UINT_MAX;
/*
* Calculate the order of allocation given an slab object size.
@@ -7655,7 +7662,7 @@ static inline int calculate_order(unsigned int size)
unsigned int max_objects;
unsigned int min_order;
- min_objects = slub_min_objects;
+ min_objects = slab_min_objects;
if (!min_objects) {
/*
* Some architectures will only update present cpus when
@@ -7672,10 +7679,10 @@ static inline int calculate_order(unsigned int size)
min_objects = 4 * (fls(nr_cpus) + 1);
}
/* min_objects can't be 0 because get_order(0) is undefined */
- max_objects = max(order_objects(slub_max_order, size), 1U);
+ max_objects = max(order_objects(slab_max_order, size), 1U);
min_objects = min(min_objects, max_objects);
- min_order = max_t(unsigned int, slub_min_order,
+ min_order = max_t(unsigned int, slab_min_order,
get_order(min_objects * size));
if (order_objects(min_order, size) > MAX_OBJS_PER_PAGE)
return get_order(size * MAX_OBJS_PER_PAGE) - 1;
@@ -7696,9 +7703,9 @@ static inline int calculate_order(unsigned int size)
* long as at least single object fits within slab_max_order.
*/
for (unsigned int fraction = 16; fraction > 1; fraction /= 2) {
- order = calc_slab_order(size, min_order, slub_max_order,
+ order = calc_slab_order(size, min_order, slab_max_order,
fraction);
- if (order <= slub_max_order)
+ if (order <= slab_max_order)
return order;
}
@@ -8268,50 +8275,14 @@ void __kmem_obj_info(struct kmem_obj_info *kpp, void *object, struct slab *slab)
* Kmalloc subsystem
*******************************************************************/
-static int __init setup_slub_min_order(const char *str, const struct kernel_param *kp)
-{
- int ret;
-
- ret = kstrtouint(str, 0, &slub_min_order);
- if (ret)
- return ret;
+core_param(slab_min_order, slab_min_order_param, uint, 0);
+core_param(slub_min_order, slab_min_order_param, uint, 0);
- if (slub_min_order > slub_max_order)
- slub_max_order = slub_min_order;
+core_param(slab_max_order, slab_max_order_param, uint, 0);
+core_param(slub_max_order, slab_max_order_param, uint, 0);
- return 0;
-}
-
-static const struct kernel_param_ops param_ops_slab_min_order __initconst = {
- .set = setup_slub_min_order,
-};
-__core_param_cb(slab_min_order, ¶m_ops_slab_min_order, &slub_min_order, 0);
-__core_param_cb(slub_min_order, ¶m_ops_slab_min_order, &slub_min_order, 0);
-
-static int __init setup_slub_max_order(const char *str, const struct kernel_param *kp)
-{
- int ret;
-
- ret = kstrtouint(str, 0, &slub_max_order);
- if (ret)
- return ret;
-
- slub_max_order = min_t(unsigned int, slub_max_order, MAX_PAGE_ORDER);
-
- if (slub_min_order > slub_max_order)
- slub_min_order = slub_max_order;
-
- return 0;
-}
-
-static const struct kernel_param_ops param_ops_slab_max_order __initconst = {
- .set = setup_slub_max_order,
-};
-__core_param_cb(slab_max_order, ¶m_ops_slab_max_order, &slub_max_order, 0);
-__core_param_cb(slub_max_order, ¶m_ops_slab_max_order, &slub_max_order, 0);
-
-core_param(slab_min_objects, slub_min_objects, uint, 0);
-core_param(slub_min_objects, slub_min_objects, uint, 0);
+core_param(slab_min_objects, slab_min_objects, uint, 0);
+core_param(slub_min_objects, slab_min_objects, uint, 0);
#ifdef CONFIG_NUMA
static int __init setup_slab_strict_numa(const char *str, const struct kernel_param *kp)
@@ -8684,8 +8655,17 @@ void __init kmem_cache_init(void)
slab_obj_ext_has_codetag_init();
+ if (slab_max_order_param <= MAX_PAGE_ORDER)
+ slab_max_order = slab_max_order_param;
+
+ if (slab_min_order_param <= MAX_PAGE_ORDER)
+ slab_min_order = slab_min_order_param;
+
if (debug_guardpage_minorder())
- slub_max_order = 0;
+ slab_max_order = 0;
+
+ if (slab_min_order > slab_max_order)
+ slab_min_order = slab_max_order;
/* Inform pointer hashing choice about slub debugging state. */
hash_pointers_finalize(__slub_debug_enabled());
@@ -8736,7 +8716,7 @@ void __init kmem_cache_init(void)
pr_info("SLUB: HWalign=%d, Order=%u-%u, MinObjects=%u, CPUs=%u, Nodes=%u\n",
cache_line_size(),
- slub_min_order, slub_max_order, slub_min_objects,
+ slab_min_order, slab_max_order, slab_min_objects,
nr_cpu_ids, nr_node_ids);
}
--
2.55.0
next prev parent reply other threads:[~2026-09-23 15:45 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-23 15:45 [PATCH RFC 0/8] replace CONFIG_SLUB_TINY with a slab_tiny boot parameter Vlastimil Babka (SUSE)
2026-09-23 15:45 ` Vlastimil Babka (SUSE) [this message]
2026-09-23 15:45 ` [PATCH RFC 2/8] mm, slab: introduce slab_debug=N Vlastimil Babka (SUSE)
2026-09-23 15:45 ` [PATCH RFC 3/8] mm, slab: rework KMALLOC_RECLAIM handling of SLUB_TINY Vlastimil Babka (SUSE)
2026-09-23 15:45 ` [PATCH RFC 4/8] mm, slab: make SLUB_TINY handling dynamic for sizing decisions Vlastimil Babka (SUSE)
2026-09-23 15:45 ` [PATCH RFC 5/8] mm, slab: convert CONFIG_SLUB_TINY checks to kmem_cache_debug() Vlastimil Babka (SUSE)
2026-09-23 15:45 ` [PATCH RFC 6/8] mm, slab: remove remaining compile-time checks for CONFIG_SLUB_TINY Vlastimil Babka (SUSE)
2026-09-23 15:45 ` [PATCH RFC 7/8] mm, slab: add slab_tiny boot param Vlastimil Babka (SUSE)
2026-09-23 15:45 ` [PATCH RFC 8/8] mm, slab: deprecate CONFIG_SLUB_TINY and reduce its Kconfig effects Vlastimil Babka (SUSE)
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=20260923-slub_tiny_rework-v1-1-a0e66d536eb5@kernel.org \
--to=vbabka@kernel.org \
--cc=cl@gentwo.org \
--cc=conor@kernel.org \
--cc=damien.lemoal@opensource.wdc.com \
--cc=geert@linux-m68k.org \
--cc=hao.li@linux.dev \
--cc=harry@kernel.org \
--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
all inboxes | Powered by JetHome®