1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | #ifndef __LINUX_SMP_TYPES_H |
3 | #define __LINUX_SMP_TYPES_H |
4 | |
5 | #include <linux/llist.h> |
6 | |
7 | enum { |
8 | CSD_FLAG_LOCK = 0x01, |
9 | |
10 | IRQ_WORK_PENDING = 0x01, |
11 | IRQ_WORK_BUSY = 0x02, |
12 | IRQ_WORK_LAZY = 0x04, /* No IPI, wait for tick */ |
13 | IRQ_WORK_HARD_IRQ = 0x08, /* IRQ context on PREEMPT_RT */ |
14 | |
15 | IRQ_WORK_CLAIMED = (IRQ_WORK_PENDING | IRQ_WORK_BUSY), |
16 | |
17 | CSD_TYPE_ASYNC = 0x00, |
18 | CSD_TYPE_SYNC = 0x10, |
19 | CSD_TYPE_IRQ_WORK = 0x20, |
20 | CSD_TYPE_TTWU = 0x30, |
21 | |
22 | CSD_FLAG_TYPE_MASK = 0xF0, |
23 | }; |
24 | |
25 | /* |
26 | * struct __call_single_node is the primary type on |
27 | * smp.c:call_single_queue. |
28 | * |
29 | * flush_smp_call_function_queue() only reads the type from |
30 | * __call_single_node::u_flags as a regular load, the above |
31 | * (anonymous) enum defines all the bits of this word. |
32 | * |
33 | * Other bits are not modified until the type is known. |
34 | * |
35 | * CSD_TYPE_SYNC/ASYNC: |
36 | * struct { |
37 | * struct llist_node node; |
38 | * unsigned int flags; |
39 | * smp_call_func_t func; |
40 | * void *info; |
41 | * }; |
42 | * |
43 | * CSD_TYPE_IRQ_WORK: |
44 | * struct { |
45 | * struct llist_node node; |
46 | * atomic_t flags; |
47 | * void (*func)(struct irq_work *); |
48 | * }; |
49 | * |
50 | * CSD_TYPE_TTWU: |
51 | * struct { |
52 | * struct llist_node node; |
53 | * unsigned int flags; |
54 | * }; |
55 | * |
56 | */ |
57 | |
58 | struct __call_single_node { |
59 | struct llist_node llist; |
60 | union { |
61 | unsigned int u_flags; |
62 | atomic_t a_flags; |
63 | }; |
64 | #ifdef CONFIG_64BIT |
65 | u16 src, dst; |
66 | #endif |
67 | }; |
68 | |
69 | #endif /* __LINUX_SMP_TYPES_H */ |
70 | |