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 | { |
