]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
LoongArch: BPF: Inline bpf_get_smp_processor_id() helper
authorTiezhu Yang <yangtiezhu@loongson.cn>
Thu, 25 Jun 2026 05:03:53 +0000 (13:03 +0800)
committerHuacai Chen <chenhuacai@loongson.cn>
Thu, 25 Jun 2026 05:03:53 +0000 (13:03 +0800)
The pointer to thread_info is always available in the $tp register, so
the call to bpf_get_smp_processor_id() can be inlined into a single load
instruction.

(1) Here is the sample test.c:

  #include <linux/bpf.h>
  #include <bpf/bpf_helpers.h>

  SEC("raw_tp/sys_enter")
  int test_cpuid(void *ctx)
  {
  return bpf_get_smp_processor_id();
  }
  char _license[] SEC("license") = "GPL";

(2) Here are the test steps:

  sudo yum install libbpf-devel kernel-devel bpftool
  clang -target bpf -O2 -c test.c -o test.o
  sudo sysctl -w net.core.bpf_jit_enable=1
  sudo bpftool prog show name test_cpuid
  sudo rm -f /sys/fs/bpf/test_cpuid
  sudo bpftool prog load test.o /sys/fs/bpf/test_cpuid
  ID=$(sudo bpftool prog show pinned /sys/fs/bpf/test_cpuid | grep -oE '^[0-9]+')
  sudo bpftool prog dump jited id $ID

(3) Here are the test results:

Before: 6 instructions

  ...
  64: lu12i.w $t1, 1213
  68: ori $t1, $t1, 1680
  6c: lu32i.d $t1, 0
  70: lu52i.d $t1, $t1, -1792
  74: jirl $ra, $t1, 0
  78: move $a5, $a0
  ...

After: 1 instruction

  ...
  64: ld.wu $a5, $tp, 16
  ...

This is similar with commit 2ddec2c80b44 ("riscv, bpf: inline
bpf_get_smp_processor_id()").

Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
arch/loongarch/net/bpf_jit.c

index 66e8c1d2d5cb5c5e7bf259ea6ca318a8a646e1c7..ad7e28375aa9513791d6863849e905dca223fde6 100644 (file)
@@ -5,6 +5,7 @@
  * Copyright (C) 2022 Loongson Technology Corporation Limited
  */
 #include <linux/memory.h>
+#include <asm/asm-offsets.h>
 #include "bpf_jit.h"
 
 #define LOONGARCH_MAX_REG_ARGS 8
@@ -1168,6 +1169,12 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext
                        break;
                }
 
+               /* Implement helper call to bpf_get_smp_processor_id() inline */
+               if (insn->src_reg == 0 && insn->imm == BPF_FUNC_get_smp_processor_id) {
+                       emit_insn(ctx, ldwu, regmap[BPF_REG_0], LOONGARCH_GPR_TP, TI_CPU);
+                       break;
+               }
+
                ret = bpf_jit_get_func_addr(ctx->prog, insn, extra_pass,
                                            &func_addr, &func_addr_fixed);
                if (ret < 0)
@@ -2394,6 +2401,7 @@ bool bpf_jit_inlines_helper_call(s32 imm)
        switch (imm) {
        case BPF_FUNC_get_current_task:
        case BPF_FUNC_get_current_task_btf:
+       case BPF_FUNC_get_smp_processor_id:
                return true;
        default:
                return false;