Skip to content

Commit 66d135f

Browse files
Haoran JiangKernel Patches Daemon
Haoran Jiang
authored and
Kernel Patches Daemon
committed
LoongArch: BPF: Optimize the calculation method of jmp_offset in the emit_bpf_tail_call function
For a ebpf subprog JIT,the last call bpf_int_jit_compile function will directly enter the skip_init_ctx process. At this point, out_offset = -1, the jmp_offset in emit_bpf_tail_call is calculated by #define jmp_offset (out_offset - (cur_offset)) is a negative number, which does not meet expectations.The final generated assembly as follow. 54: bgeu $a2, $t1, -8 # 0x0000004c 58: addi.d $a6, $s5, -1 5c: bltz $a6, -16 # 0x0000004c 60: alsl.d $t2, $a2, $a1, 0x3 64: ld.d $t2, $t2, 264 68: beq $t2, $zero, -28 # 0x0000004c Before apply this patch, the follow test case will reveal soft lock issues. cd tools/testing/selftests/bpf/ ./test_progs --allow=tailcalls/tailcall_bpf2bpf_1 dmesg: watchdog: BUG: soft lockup - CPU#2 stuck for 26s! [test_progs:25056] Signed-off-by: Haoran Jiang <[email protected]>
1 parent de55d92 commit 66d135f

File tree

1 file changed

+9
-19
lines changed

1 file changed

+9
-19
lines changed

arch/loongarch/net/bpf_jit.c

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -208,9 +208,7 @@ bool bpf_jit_supports_far_kfunc_call(void)
208208
return true;
209209
}
210210

211-
/* initialized on the first pass of build_body() */
212-
static int out_offset = -1;
213-
static int emit_bpf_tail_call(struct jit_ctx *ctx)
211+
static int emit_bpf_tail_call(int insn, struct jit_ctx *ctx)
214212
{
215213
int off;
216214
u8 tcc = tail_call_reg(ctx);
@@ -220,9 +218,8 @@ static int emit_bpf_tail_call(struct jit_ctx *ctx)
220218
u8 t2 = LOONGARCH_GPR_T2;
221219
u8 t3 = LOONGARCH_GPR_T3;
222220
const int idx0 = ctx->idx;
223-
224-
#define cur_offset (ctx->idx - idx0)
225-
#define jmp_offset (out_offset - (cur_offset))
221+
int tc_ninsn = 0;
222+
int jmp_offset = 0;
226223

227224
/*
228225
* a0: &ctx
@@ -232,8 +229,11 @@ static int emit_bpf_tail_call(struct jit_ctx *ctx)
232229
* if (index >= array->map.max_entries)
233230
* goto out;
234231
*/
232+
tc_ninsn = insn ? ctx->offset[insn+1] - ctx->offset[insn] :
233+
ctx->offset[0];
235234
off = offsetof(struct bpf_array, map.max_entries);
236235
emit_insn(ctx, ldwu, t1, a1, off);
236+
jmp_offset = tc_ninsn - (ctx->idx - idx0);
237237
/* bgeu $a2, $t1, jmp_offset */
238238
if (emit_tailcall_jmp(ctx, BPF_JGE, a2, t1, jmp_offset) < 0)
239239
goto toofar;
@@ -243,6 +243,7 @@ static int emit_bpf_tail_call(struct jit_ctx *ctx)
243243
* goto out;
244244
*/
245245
emit_insn(ctx, addid, REG_TCC, tcc, -1);
246+
jmp_offset = tc_ninsn - (ctx->idx - idx0);
246247
if (emit_tailcall_jmp(ctx, BPF_JSLT, REG_TCC, LOONGARCH_GPR_ZERO, jmp_offset) < 0)
247248
goto toofar;
248249

@@ -254,6 +255,7 @@ static int emit_bpf_tail_call(struct jit_ctx *ctx)
254255
emit_insn(ctx, alsld, t2, a2, a1, 2);
255256
off = offsetof(struct bpf_array, ptrs);
256257
emit_insn(ctx, ldd, t2, t2, off);
258+
jmp_offset = tc_ninsn - (ctx->idx - idx0);
257259
/* beq $t2, $zero, jmp_offset */
258260
if (emit_tailcall_jmp(ctx, BPF_JEQ, t2, LOONGARCH_GPR_ZERO, jmp_offset) < 0)
259261
goto toofar;
@@ -263,22 +265,11 @@ static int emit_bpf_tail_call(struct jit_ctx *ctx)
263265
emit_insn(ctx, ldd, t3, t2, off);
264266
__build_epilogue(ctx, true);
265267

266-
/* out: */
267-
if (out_offset == -1)
268-
out_offset = cur_offset;
269-
if (cur_offset != out_offset) {
270-
pr_err_once("tail_call out_offset = %d, expected %d!\n",
271-
cur_offset, out_offset);
272-
return -1;
273-
}
274-
275268
return 0;
276269

277270
toofar:
278271
pr_info_once("tail_call: jump too far\n");
279272
return -1;
280-
#undef cur_offset
281-
#undef jmp_offset
282273
}
283274

284275
static void emit_atomic(const struct bpf_insn *insn, struct jit_ctx *ctx)
@@ -916,7 +907,7 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext
916907
/* tail call */
917908
case BPF_JMP | BPF_TAIL_CALL:
918909
mark_tail_call(ctx);
919-
if (emit_bpf_tail_call(ctx) < 0)
910+
if (emit_bpf_tail_call(i, ctx) < 0)
920911
return -EINVAL;
921912
break;
922913

@@ -1342,7 +1333,6 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
13421333
if (tmp_blinded)
13431334
bpf_jit_prog_release_other(prog, prog == orig_prog ? tmp : orig_prog);
13441335

1345-
out_offset = -1;
13461336

13471337
return prog;
13481338

0 commit comments

Comments
 (0)