Re: [PATCH bpf-next v3 4/5] bpf, x86: make sure allocation in arch_bpf_trampoline_size() is writable
Daniel Borkmann <[email protected]>
| Newsgroups | org.kernel.vger.bpf,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
On 8/16/26 10:57 AM, Mike Rapoport wrote: > On Fri, Aug 14, 2026 at 04:53:32PM +0200, Jiri Olsa wrote: >> On Thu, Jul 16, 2026 at 10:51:38AM +0300, Mike Rapoport (Microsoft) wrote: >>> arch_bpf_trampoline_size() allocates a buffer to get actual size required >>> for a trampoline. >>> >>> This buffer must be in the module address space because >>> __arch_prepare_bpf_trampoline() calculates rel32 offsets relatively to >>> that buffer. >>> >>> In preparation for enabling ROX mode for EXECMEM_BPF make sure that the >>> allocated memory is writable. >>> >>> Add bpf_jit_alloc_exec_rw() wrapper for execmem_alloc_rw() and use it for > buffer allocation in arch_bpf_trampoline_size(). >>> >>> Signed-off-by: Mike Rapoport (Microsoft) <[email protected]> >>> --- >>> arch/x86/net/bpf_jit_comp.c | 5 ++--- >>> include/linux/filter.h | 1 + >>> kernel/bpf/core.c | 5 +++++ >>> 3 files changed, 8 insertions(+), 3 deletions(-) >>> >>> diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c >>> index de7515ea1bea..b2feec81e231 100644 >>> --- a/arch/x86/net/bpf_jit_comp.c >>> +++ b/arch/x86/net/bpf_jit_comp.c >>> @@ -3703,13 +3703,12 @@ int arch_bpf_trampoline_size(const struct btf_func_model *m, u32 flags, >>> int ret; >>> >>> /* Allocate a temporary buffer for __arch_prepare_bpf_trampoline(). >>> - * This will NOT cause fragmentation in direct map, as we do not >>> - * call set_memory_*() on this buffer. >>> * >>> * 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(). >>> */ >>> - image = bpf_jit_alloc_exec(PAGE_SIZE); >>> + image = bpf_jit_alloc_exec_rw(PAGE_SIZE); >> >> hi, >> this change (this particular patch plus possibly others in this set) is >> causing tracing_multi attachment bench slowdown >> >> the benchmark allocates huge number of trampolines and I'm seeing extra >> arch_bpf_trampoline_size code paths in the attached perf profile >> >> I'm not that familiar with the allocator, but following hack makes the >> benchmark ok again: >> >> diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c >> index 6a94370a2448..bbff3c9c6681 100644 >> --- a/kernel/bpf/core.c >> +++ b/kernel/bpf/core.c >> @@ -1130,7 +1130,7 @@ void *bpf_jit_alloc_exec(unsigned long size) >> >> void *bpf_jit_alloc_exec_rw(unsigned long size) >> { >> - return execmem_alloc_rw(EXECMEM_BPF, size); >> + return execmem_alloc(EXECMEM_MODULE_DATA, size); > > This is fine on x86 because all execmem types live in the same 2G > range. Other architectures may have _BPF and MODULE_DATA in different > ranges, e.g arm64 and some configurations of powerpc. > >> } >> >> void bpf_jit_free_exec(void *addr) >> >> >> I still need to do more checks, but I'm wondering if we could actually fix >> this by not allocating image data in arch_bpf_trampoline_size at all.. >> and just teach __arch_prepare_bpf_trampoline to survive NULL image data >> and just return the size in such case > > Since bpf_jit_alloc_exec_rw() is only used by > x86::arch_bpf_trampoline_size() I think we can directly allocate from > _MODULE_DATA there and drop bpf_jit_alloc_exec_rw(), like (build tested > only) patch below does. > > If/when other architectures would implement arch_bpf_trampoline_size(), > they'll probably need to deal with this differently. Mike, could you send this as a regular patch to bpf list, so it can go through BPF CI? Thanks, Daniel