Skip to content

Commit d46d5b7

Browse files
Pu LehuiKernel Patches Daemon
authored andcommitted
riscv, bpf: Optimize cmpxchg insn with Zacas support
Optimize cmpxchg instruction with amocas.w and amocas.d Zacas instructions. Signed-off-by: Pu Lehui <[email protected]>
1 parent c36239c commit d46d5b7

File tree

2 files changed

+29
-16
lines changed

2 files changed

+29
-16
lines changed

arch/riscv/net/bpf_jit.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1294,6 +1294,33 @@ static inline void emit_bswap(u8 rd, s32 imm, struct rv_jit_context *ctx)
12941294
emit_mv(rd, RV_REG_T2, ctx);
12951295
}
12961296

1297+
static inline void emit_cmpxchg(u8 rd, u8 rs, u8 r0, bool is64, struct rv_jit_context *ctx)
1298+
{
1299+
int jmp_offset;
1300+
1301+
if (rv_ext_enabled(ZACAS)) {
1302+
emit(is64 ? rvzacas_amocas_d(r0, rs, rd, 1, 1) :
1303+
rvzacas_amocas_w(r0, rs, rd, 1, 1), ctx);
1304+
if (!is64)
1305+
emit_zextw(r0, r0, ctx);
1306+
return;
1307+
}
1308+
1309+
if (is64)
1310+
emit_mv(RV_REG_T2, r0, ctx);
1311+
else
1312+
emit_addiw(RV_REG_T2, r0, 0, ctx);
1313+
emit(is64 ? rv_lr_d(r0, 0, rd, 0, 0) :
1314+
rv_lr_w(r0, 0, rd, 0, 0), ctx);
1315+
jmp_offset = ninsns_rvoff(8);
1316+
emit(rv_bne(RV_REG_T2, r0, jmp_offset >> 1), ctx);
1317+
emit(is64 ? rv_sc_d(RV_REG_T3, rs, rd, 0, 1) :
1318+
rv_sc_w(RV_REG_T3, rs, rd, 0, 1), ctx);
1319+
jmp_offset = ninsns_rvoff(-6);
1320+
emit(rv_bne(RV_REG_T3, 0, jmp_offset >> 1), ctx);
1321+
emit_fence_rw_rw(ctx);
1322+
}
1323+
12971324
#endif /* __riscv_xlen == 64 */
12981325

12991326
void bpf_jit_build_prologue(struct rv_jit_context *ctx, bool is_subprog);

arch/riscv/net/bpf_jit_comp64.c

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -599,10 +599,9 @@ static int emit_atomic_ld_st(u8 rd, u8 rs, const struct bpf_insn *insn,
599599
static int emit_atomic_rmw(u8 rd, u8 rs, const struct bpf_insn *insn,
600600
struct rv_jit_context *ctx)
601601
{
602-
u8 r0, code = insn->code;
602+
u8 code = insn->code;
603603
s16 off = insn->off;
604604
s32 imm = insn->imm;
605-
int jmp_offset;
606605
bool is64;
607606

608607
if (BPF_SIZE(code) != BPF_W && BPF_SIZE(code) != BPF_DW) {
@@ -673,20 +672,7 @@ static int emit_atomic_rmw(u8 rd, u8 rs, const struct bpf_insn *insn,
673672
break;
674673
/* r0 = atomic_cmpxchg(dst_reg + off16, r0, src_reg); */
675674
case BPF_CMPXCHG:
676-
r0 = bpf_to_rv_reg(BPF_REG_0, ctx);
677-
if (is64)
678-
emit_mv(RV_REG_T2, r0, ctx);
679-
else
680-
emit_addiw(RV_REG_T2, r0, 0, ctx);
681-
emit(is64 ? rv_lr_d(r0, 0, rd, 0, 0) :
682-
rv_lr_w(r0, 0, rd, 0, 0), ctx);
683-
jmp_offset = ninsns_rvoff(8);
684-
emit(rv_bne(RV_REG_T2, r0, jmp_offset >> 1), ctx);
685-
emit(is64 ? rv_sc_d(RV_REG_T3, rs, rd, 0, 1) :
686-
rv_sc_w(RV_REG_T3, rs, rd, 0, 1), ctx);
687-
jmp_offset = ninsns_rvoff(-6);
688-
emit(rv_bne(RV_REG_T3, 0, jmp_offset >> 1), ctx);
689-
emit_fence_rw_rw(ctx);
675+
emit_cmpxchg(rd, rs, regmap[BPF_REG_0], is64, ctx);
690676
break;
691677
default:
692678
pr_err_once("bpf-jit: invalid atomic RMW opcode %02x\n", imm);

0 commit comments

Comments
 (0)