* Re: [PATCH v1] LoongArch: Fix __smp_mb__{before,after}_atomic() [not found] <20260817035908.460-1-yangtiezhu@loongson.cn> @ 2026-08-18 13:28 ` Tiezhu Yang 2026-08-18 13:35 ` Kumar Kartikeya Dwivedi 0 siblings, 1 reply; 4+ messages in thread From: Tiezhu Yang @ 2026-08-18 13:28 UTC (permalink / raw) To: Huacai Chen Cc: loongarch, linux-kernel, Vincent Li, Kumar Kartikeya Dwivedi, bpf On 2026/8/17 上午11:59, Tiezhu Yang wrote: > When testing the BPF selftest "sudo ./test_progs -t timer_lockup", there > is a kernel lockup and panic: ... > With this patch, the lockless "store-before-load" ordering is enforced by > the DBAR instruction. The BPF timer_lockup selftest was stressed for 5000 > consecutive loops on a physical LoongArch machine without encountering any > further lockups or warnings: > > for i in {1..5000}; do sudo ./test_progs -t timer_lockup; done ... > diff --git a/arch/loongarch/include/asm/barrier.h b/arch/loongarch/include/asm/barrier.h > index 4b663f197706..adfe343dfa65 100644 > --- a/arch/loongarch/include/asm/barrier.h > +++ b/arch/loongarch/include/asm/barrier.h > @@ -57,8 +57,8 @@ > #define __WEAK_LLSC_MB " \n" > #endif > > -#define __smp_mb__before_atomic() barrier() > -#define __smp_mb__after_atomic() barrier() > +#define __smp_mb__before_atomic() __smp_mb() > +#define __smp_mb__after_atomic() __smp_mb() > > /** > * array_index_mask_nospec() - generate a ~0 mask when index < size, 0 otherwise Hi all, To address the soft lockup while avoiding the performance overhead of executing two separate instructions, I think there is a more elegant way to fix this directly in the BPF core helper: We can replace atomic_inc() and smp_mb__after_atomic() with a single atomic_fetch_add() in bpf_timer_cancel(). This consolidates the logic into a single native atomic operation with full ordering, which not only guarantees the store-load order to eliminate the deadlock but also improves the performance for weak memory model architectures. Any thoughts on this approach? ``` diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c index c18f1e16edee..ee2b3a4dcc05 100644 --- a/kernel/bpf/helpers.c +++ b/kernel/bpf/helpers.c @@ -1591,9 +1591,7 @@ BPF_CALL_1(bpf_timer_cancel, struct bpf_async_kern *, async) */ if (!cur_t) goto drop; - atomic_inc(&t->cancelling); - /* Need full barrier after relaxed atomic_inc */ - smp_mb__after_atomic(); + atomic_fetch_add(1, &t->cancelling); inc = true; if (atomic_read(&cur_t->cancelling)) { /* We're cancelling timer t, while some other timer callback is ``` I tested the above diff, the BPF timer_lockup selftest was stressed for 5000 consecutive loops on a physical LoongArch machine without encountering any further lockups or warnings. If you are OK with this change of bpf code, I will send a bpf patch later. Thanks, Tiezhu ^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH v1] LoongArch: Fix __smp_mb__{before,after}_atomic() 2026-08-18 13:28 ` [PATCH v1] LoongArch: Fix __smp_mb__{before,after}_atomic() Tiezhu Yang @ 2026-08-18 13:35 ` Kumar Kartikeya Dwivedi 2026-08-18 13:50 ` Tiezhu Yang 0 siblings, 1 reply; 4+ messages in thread From: Kumar Kartikeya Dwivedi @ 2026-08-18 13:35 UTC (permalink / raw) To: Tiezhu Yang, Huacai Chen; +Cc: loongarch, linux-kernel, Vincent Li, bpf On Tue Aug 18, 2026 at 3:28 PM CEST, Tiezhu Yang wrote: > On 2026/8/17 上午11:59, Tiezhu Yang wrote: >> When testing the BPF selftest "sudo ./test_progs -t timer_lockup", there >> is a kernel lockup and panic: > > ... > >> With this patch, the lockless "store-before-load" ordering is enforced by >> the DBAR instruction. The BPF timer_lockup selftest was stressed for 5000 >> consecutive loops on a physical LoongArch machine without encountering any >> further lockups or warnings: >> >> for i in {1..5000}; do sudo ./test_progs -t timer_lockup; done > > ... > >> diff --git a/arch/loongarch/include/asm/barrier.h b/arch/loongarch/include/asm/barrier.h >> index 4b663f197706..adfe343dfa65 100644 >> --- a/arch/loongarch/include/asm/barrier.h >> +++ b/arch/loongarch/include/asm/barrier.h >> @@ -57,8 +57,8 @@ >> #define __WEAK_LLSC_MB " \n" >> #endif >> >> -#define __smp_mb__before_atomic() barrier() >> -#define __smp_mb__after_atomic() barrier() >> +#define __smp_mb__before_atomic() __smp_mb() >> +#define __smp_mb__after_atomic() __smp_mb() >> >> /** >> * array_index_mask_nospec() - generate a ~0 mask when index < size, 0 otherwise > > Hi all, > > To address the soft lockup while avoiding the performance overhead of > executing two separate instructions, I think there is a more elegant > way to fix this directly in the BPF core helper: > > We can replace atomic_inc() and smp_mb__after_atomic() with a single > atomic_fetch_add() in bpf_timer_cancel(). This consolidates the logic > into a single native atomic operation with full ordering, which not > only guarantees the store-load order to eliminate the deadlock but > also improves the performance for weak memory model architectures. > > Any thoughts on this approach? > > ``` > diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c > index c18f1e16edee..ee2b3a4dcc05 100644 > --- a/kernel/bpf/helpers.c > +++ b/kernel/bpf/helpers.c > @@ -1591,9 +1591,7 @@ BPF_CALL_1(bpf_timer_cancel, struct bpf_async_kern > *, async) > */ > if (!cur_t) > goto drop; > - atomic_inc(&t->cancelling); > - /* Need full barrier after relaxed atomic_inc */ > - smp_mb__after_atomic(); > + atomic_fetch_add(1, &t->cancelling); > inc = true; > if (atomic_read(&cur_t->cancelling)) { > /* We're cancelling timer t, while some other timer > callback is > ``` > > I tested the above diff, the BPF timer_lockup selftest was stressed > for 5000 consecutive loops on a physical LoongArch machine without > encountering any further lockups or warnings. There is a full barrier in both cases. I don't know what performance improvement will be achieved by changing this. Don't you need to fix the lowering for smp_mb__after_atomic() anyway? It's used in several other places in the kernel. > > If you are OK with this change of bpf code, I will send a bpf patch > later. > > Thanks, > Tiezhu ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH v1] LoongArch: Fix __smp_mb__{before,after}_atomic() 2026-08-18 13:35 ` Kumar Kartikeya Dwivedi @ 2026-08-18 13:50 ` Tiezhu Yang 2026-08-18 14:05 ` Kumar Kartikeya Dwivedi 0 siblings, 1 reply; 4+ messages in thread From: Tiezhu Yang @ 2026-08-18 13:50 UTC (permalink / raw) To: Kumar Kartikeya Dwivedi, Huacai Chen Cc: loongarch, linux-kernel, Vincent Li, bpf On 2026/8/18 下午9:35, Kumar Kartikeya Dwivedi wrote: > On Tue Aug 18, 2026 at 3:28 PM CEST, Tiezhu Yang wrote: >> On 2026/8/17 上午11:59, Tiezhu Yang wrote: >>> When testing the BPF selftest "sudo ./test_progs -t timer_lockup", there >>> is a kernel lockup and panic: >> >> ... >> >>> With this patch, the lockless "store-before-load" ordering is enforced by >>> the DBAR instruction. The BPF timer_lockup selftest was stressed for 5000 >>> consecutive loops on a physical LoongArch machine without encountering any >>> further lockups or warnings: >>> >>> for i in {1..5000}; do sudo ./test_progs -t timer_lockup; done >> >> ... >> >>> diff --git a/arch/loongarch/include/asm/barrier.h b/arch/loongarch/include/asm/barrier.h >>> index 4b663f197706..adfe343dfa65 100644 >>> --- a/arch/loongarch/include/asm/barrier.h >>> +++ b/arch/loongarch/include/asm/barrier.h >>> @@ -57,8 +57,8 @@ >>> #define __WEAK_LLSC_MB " \n" >>> #endif >>> >>> -#define __smp_mb__before_atomic() barrier() >>> -#define __smp_mb__after_atomic() barrier() >>> +#define __smp_mb__before_atomic() __smp_mb() >>> +#define __smp_mb__after_atomic() __smp_mb() >>> >>> /** >>> * array_index_mask_nospec() - generate a ~0 mask when index < size, 0 otherwise >> >> Hi all, >> >> To address the soft lockup while avoiding the performance overhead of >> executing two separate instructions, I think there is a more elegant >> way to fix this directly in the BPF core helper: >> >> We can replace atomic_inc() and smp_mb__after_atomic() with a single >> atomic_fetch_add() in bpf_timer_cancel(). This consolidates the logic >> into a single native atomic operation with full ordering, which not >> only guarantees the store-load order to eliminate the deadlock but >> also improves the performance for weak memory model architectures. >> >> Any thoughts on this approach? >> >> ``` >> diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c >> index c18f1e16edee..ee2b3a4dcc05 100644 >> --- a/kernel/bpf/helpers.c >> +++ b/kernel/bpf/helpers.c >> @@ -1591,9 +1591,7 @@ BPF_CALL_1(bpf_timer_cancel, struct bpf_async_kern >> *, async) >> */ >> if (!cur_t) >> goto drop; >> - atomic_inc(&t->cancelling); >> - /* Need full barrier after relaxed atomic_inc */ >> - smp_mb__after_atomic(); >> + atomic_fetch_add(1, &t->cancelling); >> inc = true; >> if (atomic_read(&cur_t->cancelling)) { >> /* We're cancelling timer t, while some other timer >> callback is >> ``` >> >> I tested the above diff, the BPF timer_lockup selftest was stressed >> for 5000 consecutive loops on a physical LoongArch machine without >> encountering any further lockups or warnings. > > There is a full barrier in both cases. I don't know what performance improvement > will be achieved by changing this. We performed benchmarking using UnixBench on a physical LoongArch machine, the UnixBench score is different (amadd.w + dbar < amadd_db.w). > Don't you need to fix the lowering for > smp_mb__after_atomic() anyway? It's used in several other places in the kernel. The LoongArch architecture-level fix for smp_mb__after_atomic() is a fundamental bug fix that will be pushed separately to the LoongArch tree. This BPF-layer change is intended as a generic, cross-architecture performance optimization. Thanks, Tiezhu ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH v1] LoongArch: Fix __smp_mb__{before,after}_atomic() 2026-08-18 13:50 ` Tiezhu Yang @ 2026-08-18 14:05 ` Kumar Kartikeya Dwivedi 0 siblings, 0 replies; 4+ messages in thread From: Kumar Kartikeya Dwivedi @ 2026-08-18 14:05 UTC (permalink / raw) To: Tiezhu Yang, Huacai Chen; +Cc: loongarch, linux-kernel, Vincent Li, bpf On Tue Aug 18, 2026 at 3:50 PM CEST, Tiezhu Yang wrote: > On 2026/8/18 下午9:35, Kumar Kartikeya Dwivedi wrote: >> On Tue Aug 18, 2026 at 3:28 PM CEST, Tiezhu Yang wrote: >>> On 2026/8/17 上午11:59, Tiezhu Yang wrote: >>>> When testing the BPF selftest "sudo ./test_progs -t timer_lockup", there >>>> is a kernel lockup and panic: >>> >>> ... >>> >>>> With this patch, the lockless "store-before-load" ordering is enforced by >>>> the DBAR instruction. The BPF timer_lockup selftest was stressed for 5000 >>>> consecutive loops on a physical LoongArch machine without encountering any >>>> further lockups or warnings: >>>> >>>> for i in {1..5000}; do sudo ./test_progs -t timer_lockup; done >>> >>> ... >>> >>>> diff --git a/arch/loongarch/include/asm/barrier.h b/arch/loongarch/include/asm/barrier.h >>>> index 4b663f197706..adfe343dfa65 100644 >>>> --- a/arch/loongarch/include/asm/barrier.h >>>> +++ b/arch/loongarch/include/asm/barrier.h >>>> @@ -57,8 +57,8 @@ >>>> #define __WEAK_LLSC_MB " \n" >>>> #endif >>>> >>>> -#define __smp_mb__before_atomic() barrier() >>>> -#define __smp_mb__after_atomic() barrier() >>>> +#define __smp_mb__before_atomic() __smp_mb() >>>> +#define __smp_mb__after_atomic() __smp_mb() >>>> >>>> /** >>>> * array_index_mask_nospec() - generate a ~0 mask when index < size, 0 otherwise >>> >>> Hi all, >>> >>> To address the soft lockup while avoiding the performance overhead of >>> executing two separate instructions, I think there is a more elegant >>> way to fix this directly in the BPF core helper: >>> >>> We can replace atomic_inc() and smp_mb__after_atomic() with a single >>> atomic_fetch_add() in bpf_timer_cancel(). This consolidates the logic >>> into a single native atomic operation with full ordering, which not >>> only guarantees the store-load order to eliminate the deadlock but >>> also improves the performance for weak memory model architectures. >>> >>> Any thoughts on this approach? >>> >>> ``` >>> diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c >>> index c18f1e16edee..ee2b3a4dcc05 100644 >>> --- a/kernel/bpf/helpers.c >>> +++ b/kernel/bpf/helpers.c >>> @@ -1591,9 +1591,7 @@ BPF_CALL_1(bpf_timer_cancel, struct bpf_async_kern >>> *, async) >>> */ >>> if (!cur_t) >>> goto drop; >>> - atomic_inc(&t->cancelling); >>> - /* Need full barrier after relaxed atomic_inc */ >>> - smp_mb__after_atomic(); >>> + atomic_fetch_add(1, &t->cancelling); >>> inc = true; >>> if (atomic_read(&cur_t->cancelling)) { >>> /* We're cancelling timer t, while some other timer >>> callback is >>> ``` >>> >>> I tested the above diff, the BPF timer_lockup selftest was stressed >>> for 5000 consecutive loops on a physical LoongArch machine without >>> encountering any further lockups or warnings. >> >> There is a full barrier in both cases. I don't know what performance improvement >> will be achieved by changing this. > > We performed benchmarking using UnixBench on a physical LoongArch > machine, the UnixBench score is different (amadd.w + dbar < amadd_db.w). > I mean, this function is already quite heavy. We have multiple fully ordered atomics (refcount bumps/drops, xchg(), etc.) spread across the operation. Do you observe any measurable speedup in the throughput of this function? The second question is whether timer cancellation is really frequent. In practice, I don't think that is the case. The actual hrtimer_cancel() in itself is heavy and waits synchronously for the callback to finish. I'm not opposed to it or anything, I just don't think it's worth it in this case. If the latency of cancel is a problem there are other bigger opportunities to pursue than this. >> Don't you need to fix the lowering for >> smp_mb__after_atomic() anyway? It's used in several other places in the kernel. > > The LoongArch architecture-level fix for smp_mb__after_atomic() is > a fundamental bug fix that will be pushed separately to the LoongArch > tree. This BPF-layer change is intended as a generic, cross-architecture > performance optimization. > > Thanks, > Tiezhu ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-08-18 14:05 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20260817035908.460-1-yangtiezhu@loongson.cn>
2026-08-18 13:28 ` [PATCH v1] LoongArch: Fix __smp_mb__{before,after}_atomic() Tiezhu Yang
2026-08-18 13:35 ` Kumar Kartikeya Dwivedi
2026-08-18 13:50 ` Tiezhu Yang
2026-08-18 14:05 ` Kumar Kartikeya Dwivedi
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox