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