diff options
Diffstat (limited to 'arch/ia64')
-rw-r--r-- | arch/ia64/kernel/smp.c | 68 |
1 files changed, 35 insertions, 33 deletions
diff --git a/arch/ia64/kernel/smp.c b/arch/ia64/kernel/smp.c index 9a9d4c489330..983296f1c813 100644 --- a/arch/ia64/kernel/smp.c +++ b/arch/ia64/kernel/smp.c | |||
@@ -98,8 +98,33 @@ unlock_ipi_calllock(void) | |||
98 | spin_unlock_irq(&call_lock); | 98 | spin_unlock_irq(&call_lock); |
99 | } | 99 | } |
100 | 100 | ||
101 | static inline void | ||
102 | handle_call_data(void) | ||
103 | { | ||
104 | struct call_data_struct *data; | ||
105 | void (*func)(void *info); | ||
106 | void *info; | ||
107 | int wait; | ||
108 | |||
109 | /* release the 'pointer lock' */ | ||
110 | data = (struct call_data_struct *)call_data; | ||
111 | func = data->func; | ||
112 | info = data->info; | ||
113 | wait = data->wait; | ||
114 | |||
115 | mb(); | ||
116 | atomic_inc(&data->started); | ||
117 | /* At this point the structure may be gone unless wait is true. */ | ||
118 | (*func)(info); | ||
119 | |||
120 | /* Notify the sending CPU that the task is done. */ | ||
121 | mb(); | ||
122 | if (wait) | ||
123 | atomic_inc(&data->finished); | ||
124 | } | ||
125 | |||
101 | static void | 126 | static void |
102 | stop_this_cpu (void) | 127 | stop_this_cpu(void) |
103 | { | 128 | { |
104 | /* | 129 | /* |
105 | * Remove this CPU: | 130 | * Remove this CPU: |
@@ -138,44 +163,21 @@ handle_IPI (int irq, void *dev_id) | |||
138 | ops &= ~(1 << which); | 163 | ops &= ~(1 << which); |
139 | 164 | ||
140 | switch (which) { | 165 | switch (which) { |
141 | case IPI_CALL_FUNC: | 166 | case IPI_CALL_FUNC: |
142 | { | 167 | handle_call_data(); |
143 | struct call_data_struct *data; | 168 | break; |
144 | void (*func)(void *info); | 169 | |
145 | void *info; | 170 | case IPI_CPU_STOP: |
146 | int wait; | ||
147 | |||
148 | /* release the 'pointer lock' */ | ||
149 | data = (struct call_data_struct *) call_data; | ||
150 | func = data->func; | ||
151 | info = data->info; | ||
152 | wait = data->wait; | ||
153 | |||
154 | mb(); | ||
155 | atomic_inc(&data->started); | ||
156 | /* | ||
157 | * At this point the structure may be gone unless | ||
158 | * wait is true. | ||
159 | */ | ||
160 | (*func)(info); | ||
161 | |||
162 | /* Notify the sending CPU that the task is done. */ | ||
163 | mb(); | ||
164 | if (wait) | ||
165 | atomic_inc(&data->finished); | ||
166 | } | ||
167 | break; | ||
168 | |||
169 | case IPI_CPU_STOP: | ||
170 | stop_this_cpu(); | 171 | stop_this_cpu(); |
171 | break; | 172 | break; |
172 | #ifdef CONFIG_KEXEC | 173 | #ifdef CONFIG_KEXEC |
173 | case IPI_KDUMP_CPU_STOP: | 174 | case IPI_KDUMP_CPU_STOP: |
174 | unw_init_running(kdump_cpu_freeze, NULL); | 175 | unw_init_running(kdump_cpu_freeze, NULL); |
175 | break; | 176 | break; |
176 | #endif | 177 | #endif |
177 | default: | 178 | default: |
178 | printk(KERN_CRIT "Unknown IPI on CPU %d: %lu\n", this_cpu, which); | 179 | printk(KERN_CRIT "Unknown IPI on CPU %d: %lu\n", |
180 | this_cpu, which); | ||
179 | break; | 181 | break; |
180 | } | 182 | } |
181 | } while (ops); | 183 | } while (ops); |