From: Maxim Khmelevskii Date: Tue, 14 Apr 2026 14:29:26 +0000 (+0200) Subject: s390/bpf: Inline smp_processor_id and current_task X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9012cf2491e3c5d28d098b0d6da804af82977032;p=thirdparty%2Fkernel%2Flinux.git s390/bpf: Inline smp_processor_id and current_task Inline these calls in bpf jit: - bpf_get_smp_processor_id() - bpf_get_current_task() - bpf_get_current_task_btf() s390 has a 8 KiB per-CPU prefix area in the CPU's virtual address space, called the lowcore. It is a struct that contains the cpu number and a pointer to the current task. These are exactly the values returned by the BPF helpers. Emit a load from the lowcore instead of a helper function call. JIT output for `bpf_get_smp_processor_id`: Before: After: --------------- ---------------- brasl %r14,0x3ffe0385460 ly %r14,928 lgr %r14,%r2 JIT output for `bpf_get_current_task`: Before: After: --------------- ---------------- brasl %r14,0x3ffe0362a90 lg %r14,832 lgr %r14,%r2 Benchmark using [1] on KVM(virtme-ng). ./benchs/run_bench_trigger.sh glob-arr-inc arr-inc hash-inc +---------------+--------------------+--------------------+--------------+ | Name | Before | After | % change | |---------------+--------------------+--------------------+--------------| | glob-arr-inc | 244.954 ± 0.654M/s | 278.501 ± 0.834M/s | + 13.70% | | arr-inc | 311.597 ± 1.016M/s | 313.610 ± 0.331M/s | + 0.65% | | hash-inc | 47.421 ± 0.017M/s | 47.600 ± 0.004M/s | + 0.38% | +---------------+--------------------+--------------------+--------------+ [1] https://github.com/anakryiko/linux/commit/8dec900975ef Signed-off-by: Maxim Khmelevskii Reviewed-by: Ilya Leoshkevich Link: https://lore.kernel.org/r/20260414142930.528751-1-max@linux.ibm.com Signed-off-by: Alexei Starovoitov --- diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c index 94128fe6be233..14eaaa5b21851 100644 --- a/arch/s390/net/bpf_jit_comp.c +++ b/arch/s390/net/bpf_jit_comp.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -1777,6 +1778,30 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int j, ret; u64 func; + /* Implement helper call to bpf_get_smp_processor_id() inline */ + if (insn->src_reg == 0 && + insn->imm == BPF_FUNC_get_smp_processor_id) { + const u32 *cpu_nr = &get_lowcore()->cpu_nr; + + /* ly %b0, cpu_nr */ + EMIT6_DISP_LH(0xe3000000, 0x0058, BPF_REG_0, REG_0, REG_0, + (unsigned long)cpu_nr); + break; + } + + /* Implement helper call to bpf_get_current_task/_btf() inline */ + if (insn->src_reg == 0 && + (insn->imm == BPF_FUNC_get_current_task || + insn->imm == BPF_FUNC_get_current_task_btf)) { + const u64 *current_task = + &get_lowcore()->current_task; + + /* lg %b0, current_task */ + EMIT6_DISP_LH(0xe3000000, 0x0004, BPF_REG_0, REG_0, REG_0, + (unsigned long)current_task); + break; + } + ret = bpf_jit_get_func_addr(fp, insn, extra_pass, &func, &func_addr_fixed); if (ret < 0) @@ -3057,3 +3082,15 @@ bool bpf_jit_supports_timed_may_goto(void) { return true; } + +bool bpf_jit_inlines_helper_call(s32 imm) +{ + switch (imm) { + case BPF_FUNC_get_smp_processor_id: + case BPF_FUNC_get_current_task: + case BPF_FUNC_get_current_task_btf: + return true; + default: + return false; + } +}