diff options
author | Jens Axboe <jens.axboe@oracle.com> | 2008-06-26 05:21:34 -0400 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2008-06-26 05:21:34 -0400 |
commit | 3d4422332711ef48ef0f132f1fcbfcbd56c7f3d1 (patch) | |
tree | 9fd3cfa9825e8cb0b7e08dfae85cc9a722442849 /include/linux | |
parent | 543cf4cb3fe6f6cae3651ba918b9c56200b257d0 (diff) |
Add generic helpers for arch IPI function calls
This adds kernel/smp.c which contains helpers for IPI function calls. In
addition to supporting the existing smp_call_function() in a more efficient
manner, it also adds a more scalable variant called smp_call_function_single()
for calling a given function on a single CPU only.
The core of this is based on the x86-64 patch from Nick Piggin, lots of
changes since then. "Alan D. Brunelle" <Alan.Brunelle@hp.com> has
contributed lots of fixes and suggestions as well. Also thanks to
Paul E. McKenney <paulmck@linux.vnet.ibm.com> for reviewing RCU usage
and getting rid of the data allocation fallback deadlock.
Acked-by: Ingo Molnar <mingo@elte.hu>
Reviewed-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'include/linux')
-rw-r--r-- | include/linux/smp.h | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/include/linux/smp.h b/include/linux/smp.h index 55232ccf9cfd..eac3e062250f 100644 --- a/include/linux/smp.h +++ b/include/linux/smp.h | |||
@@ -7,9 +7,19 @@ | |||
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/errno.h> | 9 | #include <linux/errno.h> |
10 | #include <linux/list.h> | ||
11 | #include <linux/spinlock.h> | ||
12 | #include <linux/cpumask.h> | ||
10 | 13 | ||
11 | extern void cpu_idle(void); | 14 | extern void cpu_idle(void); |
12 | 15 | ||
16 | struct call_single_data { | ||
17 | struct list_head list; | ||
18 | void (*func) (void *info); | ||
19 | void *info; | ||
20 | unsigned int flags; | ||
21 | }; | ||
22 | |||
13 | #ifdef CONFIG_SMP | 23 | #ifdef CONFIG_SMP |
14 | 24 | ||
15 | #include <linux/preempt.h> | 25 | #include <linux/preempt.h> |
@@ -53,9 +63,28 @@ extern void smp_cpus_done(unsigned int max_cpus); | |||
53 | * Call a function on all other processors | 63 | * Call a function on all other processors |
54 | */ | 64 | */ |
55 | int smp_call_function(void(*func)(void *info), void *info, int retry, int wait); | 65 | int smp_call_function(void(*func)(void *info), void *info, int retry, int wait); |
56 | 66 | int smp_call_function_mask(cpumask_t mask, void(*func)(void *info), void *info, | |
67 | int wait); | ||
57 | int smp_call_function_single(int cpuid, void (*func) (void *info), void *info, | 68 | int smp_call_function_single(int cpuid, void (*func) (void *info), void *info, |
58 | int retry, int wait); | 69 | int retry, int wait); |
70 | void __smp_call_function_single(int cpuid, struct call_single_data *data); | ||
71 | |||
72 | /* | ||
73 | * Generic and arch helpers | ||
74 | */ | ||
75 | #ifdef CONFIG_USE_GENERIC_SMP_HELPERS | ||
76 | void generic_smp_call_function_single_interrupt(void); | ||
77 | void generic_smp_call_function_interrupt(void); | ||
78 | void init_call_single_data(void); | ||
79 | void ipi_call_lock(void); | ||
80 | void ipi_call_unlock(void); | ||
81 | void ipi_call_lock_irq(void); | ||
82 | void ipi_call_unlock_irq(void); | ||
83 | #else | ||
84 | static inline void init_call_single_data(void) | ||
85 | { | ||
86 | } | ||
87 | #endif | ||
59 | 88 | ||
60 | /* | 89 | /* |
61 | * Call a function on all processors | 90 | * Call a function on all processors |
@@ -112,7 +141,9 @@ static inline void smp_send_reschedule(int cpu) { } | |||
112 | }) | 141 | }) |
113 | #define smp_call_function_mask(mask, func, info, wait) \ | 142 | #define smp_call_function_mask(mask, func, info, wait) \ |
114 | (up_smp_call_function(func, info)) | 143 | (up_smp_call_function(func, info)) |
115 | 144 | static inline void init_call_single_data(void) | |
145 | { | ||
146 | } | ||
116 | #endif /* !SMP */ | 147 | #endif /* !SMP */ |
117 | 148 | ||
118 | /* | 149 | /* |