Re: [PATCH v2 3/4] LoongArch: BPF: Refactor jump offset calculation in tail call

From: bot+bpf-ci

Date: Mon Jul 06 2026 - 00:43:39 EST


> In emit_bpf_tail_call(), the macro-based jmp_offset calculation relies
> on a fragile prediction equation: "tc_ninsn - (ctx->idx - idx0)". This
> calculation model utilizes tc_ninsn from the previous pass to estimate
> the remaining stride of the active tail call code block.
>
> Given that the macro relies on stale layout data from a prior pass to
> compute the active relative stride, the conditional branches end up
> encoding wrong immediate offsets under extra JIT passes. Consequently,
> the execution flow leaps into misaligned instruction boundaries,
> triggering soft lockups or early loop collapse.
>
> To fix this issue, drop the pass-dependent macro and the intermediate
> variable entirely. Instead, explicitly calculate "jmp_offset" using an
> absolute target reference anchor: "ctx->offset[insn + 1] - ctx->idx".
>
> However, during the initial size-estimation pass, the target address
> "ctx->offset[insn + 1]" is not yet populated and will evaluate to 0,
> resulting in "jmp_offset = -ctx->idx". For large eBPF programs, this
> inflated negative offset would overflow the 16-bit signed immediate
> limit of LoongArch conditional branch instructions, causing the range
> validation inside emit_tailcall_jmp() to abort the JIT compilation
> prematurely.
>
> To bypass this initialization bottleneck cleanly without changing any
> function signatures, leverage the "ctx->image" pointer to safely detect
> the initial pass. Since conditional branch instructions on LoongArch
> maintain a fixed 4-byte width regardless of the target displacement,
> injecting a safe dummy offset (0) when "ctx->image == NULL" preserves
> accurate size estimation while preventing 16-bit range check failures.
>
> Within this new deterministic arithmetic model:
> 1) "ctx->offset[insn + 1]" maps directly to the absolute instruction
> index of the immediate next eBPF business instruction, serving as
> a rock-solid target label.
> 2) "ctx->idx" tracks the real-time instruction index of the conditional
> branch currently being emitted.
>
> This guarantees the generated immediate offsets always land precisely
> on the next instruction boundary under all multi-pass compilation paths
> and all code size dimensions.
>
> Signed-off-by: Tiezhu Yang <yangtiezhu@xxxxxxxxxxx>

This looks like a fix for wrong branch offsets in the tail call path.
Should it carry a Fixes: tag? The tc_ninsn macro and the

tc_ninsn = insn ? ctx->offset[insn+1] - ctx->offset[insn] : ctx->offset[0];

calculation being removed here were introduced by:

Fixes: cd39d9e6b7e4 ("LoongArch: BPF: Fix jump offset calculation in tailcall")

This isn't a bug, but could the changelog be tightened? Phrases such as
"rock-solid target label", "deterministic arithmetic model",
"initialization bottleneck", "eBPF business instruction" and "all code
size dimensions" read as fairly ornate for an offset-formula refactor.

Could it just state that the old macro derived jmp_offset from a stale
prior-pass stride while the new form anchors on ctx->offset[insn + 1],
with the ctx->image == NULL guard avoiding a false 16-bit range abort
during size estimation?


---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md

CI run summary: https://github.com/kernel-patches/bpf/actions/runs/28766636714