Skip to content

Commit 7b65f7f

Browse files
terminusKernel Patches Daemon
authored andcommitted
rqspinlock: use smp_cond_load_acquire_timewait()
Use smp_cond_load_acquire_timewait() to define res_atomic_cond_read_acquire() and res_smp_cond_load_acquire_timewait(). The timeout check for both is done via RES_CHECK_TIMEOUT(). Define res_smp_cond_load_acquire_waiting() to allow it to amortize the check for spin-wait implementations. Cc: Kumar Kartikeya Dwivedi <[email protected]> Cc: Alexei Starovoitov <[email protected]> Signed-off-by: Ankur Arora <[email protected]>
1 parent 5b8f00d commit 7b65f7f

File tree

3 files changed

+16
-16
lines changed

3 files changed

+16
-16
lines changed

arch/arm64/include/asm/rqspinlock.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
#define _ASM_RQSPINLOCK_H
44

55
#include <asm/barrier.h>
6+
7+
#define res_smp_cond_load_acquire_waiting() arch_timer_evtstrm_available()
8+
69
#include <asm-generic/rqspinlock.h>
710

811
#endif /* _ASM_RQSPINLOCK_H */

include/asm-generic/rqspinlock.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,4 +247,8 @@ static __always_inline void res_spin_unlock(rqspinlock_t *lock)
247247

248248
#define raw_res_spin_unlock_irqrestore(lock, flags) ({ raw_res_spin_unlock(lock); local_irq_restore(flags); })
249249

250+
#ifndef res_smp_cond_load_acquire_waiting
251+
#define res_smp_cond_load_acquire_waiting() 0
252+
#endif
253+
250254
#endif /* __ASM_GENERIC_RQSPINLOCK_H */

kernel/bpf/rqspinlock.c

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ struct rqspinlock_timeout {
8282
u64 duration;
8383
u64 cur;
8484
u16 spin;
85+
u8 wait;
8586
};
8687

8788
#define RES_TIMEOUT_VAL 2
@@ -241,26 +242,20 @@ static noinline int check_timeout(rqspinlock_t *lock, u32 mask,
241242
}
242243

243244
/*
244-
* Do not amortize with spins when res_smp_cond_load_acquire is defined,
245-
* as the macro does internal amortization for us.
245+
* Only amortize with spins when we don't have a waiting implementation.
246246
*/
247-
#ifndef res_smp_cond_load_acquire
248247
#define RES_CHECK_TIMEOUT(ts, ret, mask) \
249248
({ \
250-
if (!(ts).spin++) \
249+
if ((ts).wait || !(ts).spin++) \
251250
(ret) = check_timeout((lock), (mask), &(ts)); \
252251
(ret); \
253252
})
254-
#else
255-
#define RES_CHECK_TIMEOUT(ts, ret, mask) \
256-
({ (ret) = check_timeout((lock), (mask), &(ts)); })
257-
#endif
258253

259254
/*
260255
* Initialize the 'spin' member.
261256
* Set spin member to 0 to trigger AA/ABBA checks immediately.
262257
*/
263-
#define RES_INIT_TIMEOUT(ts) ({ (ts).spin = 0; })
258+
#define RES_INIT_TIMEOUT(ts) ({ (ts).spin = 0; (ts).wait = res_smp_cond_load_acquire_waiting(); })
264259

265260
/*
266261
* We only need to reset 'timeout_end', 'spin' will just wrap around as necessary.
@@ -313,11 +308,8 @@ EXPORT_SYMBOL_GPL(resilient_tas_spin_lock);
313308
*/
314309
static DEFINE_PER_CPU_ALIGNED(struct qnode, rqnodes[_Q_MAX_NODES]);
315310

316-
#ifndef res_smp_cond_load_acquire
317-
#define res_smp_cond_load_acquire(v, c) smp_cond_load_acquire(v, c)
318-
#endif
319-
320-
#define res_atomic_cond_read_acquire(v, c) res_smp_cond_load_acquire(&(v)->counter, (c))
311+
#define res_atomic_cond_read_acquire(v, c, t) smp_cond_load_acquire_timewait(&(v)->counter, (c), (t))
312+
#define res_smp_cond_load_acquire_timewait(v, c, t) smp_cond_load_acquire_timewait(v, (c), (t))
321313

322314
/**
323315
* resilient_queued_spin_lock_slowpath - acquire the queued spinlock
@@ -418,7 +410,8 @@ int __lockfunc resilient_queued_spin_lock_slowpath(rqspinlock_t *lock, u32 val)
418410
*/
419411
if (val & _Q_LOCKED_MASK) {
420412
RES_RESET_TIMEOUT(ts, RES_DEF_TIMEOUT);
421-
res_smp_cond_load_acquire(&lock->locked, !VAL || RES_CHECK_TIMEOUT(ts, ret, _Q_LOCKED_MASK));
413+
res_smp_cond_load_acquire_timewait(&lock->locked, !VAL,
414+
RES_CHECK_TIMEOUT(ts, ret, _Q_LOCKED_MASK));
422415
}
423416

424417
if (ret) {
@@ -572,7 +565,7 @@ int __lockfunc resilient_queued_spin_lock_slowpath(rqspinlock_t *lock, u32 val)
572565
* us.
573566
*/
574567
RES_RESET_TIMEOUT(ts, RES_DEF_TIMEOUT * 2);
575-
val = res_atomic_cond_read_acquire(&lock->val, !(VAL & _Q_LOCKED_PENDING_MASK) ||
568+
val = res_atomic_cond_read_acquire(&lock->val, !(VAL & _Q_LOCKED_PENDING_MASK),
576569
RES_CHECK_TIMEOUT(ts, ret, _Q_LOCKED_PENDING_MASK));
577570

578571
waitq_timeout:

0 commit comments

Comments
 (0)