> diff --git a/arch/loongarch/include/asm/inst.h 
> b/arch/loongarch/include/asm/inst.h
> index 76b723590023..636cfc524b02 100644
> --- a/arch/loongarch/include/asm/inst.h
> +++ b/arch/loongarch/include/asm/inst.h
> @@ -783,6 +783,8 @@ DEF_EMIT_REG3_FORMAT(amswapb, amswapb_op)
>  DEF_EMIT_REG3_FORMAT(amswaph, amswaph_op)
>  DEF_EMIT_REG3_FORMAT(amswapw, amswapw_op)
>  DEF_EMIT_REG3_FORMAT(amswapd, amswapd_op)
> +DEF_EMIT_REG3_FORMAT(amswapdbw, amswapdbw_op)
> +DEF_EMIT_REG3_FORMAT(amswapdbd, amswapdbd_op)
>
>  #define DEF_EMIT_REG3SA2_FORMAT(NAME, OP)                            \
>  static inline void emit_##NAME(union loongarch_instruction *insn,    \

> diff --git a/arch/loongarch/net/bpf_jit.c b/arch/loongarch/net/bpf_jit.c
> index 24913dc7f4e8..f071d913e054 100644
> --- a/arch/loongarch/net/bpf_jit.c
> +++ b/arch/loongarch/net/bpf_jit.c
> @@ -482,11 +482,11 @@ static int emit_atomic_rmw(const struct bpf_insn *insn, 
> struct jit_ctx *ctx)
>                       emit_zext_32(ctx, src, true);
>                       break;
>               case BPF_W:
> -                     emit_insn(ctx, amswapw, src, t1, t3);
> +                     emit_insn(ctx, amswapdbw, src, t1, t3);
>                       emit_zext_32(ctx, src, true);
>                       break;
>               case BPF_DW:
> -                     emit_insn(ctx, amswapd, src, t1, t3);
> +                     emit_insn(ctx, amswapdbd, src, t1, t3);
>                       break;
>               }
>               break;

The commit message states that value-returning atomic RMW instructions
imply a full barrier per the LKMM.

This change only updates the BPF_W and BPF_DW BPF_XCHG cases.  Should the
other value-returning atomics in emit_atomic_rmw() get the same treatment?

The BPF_*_FETCH cases still emit the plain amadd/amand/amor/amxor variants:

arch/loongarch/net/bpf_jit.c:emit_atomic_rmw() {
        ...
        case BPF_W:
                emit_insn(ctx, amaddw, src, t1, t3);
                emit_zext_32(ctx, src, true);
                break;
        case BPF_DW:
                emit_insn(ctx, amaddd, src, t1, t3);
                break;
        ...
        case BPF_AND | BPF_FETCH:
                if (isdw) {
                        emit_insn(ctx, amandd, src, t1, t3);
                } else {
                        emit_insn(ctx, amandw, src, t1, t3);
        ...
}

The sub-word BPF_XCHG cases (BPF_B and BPF_H) still emit plain
amswap.b/amswap.h:

arch/loongarch/net/bpf_jit.c:emit_atomic_rmw() {
        ...
        case BPF_B:
                ...
                emit_insn(ctx, amswapb, src, t1, t3);
        ...
        case BPF_H:
                ...
                emit_insn(ctx, amswaph, src, t1, t3);
        ...
}

And BPF_CMPXCHG uses an ll/sc loop with no dbar barrier:

arch/loongarch/net/bpf_jit.c:emit_atomic_rmw() {
        ...
        case BPF_CMPXCHG:
                move_reg(ctx, t2, r0);
                if (isdw) {
                        emit_insn(ctx, lld, r0, t1, 0);
                        emit_insn(ctx, bne, t2, r0, 4);
                        move_reg(ctx, t3, src);
                        emit_insn(ctx, scd, t3, t1, 0);
                        emit_insn(ctx, beq, t3, LOONGARCH_GPR_ZERO, -4);
                } else {
        ...
}

These are also value-returning atomics.  If the LKMM requires a full
barrier for all of them, would these cases need updating too so that
lockless BPF algorithms stay sequentially consistent?

This was also raised by the Sashiko AI review on v2:
https://lore.kernel.org/bpf/[email protected]

There is no Fixes: tag on this commit.

The amswap.{w,d} BPF_XCHG path was introduced when the LoongArch BPF JIT
first implemented BPF_XCHG.  Should this carry:

  Fixes: 5dc615520c4d ("LoongArch: Add BPF JIT support")


---
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/26878707871

Reply via email to