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.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.