Backport 2 salb improve patch, which has 1% improve for fork.
Vlastimil Babka (2): mm, slab: put should_failslab() back behind CONFIG_SHOULD_FAILSLAB mm, page_alloc: put should_fail_alloc_page() back behing CONFIG_FAIL_PAGE_ALLOC
include/linux/fault-inject.h | 11 ++++------- kernel/bpf/verifier.c | 4 ++++ mm/fail_page_alloc.c | 4 +++- mm/failslab.c | 14 ++++++++------ mm/page_alloc.c | 6 ------ mm/slab_common.c | 8 -------- 6 files changed, 19 insertions(+), 28 deletions(-)
From: Vlastimil Babka vbabka@suse.cz
mainline inclusion from mainline-v6.11-rc1 commit a7526fe8b94eced7d82aa00b2bcca44e39ae0769 category: performance bugzilla: https://gitee.com/src-openeuler/kernel/issues/IB0VAP
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i...
--------------------------------
Patch series "revert unconditional slab and page allocator fault injection calls".
These two patches largely revert commits that added function call overhead into slab and page allocation hotpaths and that cannot be currently disabled even though related CONFIG_ options do exist.
A much more involved solution that can keep the callsites always existing but hidden behind a static key if unused, is possible [1] and can be pursued by anyone who believes it's necessary. Meanwhile the fact the should_failslab() error injection is already not functional on kernels built with current gcc without anyone noticing [2], and lukewarm response to [1] suggests the need is not there. I believe it will be more fair to have the state after this series as a baseline for possible further optimisation, instead of the unconditional overhead.
For example a possible compromise for anyone who's fine with an empty function call overhead but not the full CONFIG_FAILSLAB / CONFIG_FAIL_PAGE_ALLOC overhead is to reuse patch 1 from [1] but insert a static key check only inside should_failslab() and should_fail_alloc_page() before performing the more expensive checks.
[1] https://lore.kernel.org/all/20240620-fault-injection-statickeys-v2-0-e23947d... [2] https://github.com/bpftrace/bpftrace/issues/3258
This patch (of 2):
This mostly reverts commit 4f6923fbb352 ("mm: make should_failslab always available for fault injection"). The commit made should_failslab() a noinline function that's always called from the slab allocation hotpath, even if it's empty because CONFIG_SHOULD_FAILSLAB is not enabled, and there is no option to disable that call. This is visible in profiles and the function call overhead can be noticeable especially with cpu mitigations.
Meanwhile the bpftrace program example in the commit silently does not work without CONFIG_SHOULD_FAILSLAB anyway with a recent gcc, because the empty function gets a .constprop clone that is actually being called (uselessly) from the slab hotpath, while the error injection is hooked to the original function that's not being called at all [1].
Thus put the whole should_failslab() function back behind CONFIG_SHOULD_FAILSLAB. It's not a complete revert of 4f6923fbb352 - the int return type that returns -ENOMEM on failure is preserved, as well ALLOW_ERROR_INJECTION annotation. The BTF_ID() record that was meanwhile added is also guarded by CONFIG_SHOULD_FAILSLAB.
[1] https://github.com/bpftrace/bpftrace/issues/3258
Link: https://lkml.kernel.org/r/20240711-b4-fault-injection-reverts-v1-0-9e2651945... Link: https://lkml.kernel.org/r/20240711-b4-fault-injection-reverts-v1-1-9e2651945... Signed-off-by: Vlastimil Babka vbabka@suse.cz Cc: Akinobu Mita akinobu.mita@gmail.com Cc: Alexei Starovoitov ast@kernel.org Cc: Andrii Nakryiko andrii@kernel.org Cc: Christoph Lameter cl@linux.com Cc: Daniel Borkmann daniel@iogearbox.net Cc: David Rientjes rientjes@google.com Cc: Eduard Zingerman eddyz87@gmail.com Cc: Hao Luo haoluo@google.com Cc: Hyeonggon Yoo 42.hyeyoo@gmail.com Cc: Jiri Olsa jolsa@kernel.org Cc: John Fastabend john.fastabend@gmail.com Cc: KP Singh kpsingh@kernel.org Cc: Martin KaFai Lau martin.lau@linux.dev Cc: Mateusz Guzik mjguzik@gmail.com Cc: Roman Gushchin roman.gushchin@linux.dev Cc: Song Liu song@kernel.org Cc: Stanislav Fomichev sdf@fomichev.me Cc: Yonghong Song yonghong.song@linux.dev Signed-off-by: Andrew Morton akpm@linux-foundation.org
Conflicts: mm/slab_common.c mm/slub.c [Context conflicts.] Signed-off-by: Li Zetao lizetao1@huawei.com --- include/linux/fault-inject.h | 5 ++--- kernel/bpf/verifier.c | 2 ++ mm/failslab.c | 14 ++++++++------ mm/slab_common.c | 8 -------- 4 files changed, 12 insertions(+), 17 deletions(-)
diff --git a/include/linux/fault-inject.h b/include/linux/fault-inject.h index 6d5edef09d45..be6d0bc111ad 100644 --- a/include/linux/fault-inject.h +++ b/include/linux/fault-inject.h @@ -102,11 +102,10 @@ static inline bool __should_fail_alloc_page(gfp_t gfp_mask, unsigned int order) } #endif /* CONFIG_FAIL_PAGE_ALLOC */
-int should_failslab(struct kmem_cache *s, gfp_t gfpflags); #ifdef CONFIG_FAILSLAB -extern bool __should_failslab(struct kmem_cache *s, gfp_t gfpflags); +int should_failslab(struct kmem_cache *s, gfp_t gfpflags); #else -static inline bool __should_failslab(struct kmem_cache *s, gfp_t gfpflags) +static inline int should_failslab(struct kmem_cache *s, gfp_t gfpflags) { return false; } diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 817d74e08e13..96f37ae3c48e 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -20012,7 +20012,9 @@ BTF_SET_START(btf_non_sleepable_error_inject) */ BTF_ID(func, __filemap_add_folio) BTF_ID(func, should_fail_alloc_page) +#ifdef CONFIG_FAILSLAB BTF_ID(func, should_failslab) +#endif BTF_SET_END(btf_non_sleepable_error_inject)
static int check_non_sleepable_error_inject(u32 btf_id) diff --git a/mm/failslab.c b/mm/failslab.c index ffc420c0e767..af16c2ed578f 100644 --- a/mm/failslab.c +++ b/mm/failslab.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include <linux/fault-inject.h> +#include <linux/error-injection.h> #include <linux/slab.h> #include <linux/mm.h> #include "slab.h" @@ -14,23 +15,23 @@ static struct { .cache_filter = false, };
-bool __should_failslab(struct kmem_cache *s, gfp_t gfpflags) +int should_failslab(struct kmem_cache *s, gfp_t gfpflags) { int flags = 0;
/* No fault-injection for bootstrap cache */ if (unlikely(s == kmem_cache)) - return false; + return 0;
if (gfpflags & __GFP_NOFAIL) - return false; + return 0;
if (failslab.ignore_gfp_reclaim && (gfpflags & __GFP_DIRECT_RECLAIM)) - return false; + return 0;
if (failslab.cache_filter && !(s->flags & SLAB_FAILSLAB)) - return false; + return 0;
/* * In some cases, it expects to specify __GFP_NOWARN @@ -41,8 +42,9 @@ bool __should_failslab(struct kmem_cache *s, gfp_t gfpflags) if (gfpflags & __GFP_NOWARN) flags |= FAULT_NOWARN;
- return should_fail_ex(&failslab.attr, s->object_size, flags); + return should_fail_ex(&failslab.attr, s->object_size, flags) ? -ENOMEM : 0; } +ALLOW_ERROR_INJECTION(should_failslab, ERRNO);
static int __init setup_failslab(char *str) { diff --git a/mm/slab_common.c b/mm/slab_common.c index ef971fcdaa07..a091030e4cfc 100644 --- a/mm/slab_common.c +++ b/mm/slab_common.c @@ -1494,11 +1494,3 @@ EXPORT_TRACEPOINT_SYMBOL(kmalloc); EXPORT_TRACEPOINT_SYMBOL(kmem_cache_alloc); EXPORT_TRACEPOINT_SYMBOL(kfree); EXPORT_TRACEPOINT_SYMBOL(kmem_cache_free); - -int should_failslab(struct kmem_cache *s, gfp_t gfpflags) -{ - if (__should_failslab(s, gfpflags)) - return -ENOMEM; - return 0; -} -ALLOW_ERROR_INJECTION(should_failslab, ERRNO);
From: Vlastimil Babka vbabka@suse.cz
mainline inclusion from mainline-v6.11-rc1 commit 53dabce2652fb854eae84609ce9c37429d5d87ba category: performance bugzilla: https://gitee.com/src-openeuler/kernel/issues/IB0VAP
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i...
--------------------------------
This mostly reverts commit af3b854492f3 ("mm/page_alloc.c: allow error injection"). The commit made should_fail_alloc_page() a noinline function that's always called from the page allocation hotpath, even if it's empty because CONFIG_FAIL_PAGE_ALLOC is not enabled, and there is no option to disable it and prevent the associated function call overhead.
As with the preceding patch "mm, slab: put should_failslab back behind CONFIG_SHOULD_FAILSLAB" and for the same reasons, put the should_fail_alloc_page() back behind the config option. When enabled, the ALLOW_ERROR_INJECTION and BTF_ID records are preserved so it's not a complete revert.
Link: https://lkml.kernel.org/r/20240711-b4-fault-injection-reverts-v1-2-9e2651945... Signed-off-by: Vlastimil Babka vbabka@suse.cz Cc: Akinobu Mita akinobu.mita@gmail.com Cc: Alexei Starovoitov ast@kernel.org Cc: Andrii Nakryiko andrii@kernel.org Cc: Christoph Lameter cl@linux.com Cc: Daniel Borkmann daniel@iogearbox.net Cc: David Rientjes rientjes@google.com Cc: Eduard Zingerman eddyz87@gmail.com Cc: Hao Luo haoluo@google.com Cc: Hyeonggon Yoo 42.hyeyoo@gmail.com Cc: Jiri Olsa jolsa@kernel.org Cc: John Fastabend john.fastabend@gmail.com Cc: KP Singh kpsingh@kernel.org Cc: Martin KaFai Lau martin.lau@linux.dev Cc: Mateusz Guzik mjguzik@gmail.com Cc: Roman Gushchin roman.gushchin@linux.dev Cc: Song Liu song@kernel.org Cc: Stanislav Fomichev sdf@fomichev.me Cc: Yonghong Song yonghong.song@linux.dev Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Li Zetao lizetao1@huawei.com --- include/linux/fault-inject.h | 6 ++---- kernel/bpf/verifier.c | 2 ++ mm/fail_page_alloc.c | 4 +++- mm/page_alloc.c | 6 ------ 4 files changed, 7 insertions(+), 11 deletions(-)
diff --git a/include/linux/fault-inject.h b/include/linux/fault-inject.h index be6d0bc111ad..354413950d34 100644 --- a/include/linux/fault-inject.h +++ b/include/linux/fault-inject.h @@ -91,12 +91,10 @@ static inline void fault_config_init(struct fault_config *config,
struct kmem_cache;
-bool should_fail_alloc_page(gfp_t gfp_mask, unsigned int order); - #ifdef CONFIG_FAIL_PAGE_ALLOC -bool __should_fail_alloc_page(gfp_t gfp_mask, unsigned int order); +bool should_fail_alloc_page(gfp_t gfp_mask, unsigned int order); #else -static inline bool __should_fail_alloc_page(gfp_t gfp_mask, unsigned int order) +static inline bool should_fail_alloc_page(gfp_t gfp_mask, unsigned int order) { return false; } diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 96f37ae3c48e..c84407f5a6d3 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -20011,7 +20011,9 @@ BTF_SET_START(btf_non_sleepable_error_inject) * Assume non-sleepable from bpf safety point of view. */ BTF_ID(func, __filemap_add_folio) +#ifdef CONFIG_FAIL_PAGE_ALLOC BTF_ID(func, should_fail_alloc_page) +#endif #ifdef CONFIG_FAILSLAB BTF_ID(func, should_failslab) #endif diff --git a/mm/fail_page_alloc.c b/mm/fail_page_alloc.c index b1b09cce9394..532851ce5132 100644 --- a/mm/fail_page_alloc.c +++ b/mm/fail_page_alloc.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include <linux/fault-inject.h> +#include <linux/error-injection.h> #include <linux/mm.h>
static struct { @@ -21,7 +22,7 @@ static int __init setup_fail_page_alloc(char *str) } __setup("fail_page_alloc=", setup_fail_page_alloc);
-bool __should_fail_alloc_page(gfp_t gfp_mask, unsigned int order) +bool should_fail_alloc_page(gfp_t gfp_mask, unsigned int order) { int flags = 0;
@@ -41,6 +42,7 @@ bool __should_fail_alloc_page(gfp_t gfp_mask, unsigned int order)
return should_fail_ex(&fail_page_alloc.attr, 1 << order, flags); } +ALLOW_ERROR_INJECTION(should_fail_alloc_page, TRUE);
#ifdef CONFIG_FAULT_INJECTION_DEBUG_FS
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 52382ba24232..6d43d3206b57 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -2959,12 +2959,6 @@ struct page *rmqueue(struct zone *preferred_zone, return page; }
-noinline bool should_fail_alloc_page(gfp_t gfp_mask, unsigned int order) -{ - return __should_fail_alloc_page(gfp_mask, order); -} -ALLOW_ERROR_INJECTION(should_fail_alloc_page, TRUE); - static inline long __zone_watermark_unusable_free(struct zone *z, unsigned int order, unsigned int alloc_flags) {
反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://gitee.com/openeuler/kernel/pulls/14091 邮件列表地址:https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/D...
FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://gitee.com/openeuler/kernel/pulls/14091 Mailing list address: https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/D...