Branch data Line data Source code
1 : : /* SPDX-License-Identifier: GPL-2.0 */
2 : : #ifndef __LINUX_SMP_H
3 : : #define __LINUX_SMP_H
4 : :
5 : : /*
6 : : * Generic SMP support
7 : : * Alan Cox. <alan@redhat.com>
8 : : */
9 : :
10 : : #include <linux/errno.h>
11 : : #include <linux/types.h>
12 : : #include <linux/list.h>
13 : : #include <linux/cpumask.h>
14 : : #include <linux/init.h>
15 : : #include <linux/llist.h>
16 : :
17 : : typedef void (*smp_call_func_t)(void *info);
18 : : typedef bool (*smp_cond_func_t)(int cpu, void *info);
19 : : struct __call_single_data {
20 : : struct llist_node llist;
21 : : smp_call_func_t func;
22 : : void *info;
23 : : unsigned int flags;
24 : : };
25 : :
26 : : /* Use __aligned() to avoid to use 2 cache lines for 1 csd */
27 : : typedef struct __call_single_data call_single_data_t
28 : : __aligned(sizeof(struct __call_single_data));
29 : :
30 : : /* total number of cpus in this system (may exceed NR_CPUS) */
31 : : extern unsigned int total_cpus;
32 : :
33 : : int smp_call_function_single(int cpuid, smp_call_func_t func, void *info,
34 : : int wait);
35 : :
36 : : /*
37 : : * Call a function on all processors
38 : : */
39 : : void on_each_cpu(smp_call_func_t func, void *info, int wait);
40 : :
41 : : /*
42 : : * Call a function on processors specified by mask, which might include
43 : : * the local one.
44 : : */
45 : : void on_each_cpu_mask(const struct cpumask *mask, smp_call_func_t func,
46 : : void *info, bool wait);
47 : :
48 : : /*
49 : : * Call a function on each processor for which the supplied function
50 : : * cond_func returns a positive value. This may include the local
51 : : * processor.
52 : : */
53 : : void on_each_cpu_cond(smp_cond_func_t cond_func, smp_call_func_t func,
54 : : void *info, bool wait);
55 : :
56 : : void on_each_cpu_cond_mask(smp_cond_func_t cond_func, smp_call_func_t func,
57 : : void *info, bool wait, const struct cpumask *mask);
58 : :
59 : : int smp_call_function_single_async(int cpu, call_single_data_t *csd);
60 : :
61 : : #ifdef CONFIG_SMP
62 : :
63 : : #include <linux/preempt.h>
64 : : #include <linux/kernel.h>
65 : : #include <linux/compiler.h>
66 : : #include <linux/thread_info.h>
67 : : #include <asm/smp.h>
68 : :
69 : : /*
70 : : * main cross-CPU interfaces, handles INIT, TLB flush, STOP, etc.
71 : : * (defined in asm header):
72 : : */
73 : :
74 : : /*
75 : : * stops all CPUs but the current one:
76 : : */
77 : : extern void smp_send_stop(void);
78 : :
79 : : /*
80 : : * sends a 'reschedule' event to another CPU:
81 : : */
82 : : extern void smp_send_reschedule(int cpu);
83 : :
84 : :
85 : : /*
86 : : * Prepare machine for booting other CPUs.
87 : : */
88 : : extern void smp_prepare_cpus(unsigned int max_cpus);
89 : :
90 : : /*
91 : : * Bring a CPU up
92 : : */
93 : : extern int __cpu_up(unsigned int cpunum, struct task_struct *tidle);
94 : :
95 : : /*
96 : : * Final polishing of CPUs
97 : : */
98 : : extern void smp_cpus_done(unsigned int max_cpus);
99 : :
100 : : /*
101 : : * Call a function on all other processors
102 : : */
103 : : void smp_call_function(smp_call_func_t func, void *info, int wait);
104 : : void smp_call_function_many(const struct cpumask *mask,
105 : : smp_call_func_t func, void *info, bool wait);
106 : :
107 : : int smp_call_function_any(const struct cpumask *mask,
108 : : smp_call_func_t func, void *info, int wait);
109 : :
110 : : void kick_all_cpus_sync(void);
111 : : void wake_up_all_idle_cpus(void);
112 : :
113 : : /*
114 : : * Generic and arch helpers
115 : : */
116 : : void __init call_function_init(void);
117 : : void generic_smp_call_function_single_interrupt(void);
118 : : #define generic_smp_call_function_interrupt \
119 : : generic_smp_call_function_single_interrupt
120 : :
121 : : /*
122 : : * Mark the boot cpu "online" so that it can call console drivers in
123 : : * printk() and can access its per-cpu storage.
124 : : */
125 : : void smp_prepare_boot_cpu(void);
126 : :
127 : : extern unsigned int setup_max_cpus;
128 : : extern void __init setup_nr_cpu_ids(void);
129 : : extern void __init smp_init(void);
130 : :
131 : : extern int __boot_cpu_id;
132 : :
133 : 0 : static inline int get_boot_cpu_id(void)
134 : : {
135 : 0 : return __boot_cpu_id;
136 : : }
137 : :
138 : : #else /* !SMP */
139 : :
140 : : static inline void smp_send_stop(void) { }
141 : :
142 : : /*
143 : : * These macros fold the SMP functionality into a single CPU system
144 : : */
145 : : #define raw_smp_processor_id() 0
146 : : static inline void up_smp_call_function(smp_call_func_t func, void *info)
147 : : {
148 : : }
149 : : #define smp_call_function(func, info, wait) \
150 : : (up_smp_call_function(func, info))
151 : :
152 : : static inline void smp_send_reschedule(int cpu) { }
153 : : #define smp_prepare_boot_cpu() do {} while (0)
154 : : #define smp_call_function_many(mask, func, info, wait) \
155 : : (up_smp_call_function(func, info))
156 : : static inline void call_function_init(void) { }
157 : :
158 : : static inline int
159 : : smp_call_function_any(const struct cpumask *mask, smp_call_func_t func,
160 : : void *info, int wait)
161 : : {
162 : : return smp_call_function_single(0, func, info, wait);
163 : : }
164 : :
165 : : static inline void kick_all_cpus_sync(void) { }
166 : : static inline void wake_up_all_idle_cpus(void) { }
167 : :
168 : : #ifdef CONFIG_UP_LATE_INIT
169 : : extern void __init up_late_init(void);
170 : : static inline void smp_init(void) { up_late_init(); }
171 : : #else
172 : : static inline void smp_init(void) { }
173 : : #endif
174 : :
175 : : static inline int get_boot_cpu_id(void)
176 : : {
177 : : return 0;
178 : : }
179 : :
180 : : #endif /* !SMP */
181 : :
182 : : /**
183 : : * raw_processor_id() - get the current (unstable) CPU id
184 : : *
185 : : * For then you know what you are doing and need an unstable
186 : : * CPU id.
187 : : */
188 : :
189 : : /**
190 : : * smp_processor_id() - get the current (stable) CPU id
191 : : *
192 : : * This is the normal accessor to the CPU id and should be used
193 : : * whenever possible.
194 : : *
195 : : * The CPU id is stable when:
196 : : *
197 : : * - IRQs are disabled;
198 : : * - preemption is disabled;
199 : : * - the task is CPU affine.
200 : : *
201 : : * When CONFIG_DEBUG_PREEMPT; we verify these assumption and WARN
202 : : * when smp_processor_id() is used when the CPU id is not stable.
203 : : */
204 : :
205 : : /*
206 : : * Allow the architecture to differentiate between a stable and unstable read.
207 : : * For example, x86 uses an IRQ-safe asm-volatile read for the unstable but a
208 : : * regular asm read for the stable.
209 : : */
210 : : #ifndef __smp_processor_id
211 : : #define __smp_processor_id(x) raw_smp_processor_id(x)
212 : : #endif
213 : :
214 : : #ifdef CONFIG_DEBUG_PREEMPT
215 : : extern unsigned int debug_smp_processor_id(void);
216 : : # define smp_processor_id() debug_smp_processor_id()
217 : : #else
218 : : # define smp_processor_id() __smp_processor_id()
219 : : #endif
220 : :
221 : : #define get_cpu() ({ preempt_disable(); __smp_processor_id(); })
222 : : #define put_cpu() preempt_enable()
223 : :
224 : : /*
225 : : * Callback to arch code if there's nosmp or maxcpus=0 on the
226 : : * boot command line:
227 : : */
228 : : extern void arch_disable_smp_support(void);
229 : :
230 : : extern void arch_enable_nonboot_cpus_begin(void);
231 : : extern void arch_enable_nonboot_cpus_end(void);
232 : :
233 : : void smp_setup_processor_id(void);
234 : :
235 : : int smp_call_on_cpu(unsigned int cpu, int (*func)(void *), void *par,
236 : : bool phys);
237 : :
238 : : /* SMP core functions */
239 : : int smpcfd_prepare_cpu(unsigned int cpu);
240 : : int smpcfd_dead_cpu(unsigned int cpu);
241 : : int smpcfd_dying_cpu(unsigned int cpu);
242 : :
243 : : #endif /* __LINUX_SMP_H */
|