xref: /linux-6.15/include/linux/processor.h (revision 79282605)
1*b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
2fd851a3cSNicholas Piggin /* Misc low level processor primitives */
3fd851a3cSNicholas Piggin #ifndef _LINUX_PROCESSOR_H
4fd851a3cSNicholas Piggin #define _LINUX_PROCESSOR_H
5fd851a3cSNicholas Piggin 
6fd851a3cSNicholas Piggin #include <asm/processor.h>
7fd851a3cSNicholas Piggin 
8fd851a3cSNicholas Piggin /*
9fd851a3cSNicholas Piggin  * spin_begin is used before beginning a busy-wait loop, and must be paired
10fd851a3cSNicholas Piggin  * with spin_end when the loop is exited. spin_cpu_relax must be called
11fd851a3cSNicholas Piggin  * within the loop.
12fd851a3cSNicholas Piggin  *
13fd851a3cSNicholas Piggin  * The loop body should be as small and fast as possible, on the order of
14fd851a3cSNicholas Piggin  * tens of instructions/cycles as a guide. It should and avoid calling
15fd851a3cSNicholas Piggin  * cpu_relax, or any "spin" or sleep type of primitive including nested uses
16fd851a3cSNicholas Piggin  * of these primitives. It should not lock or take any other resource.
17fd851a3cSNicholas Piggin  * Violations of these guidelies will not cause a bug, but may cause sub
18fd851a3cSNicholas Piggin  * optimal performance.
19fd851a3cSNicholas Piggin  *
20fd851a3cSNicholas Piggin  * These loops are optimized to be used where wait times are expected to be
21fd851a3cSNicholas Piggin  * less than the cost of a context switch (and associated overhead).
22fd851a3cSNicholas Piggin  *
23fd851a3cSNicholas Piggin  * Detection of resource owner and decision to spin or sleep or guest-yield
24fd851a3cSNicholas Piggin  * (e.g., spin lock holder vcpu preempted, or mutex owner not on CPU) can be
25fd851a3cSNicholas Piggin  * tested within the loop body.
26fd851a3cSNicholas Piggin  */
27fd851a3cSNicholas Piggin #ifndef spin_begin
28fd851a3cSNicholas Piggin #define spin_begin()
29fd851a3cSNicholas Piggin #endif
30fd851a3cSNicholas Piggin 
31fd851a3cSNicholas Piggin #ifndef spin_cpu_relax
32fd851a3cSNicholas Piggin #define spin_cpu_relax() cpu_relax()
33fd851a3cSNicholas Piggin #endif
34fd851a3cSNicholas Piggin 
35fd851a3cSNicholas Piggin #ifndef spin_end
36fd851a3cSNicholas Piggin #define spin_end()
37fd851a3cSNicholas Piggin #endif
38fd851a3cSNicholas Piggin 
39fd851a3cSNicholas Piggin /*
40fd851a3cSNicholas Piggin  * spin_until_cond can be used to wait for a condition to become true. It
41fd851a3cSNicholas Piggin  * may be expected that the first iteration will true in the common case
42fd851a3cSNicholas Piggin  * (no spinning), so that callers should not require a first "likely" test
43fd851a3cSNicholas Piggin  * for the uncontended case before using this primitive.
44fd851a3cSNicholas Piggin  *
45fd851a3cSNicholas Piggin  * Usage and implementation guidelines are the same as for the spin_begin
46fd851a3cSNicholas Piggin  * primitives, above.
47fd851a3cSNicholas Piggin  */
48fd851a3cSNicholas Piggin #ifndef spin_until_cond
49fd851a3cSNicholas Piggin #define spin_until_cond(cond)					\
50fd851a3cSNicholas Piggin do {								\
51fd851a3cSNicholas Piggin 	if (unlikely(!(cond))) {				\
52fd851a3cSNicholas Piggin 		spin_begin();					\
53fd851a3cSNicholas Piggin 		do {						\
54fd851a3cSNicholas Piggin 			spin_cpu_relax();			\
55fd851a3cSNicholas Piggin 		} while (!(cond));				\
56fd851a3cSNicholas Piggin 		spin_end();					\
57fd851a3cSNicholas Piggin 	}							\
58fd851a3cSNicholas Piggin } while (0)
59fd851a3cSNicholas Piggin 
60fd851a3cSNicholas Piggin #endif
61fd851a3cSNicholas Piggin 
62fd851a3cSNicholas Piggin #endif /* _LINUX_PROCESSOR_H */
63