/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_RQSPINLOCK_H
#define _ASM_RQSPINLOCK_H
#include <asm /barrier.h>
/*
* Hardcode res_smp_cond_load_acquire implementations for arm64 to a custom
* version based on [ 0 ] . In rqspinlock code , our conditional expression involves
* checking the value _ and_ additionally a timeout . However , on arm64 , the
* WFE - based implementation may never spin again if no stores occur to the
* locked byte in the lock word . As such , we may be stuck forever if
* event - stream based unblocking is not available on the platform for WFE spin
* loops ( arch_timer_evtstrm_available ) .
*
* Once support for smp_cond_load_acquire_timewait [ 0 ] lands , we can drop this
* copy - paste .
*
* While we rely on the implementation to amortize the cost of sampling
* cond_expr for us , it will not happen when event stream support is
* unavailable , time_expr check is amortized . This is not the common case , and
* it would be difficult to fit our logic in the time_expr_ns > = time_limit_ns
* comparison , hence just let it be . In case of event - stream , the loop is woken
* up at microsecond granularity .
*
* [ 0 ] : https : //lore.kernel.org/lkml/20250203214911.898276-1-ankur.a.arora@oracle.com
*/
#ifndef smp_cond_load_acquire_timewait
#define smp_cond_time_check_count 200
#define __smp_cond_load_relaxed_spinwait(ptr, cond_expr, time_expr_ns, \
time_limit_ns) ({ \
typeof(ptr) __PTR = (ptr); \
__unqual_scalar_typeof(*ptr) VAL; \
unsigned int __count = 0 ; \
for (;;) { \
VAL = READ_ONCE(*__PTR); \
if (cond_expr) \
break ; \
cpu_relax(); \
if (__count++ < smp_cond_time_check_count) \
continue ; \
if ((time_expr_ns) >= (time_limit_ns)) \
break ; \
__count = 0 ; \
} \
(typeof(*ptr))VAL; \
})
#define __smp_cond_load_acquire_timewait(ptr, cond_expr, \
time_expr_ns, time_limit_ns) \
({ \
typeof(ptr) __PTR = (ptr); \
__unqual_scalar_typeof(*ptr) VAL; \
for (;;) { \
VAL = smp_load_acquire(__PTR); \
if (cond_expr) \
break ; \
__cmpwait_relaxed(__PTR, VAL); \
if ((time_expr_ns) >= (time_limit_ns)) \
break ; \
} \
(typeof(*ptr))VAL; \
})
#define smp_cond_load_acquire_timewait(ptr, cond_expr, \
time_expr_ns, time_limit_ns) \
({ \
__unqual_scalar_typeof(*ptr) _val; \
int __wfe = arch_timer_evtstrm_available(); \
\
if (likely(__wfe)) { \
_val = __smp_cond_load_acquire_timewait(ptr, cond_expr, \
time_expr_ns, \
time_limit_ns); \
} else { \
_val = __smp_cond_load_relaxed_spinwait(ptr, cond_expr, \
time_expr_ns, \
time_limit_ns); \
smp_acquire__after_ctrl_dep(); \
} \
(typeof(*ptr))_val; \
})
#endif
#define res_smp_cond_load_acquire(v, c) smp_cond_load_acquire_timewait(v, c, 0 , 1 )
#include <asm -generic/rqspinlock.h>
#endif /* _ASM_RQSPINLOCK_H */
Messung V0.5 in Prozent C=96 H=58 G=79
¤ Dauer der Verarbeitung: 0.9 Sekunden
(vorverarbeitet am 2026-09-29)
¤
*© Formatika GbR, Deutschland