Re: [PATCH bpf-next v3 4/5] bpf, x86: make sure allocation in arch_bpf_trampoline_size() is writable
Jiri Olsa <[email protected]>
| Newsgroups | org.kernel.vger.bpf,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <aoIZztIXgtbs7iaW@krava> |
On Sun, Aug 16, 2026 at 11:57:35AM +0300, Mike Rapoport wrote: SNIP > From 14dff78529a9204408a5c14036954df5f2f76431 Mon Sep 17 00:00:00 2001 > From: "Mike Rapoport (Microsoft)" <[email protected]> > Date: Sun, 16 Aug 2026 11:27:32 +0300 > Subject: [PATCH] x86/bpf: make arch_bpf_trampoline_size allocate from > EXECMEM_MODULE_DATA > > Jiri Olsa reports slowdown of tracing_multi benchmark that allocates huge > number of trampolines [1]. > > The slowdown caused by extra protection changes in execmem_alloc_rw() and > execmem_free(). > > With ROX caches enabled, all execmem allocations except EXECMEM_MODULE_DATA > are ROX after the allocation. execmem_alloc_rw() temporarily sets them to > W+NX and execmem_free() resets them back to ROX. > > The only user of bpf_jit_alloc_exec_rw() is x86::arch_bpf_trampoline_size() > that only needs a temporary writable buffer in the modules address space. > > On x86 executable memory and module data are constrained to the same > address range, so x86::arch_bpf_trampoline_size() can directly use > execmem_alloc(EXECMEM_MODULE_DATA) > > Replace the call to bpf_jit_alloc_exec_rw() with a call to > execmem_alloc(EXECMEM_MODULE_DATA) in x86::arch_bpf_trampoline_size() and > drop bpf_jit_alloc_exec_rw() helper. > > Reported-by: Jiri Olsa <[email protected]> > Link: https://lore.kernel.org/all/an8r7EODLIL-bZM3@krava > Fixes: f0334294a428 ("bpf, x86: make sure allocation in arch_bpf_trampoline_size() is writable") > Signed-off-by: Mike Rapoport (Microsoft) <[email protected]> looks good, thanks serial_test_tracing_multi_bench_attach: found 55077 functions serial_test_tracing_multi_bench_attach: attached in 1.470s serial_test_tracing_multi_bench_attach: detached in 0.249s Tested-by: Jiri Olsa <[email protected]> jirka > --- > arch/x86/net/bpf_jit_comp.c | 8 +++++--- > include/linux/filter.h | 1 - > kernel/bpf/core.c | 5 ----- > 3 files changed, 5 insertions(+), 9 deletions(-) > > diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c > index b2feec81e231..7d064d3e2788 100644 > --- a/arch/x86/net/bpf_jit_comp.c > +++ b/arch/x86/net/bpf_jit_comp.c > @@ -13,6 +13,7 @@ > #include <linux/bpf_verifier.h> > #include <linux/memory.h> > #include <linux/sort.h> > +#include <linux/execmem.h> > #include <asm/extable.h> > #include <asm/ftrace.h> > #include <asm/set_memory.h> > @@ -3706,15 +3707,16 @@ int arch_bpf_trampoline_size(const struct btf_func_model *m, u32 flags, > * > * We cannot use kvmalloc here, because we need image to be in > * module memory range. > - * Since it must be writable use bpf_jit_alloc_exec_rw(). > + * Since it must be writable use execmem_alloc(EXECMEM_MODULE_DATA) > + * that returns writable memory in the module address space. > */ > - image = bpf_jit_alloc_exec_rw(PAGE_SIZE); > + image = execmem_alloc(EXECMEM_MODULE_DATA, PAGE_SIZE); > if (!image) > return -ENOMEM; > > ret = __arch_prepare_bpf_trampoline(&im, image, image + PAGE_SIZE, image, > m, flags, tnodes, func_addr); > - bpf_jit_free_exec(image); > + execmem_free(image); > return ret; > } > > diff --git a/include/linux/filter.h b/include/linux/filter.h > index 32d5297c557e..14acb2455746 100644 > --- a/include/linux/filter.h > +++ b/include/linux/filter.h > @@ -1333,7 +1333,6 @@ bpf_jit_binary_alloc(unsigned int proglen, u8 **image_ptr, > void bpf_jit_binary_free(struct bpf_binary_header *hdr); > u64 bpf_jit_alloc_exec_limit(void); > void *bpf_jit_alloc_exec(unsigned long size); > -void *bpf_jit_alloc_exec_rw(unsigned long size); > void bpf_jit_free_exec(void *addr); > void bpf_jit_free(struct bpf_prog *fp); > struct bpf_binary_header * > diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c > index e2076667b245..1b89c18cf246 100644 > --- a/kernel/bpf/core.c > +++ b/kernel/bpf/core.c > @@ -1128,11 +1128,6 @@ void *bpf_jit_alloc_exec(unsigned long size) > return execmem_alloc(EXECMEM_BPF, size); > } > > -void *bpf_jit_alloc_exec_rw(unsigned long size) > -{ > - return execmem_alloc_rw(EXECMEM_BPF, size); > -} > - > void bpf_jit_free_exec(void *addr) > { > execmem_free(addr); > -- > 2.53.0 > > > > thanks, > > jirka > > -- > Sincerely yours, > Mike.