1
2#ifndef __LINUX_SMP_H
3#define __LINUX_SMP_H
4
5
6
7
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/smp_types.h>
16
17typedef void (*smp_call_func_t)(void *info);
18typedef bool (*smp_cond_func_t)(int cpu, void *info);
19
20
21
22
23struct __call_single_data {
24 struct __call_single_node node;
25 smp_call_func_t func;
26 void *info;
27};
28
29#define CSD_INIT(_func, _info) \
30 (struct __call_single_data){ .func = (_func), .info = (_info), }
31
32
33typedef struct __call_single_data call_single_data_t
34 __aligned(sizeof(struct __call_single_data));
35
36#define INIT_CSD(_csd, _func, _info) \
37do { \
38 *(_csd) = CSD_INIT((_func), (_info)); \
39} while (0)
40
41
42
43
44
45extern void __smp_call_single_queue(int cpu, struct llist_node *node);
46
47
48extern unsigned int total_cpus;
49
50int smp_call_function_single(int cpuid, smp_call_func_t func, void *info,
51 int wait);
52
53void on_each_cpu_cond_mask(smp_cond_func_t cond_func, smp_call_func_t func,
54 void *info, bool wait, const struct cpumask *mask);
55
56int smp_call_function_single_async(int cpu, struct __call_single_data *csd);
57
58
59
60
61
62void panic_smp_self_stop(void);
63void nmi_panic_self_stop(struct pt_regs *regs);
64void crash_smp_send_stop(void);
65
66
67
68
69static inline void on_each_cpu(smp_call_func_t func, void *info, int wait)
70{
71 on_each_cpu_cond_mask(NULL, func, info, wait, cpu_online_mask);
72}
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90static inline void on_each_cpu_mask(const struct cpumask *mask,
91 smp_call_func_t func, void *info, bool wait)
92{
93 on_each_cpu_cond_mask(NULL, func, info, wait, mask);
94}
95
96
97
98
99
100
101
102static inline void on_each_cpu_cond(smp_cond_func_t cond_func,
103 smp_call_func_t func, void *info, bool wait)
104{
105 on_each_cpu_cond_mask(cond_func, func, info, wait, cpu_online_mask);
106}
107
108#ifdef CONFIG_SMP
109
110#include <linux/preempt.h>
111#include <linux/compiler.h>
112#include <linux/thread_info.h>
113#include <asm/smp.h>
114
115
116
117
118
119
120
121
122
123extern void smp_send_stop(void);
124
125
126
127
128extern void smp_send_reschedule(int cpu);
129
130
131
132
133
134extern void smp_prepare_cpus(unsigned int max_cpus);
135
136
137
138
139extern int __cpu_up(unsigned int cpunum, struct task_struct *tidle);
140
141
142
143
144extern void smp_cpus_done(unsigned int max_cpus);
145
146
147
148
149void smp_call_function(smp_call_func_t func, void *info, int wait);
150void smp_call_function_many(const struct cpumask *mask,
151 smp_call_func_t func, void *info, bool wait);
152
153int smp_call_function_any(const struct cpumask *mask,
154 smp_call_func_t func, void *info, int wait);
155
156void kick_all_cpus_sync(void);
157void wake_up_all_idle_cpus(void);
158
159
160
161
162void __init call_function_init(void);
163void generic_smp_call_function_single_interrupt(void);
164#define generic_smp_call_function_interrupt \
165 generic_smp_call_function_single_interrupt
166
167
168
169
170
171void smp_prepare_boot_cpu(void);
172
173extern unsigned int setup_max_cpus;
174extern void __init setup_nr_cpu_ids(void);
175extern void __init smp_init(void);
176
177extern int __boot_cpu_id;
178
179static inline int get_boot_cpu_id(void)
180{
181 return __boot_cpu_id;
182}
183
184#else
185
186static inline void smp_send_stop(void) { }
187
188
189
190
191#define raw_smp_processor_id() 0
192static inline void up_smp_call_function(smp_call_func_t func, void *info)
193{
194}
195#define smp_call_function(func, info, wait) \
196 (up_smp_call_function(func, info))
197
198static inline void smp_send_reschedule(int cpu) { }
199#define smp_prepare_boot_cpu() do {} while (0)
200#define smp_call_function_many(mask, func, info, wait) \
201 (up_smp_call_function(func, info))
202static inline void call_function_init(void) { }
203
204static inline int
205smp_call_function_any(const struct cpumask *mask, smp_call_func_t func,
206 void *info, int wait)
207{
208 return smp_call_function_single(0, func, info, wait);
209}
210
211static inline void kick_all_cpus_sync(void) { }
212static inline void wake_up_all_idle_cpus(void) { }
213
214#ifdef CONFIG_UP_LATE_INIT
215extern void __init up_late_init(void);
216static inline void smp_init(void) { up_late_init(); }
217#else
218static inline void smp_init(void) { }
219#endif
220
221static inline int get_boot_cpu_id(void)
222{
223 return 0;
224}
225
226#endif
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256#ifndef __smp_processor_id
257#define __smp_processor_id(x) raw_smp_processor_id(x)
258#endif
259
260#ifdef CONFIG_DEBUG_PREEMPT
261 extern unsigned int debug_smp_processor_id(void);
262# define smp_processor_id() debug_smp_processor_id()
263#else
264# define smp_processor_id() __smp_processor_id()
265#endif
266
267#define get_cpu() ({ preempt_disable(); __smp_processor_id(); })
268#define put_cpu() preempt_enable()
269
270
271
272
273
274extern void arch_disable_smp_support(void);
275
276extern void arch_thaw_secondary_cpus_begin(void);
277extern void arch_thaw_secondary_cpus_end(void);
278
279void smp_setup_processor_id(void);
280
281int smp_call_on_cpu(unsigned int cpu, int (*func)(void *), void *par,
282 bool phys);
283
284
285int smpcfd_prepare_cpu(unsigned int cpu);
286int smpcfd_dead_cpu(unsigned int cpu);
287int smpcfd_dying_cpu(unsigned int cpu);
288
289#endif
290