diff options
Diffstat (limited to 'arch/mips/kernel/smp.c')
-rw-r--r-- | arch/mips/kernel/smp.c | 51 |
1 files changed, 27 insertions, 24 deletions
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index af5cd3b8a396..fcacf1aae98a 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c | |||
@@ -50,7 +50,6 @@ static void smp_tune_scheduling (void) | |||
50 | { | 50 | { |
51 | struct cache_desc *cd = ¤t_cpu_data.scache; | 51 | struct cache_desc *cd = ¤t_cpu_data.scache; |
52 | unsigned long cachesize; /* kB */ | 52 | unsigned long cachesize; /* kB */ |
53 | unsigned long bandwidth = 350; /* MB/s */ | ||
54 | unsigned long cpu_khz; | 53 | unsigned long cpu_khz; |
55 | 54 | ||
56 | /* | 55 | /* |
@@ -121,7 +120,19 @@ struct call_data_struct *call_data; | |||
121 | * or are or have executed. | 120 | * or are or have executed. |
122 | * | 121 | * |
123 | * You must not call this function with disabled interrupts or from a | 122 | * You must not call this function with disabled interrupts or from a |
124 | * hardware interrupt handler or from a bottom half handler. | 123 | * hardware interrupt handler or from a bottom half handler: |
124 | * | ||
125 | * CPU A CPU B | ||
126 | * Disable interrupts | ||
127 | * smp_call_function() | ||
128 | * Take call_lock | ||
129 | * Send IPIs | ||
130 | * Wait for all cpus to acknowledge IPI | ||
131 | * CPU A has not responded, spin waiting | ||
132 | * for cpu A to respond, holding call_lock | ||
133 | * smp_call_function() | ||
134 | * Spin waiting for call_lock | ||
135 | * Deadlock Deadlock | ||
125 | */ | 136 | */ |
126 | int smp_call_function (void (*func) (void *info), void *info, int retry, | 137 | int smp_call_function (void (*func) (void *info), void *info, int retry, |
127 | int wait) | 138 | int wait) |
@@ -130,6 +141,11 @@ int smp_call_function (void (*func) (void *info), void *info, int retry, | |||
130 | int i, cpus = num_online_cpus() - 1; | 141 | int i, cpus = num_online_cpus() - 1; |
131 | int cpu = smp_processor_id(); | 142 | int cpu = smp_processor_id(); |
132 | 143 | ||
144 | /* | ||
145 | * Can die spectacularly if this CPU isn't yet marked online | ||
146 | */ | ||
147 | BUG_ON(!cpu_online(cpu)); | ||
148 | |||
133 | if (!cpus) | 149 | if (!cpus) |
134 | return 0; | 150 | return 0; |
135 | 151 | ||
@@ -214,7 +230,6 @@ void __init smp_cpus_done(unsigned int max_cpus) | |||
214 | /* called from main before smp_init() */ | 230 | /* called from main before smp_init() */ |
215 | void __init smp_prepare_cpus(unsigned int max_cpus) | 231 | void __init smp_prepare_cpus(unsigned int max_cpus) |
216 | { | 232 | { |
217 | cpu_data[0].udelay_val = loops_per_jiffy; | ||
218 | init_new_context(current, &init_mm); | 233 | init_new_context(current, &init_mm); |
219 | current_thread_info()->cpu = 0; | 234 | current_thread_info()->cpu = 0; |
220 | smp_tune_scheduling(); | 235 | smp_tune_scheduling(); |
@@ -236,23 +251,28 @@ void __devinit smp_prepare_boot_cpu(void) | |||
236 | } | 251 | } |
237 | 252 | ||
238 | /* | 253 | /* |
239 | * Startup the CPU with this logical number | 254 | * Called once for each "cpu_possible(cpu)". Needs to spin up the cpu |
255 | * and keep control until "cpu_online(cpu)" is set. Note: cpu is | ||
256 | * physical, not logical. | ||
240 | */ | 257 | */ |
241 | static int __init do_boot_cpu(int cpu) | 258 | int __devinit __cpu_up(unsigned int cpu) |
242 | { | 259 | { |
243 | struct task_struct *idle; | 260 | struct task_struct *idle; |
244 | 261 | ||
245 | /* | 262 | /* |
263 | * Processor goes to start_secondary(), sets online flag | ||
246 | * The following code is purely to make sure | 264 | * The following code is purely to make sure |
247 | * Linux can schedule processes on this slave. | 265 | * Linux can schedule processes on this slave. |
248 | */ | 266 | */ |
249 | idle = fork_idle(cpu); | 267 | idle = fork_idle(cpu); |
250 | if (IS_ERR(idle)) | 268 | if (IS_ERR(idle)) |
251 | panic("failed fork for CPU %d\n", cpu); | 269 | panic(KERN_ERR "Fork failed for CPU %d", cpu); |
252 | 270 | ||
253 | prom_boot_secondary(cpu, idle); | 271 | prom_boot_secondary(cpu, idle); |
254 | 272 | ||
255 | /* XXXKW timeout */ | 273 | /* |
274 | * Trust is futile. We should really have timeouts ... | ||
275 | */ | ||
256 | while (!cpu_isset(cpu, cpu_callin_map)) | 276 | while (!cpu_isset(cpu, cpu_callin_map)) |
257 | udelay(100); | 277 | udelay(100); |
258 | 278 | ||
@@ -261,23 +281,6 @@ static int __init do_boot_cpu(int cpu) | |||
261 | return 0; | 281 | return 0; |
262 | } | 282 | } |
263 | 283 | ||
264 | /* | ||
265 | * Called once for each "cpu_possible(cpu)". Needs to spin up the cpu | ||
266 | * and keep control until "cpu_online(cpu)" is set. Note: cpu is | ||
267 | * physical, not logical. | ||
268 | */ | ||
269 | int __devinit __cpu_up(unsigned int cpu) | ||
270 | { | ||
271 | int ret; | ||
272 | |||
273 | /* Processor goes to start_secondary(), sets online flag */ | ||
274 | ret = do_boot_cpu(cpu); | ||
275 | if (ret < 0) | ||
276 | return ret; | ||
277 | |||
278 | return 0; | ||
279 | } | ||
280 | |||
281 | /* Not really SMP stuff ... */ | 284 | /* Not really SMP stuff ... */ |
282 | int setup_profiling_timer(unsigned int multiplier) | 285 | int setup_profiling_timer(unsigned int multiplier) |
283 | { | 286 | { |