Introduce 2 ways to setup/configure "unlimited_slabs" tweak: 1. "slub.unlimited_slabs=" kernel boot option * "slub.unlimited_slabs=1" to enable the tweak * "slub.unlimited_slabs=0" to disable the tweak
2. /sys/kernel/debug/unlimited_slabs entry * echo 1 > /sys/module/slub/parameters/unlimited_slabs to enable the tweak * echo 0 > /sys/module/slub/parameters/unlimited_slabs to disable the tweak The module parameter is BOOL, you can use [yYnN01] values. The "unlimited_slabs" functionality is disabled by default. Note: do not forget to mark SLABs with "pf_malloc" flag (use slub_debug=M to mark all SLABs by default on boot). https://virtuozzo.atlassian.net/browse/PSBM-155867 Signed-off-by: Konstantin Khorenko <khore...@virtuozzo.com> --- v2: * static key renamed from "unlimited_slabs" to "unlimited_slabs_key" * scheme of using __setup() for kernel boot option and manually created debugfs entry has been substituted by module_param_cb() which automatically creates debugfs entry for module parameter. * kernel boot option changed from "unlimited_slabs" to "slub.unlimited_slabs" as it's now module parameter * the module parameter is BOOL, so [yYnN01] values can be used * static keys cannot be switched during kernel boot option parsing, so the actual switch is delayed to late_init stag v3: * use late_param_cb() instead of module_param_cb(), it allows to avoid using separate boot option parsing and using a separate delayed static_key configuration function. mm/slub.c | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/mm/slub.c b/mm/slub.c index ea3e20e73fe6..ec823232923e 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -2466,6 +2466,40 @@ static inline void *get_freelist(struct kmem_cache *s, struct page *page) return freelist; } +struct static_key unlimited_slabs_key = STATIC_KEY_INIT_FALSE; +static bool __read_mostly unlimited_slabs = false; + +static int unlimited_slabs_set(const char *val, const struct kernel_param *kp) +{ + /* One of =[yYnN01] */ + if (strtobool(val, &unlimited_slabs) < 0) + return -EINVAL; + + if (static_key_false(&unlimited_slabs_key) && !unlimited_slabs) { + static_key_slow_dec(&unlimited_slabs_key); + printk("unlimited_slabs tweak has been disabled\n"); + } else if (!static_key_false(&unlimited_slabs_key) && unlimited_slabs) { + static_key_slow_inc(&unlimited_slabs_key); + printk("unlimited_slabs tweak has been enabled\n"); + } + + return 0; +} + +static const struct kernel_param_ops unlimited_slabs_ops = { + .set = unlimited_slabs_set, + .get = param_get_bool, +}; + +/* + * static_keys cannot be switched during early boot stage, + * so delay the setup till late_initcall + */ +late_param_cb(unlimited_slabs, &unlimited_slabs_ops, &unlimited_slabs, 0644); +__MODULE_PARM_TYPE(unlimited_slabs, "bool"); +MODULE_PARM_DESC(unlimited_slabs, + "SLABs marked with pf_memalloc flag ignore memcg limits"); + /* * Slow path. The lockless freelist is empty or we need to perform * debugging duties. @@ -2619,7 +2653,10 @@ static void *___slab_alloc_unlimited(struct kmem_cache *s, gfp_t gfpflags, int n static void *___slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node, unsigned long addr, struct kmem_cache_cpu *c) { - return ___slab_alloc_unlimited(s, gfpflags, node, addr, c); + if (static_key_false(&unlimited_slabs_key)) + return ___slab_alloc_unlimited(s, gfpflags, node, addr, c); + else + return ___slab_alloc_limited(s, gfpflags, node, addr, c); } /* -- 2.24.3 _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel