diff options
Diffstat (limited to 'arch/s390/kernel/smp.c')
-rw-r--r-- | arch/s390/kernel/smp.c | 54 |
1 files changed, 24 insertions, 30 deletions
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index b39f596d71bd..d8a0b115c7c1 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c | |||
@@ -53,7 +53,7 @@ | |||
53 | #include "entry.h" | 53 | #include "entry.h" |
54 | 54 | ||
55 | /* logical cpu to cpu address */ | 55 | /* logical cpu to cpu address */ |
56 | int __cpu_logical_map[NR_CPUS]; | 56 | unsigned short __cpu_logical_map[NR_CPUS]; |
57 | 57 | ||
58 | static struct task_struct *current_set[NR_CPUS]; | 58 | static struct task_struct *current_set[NR_CPUS]; |
59 | 59 | ||
@@ -72,13 +72,13 @@ static int cpu_management; | |||
72 | 72 | ||
73 | static DEFINE_PER_CPU(struct cpu, cpu_devices); | 73 | static DEFINE_PER_CPU(struct cpu, cpu_devices); |
74 | 74 | ||
75 | static void smp_ext_bitcall(int, ec_bit_sig); | 75 | static void smp_ext_bitcall(int, int); |
76 | 76 | ||
77 | static int cpu_stopped(int cpu) | 77 | static int raw_cpu_stopped(int cpu) |
78 | { | 78 | { |
79 | __u32 status; | 79 | u32 status; |
80 | 80 | ||
81 | switch (signal_processor_ps(&status, 0, cpu, sigp_sense)) { | 81 | switch (raw_sigp_ps(&status, 0, cpu, sigp_sense)) { |
82 | case sigp_status_stored: | 82 | case sigp_status_stored: |
83 | /* Check for stopped and check stop state */ | 83 | /* Check for stopped and check stop state */ |
84 | if (status & 0x50) | 84 | if (status & 0x50) |
@@ -90,6 +90,11 @@ static int cpu_stopped(int cpu) | |||
90 | return 0; | 90 | return 0; |
91 | } | 91 | } |
92 | 92 | ||
93 | static inline int cpu_stopped(int cpu) | ||
94 | { | ||
95 | return raw_cpu_stopped(cpu_logical_map(cpu)); | ||
96 | } | ||
97 | |||
93 | void smp_switch_to_ipl_cpu(void (*func)(void *), void *data) | 98 | void smp_switch_to_ipl_cpu(void (*func)(void *), void *data) |
94 | { | 99 | { |
95 | struct _lowcore *lc, *current_lc; | 100 | struct _lowcore *lc, *current_lc; |
@@ -110,7 +115,7 @@ void smp_switch_to_ipl_cpu(void (*func)(void *), void *data) | |||
110 | lc->restart_psw.addr = PSW_ADDR_AMODE | (unsigned long) smp_restart_cpu; | 115 | lc->restart_psw.addr = PSW_ADDR_AMODE | (unsigned long) smp_restart_cpu; |
111 | if (!cpu_online(0)) | 116 | if (!cpu_online(0)) |
112 | smp_switch_to_cpu(func, data, 0, stap(), __cpu_logical_map[0]); | 117 | smp_switch_to_cpu(func, data, 0, stap(), __cpu_logical_map[0]); |
113 | while (signal_processor(0, sigp_stop_and_store_status) == sigp_busy) | 118 | while (sigp(0, sigp_stop_and_store_status) == sigp_busy) |
114 | cpu_relax(); | 119 | cpu_relax(); |
115 | sp = lc->panic_stack; | 120 | sp = lc->panic_stack; |
116 | sp -= sizeof(struct pt_regs); | 121 | sp -= sizeof(struct pt_regs); |
@@ -136,7 +141,7 @@ void smp_send_stop(void) | |||
136 | if (cpu == smp_processor_id()) | 141 | if (cpu == smp_processor_id()) |
137 | continue; | 142 | continue; |
138 | do { | 143 | do { |
139 | rc = signal_processor(cpu, sigp_stop); | 144 | rc = sigp(cpu, sigp_stop); |
140 | } while (rc == sigp_busy); | 145 | } while (rc == sigp_busy); |
141 | 146 | ||
142 | while (!cpu_stopped(cpu)) | 147 | while (!cpu_stopped(cpu)) |
@@ -172,13 +177,13 @@ static void do_ext_call_interrupt(__u16 code) | |||
172 | * Send an external call sigp to another cpu and return without waiting | 177 | * Send an external call sigp to another cpu and return without waiting |
173 | * for its completion. | 178 | * for its completion. |
174 | */ | 179 | */ |
175 | static void smp_ext_bitcall(int cpu, ec_bit_sig sig) | 180 | static void smp_ext_bitcall(int cpu, int sig) |
176 | { | 181 | { |
177 | /* | 182 | /* |
178 | * Set signaling bit in lowcore of target cpu and kick it | 183 | * Set signaling bit in lowcore of target cpu and kick it |
179 | */ | 184 | */ |
180 | set_bit(sig, (unsigned long *) &lowcore_ptr[cpu]->ext_call_fast); | 185 | set_bit(sig, (unsigned long *) &lowcore_ptr[cpu]->ext_call_fast); |
181 | while (signal_processor(cpu, sigp_emergency_signal) == sigp_busy) | 186 | while (sigp(cpu, sigp_emergency_signal) == sigp_busy) |
182 | udelay(10); | 187 | udelay(10); |
183 | } | 188 | } |
184 | 189 | ||
@@ -272,13 +277,6 @@ void smp_ctl_clear_bit(int cr, int bit) | |||
272 | } | 277 | } |
273 | EXPORT_SYMBOL(smp_ctl_clear_bit); | 278 | EXPORT_SYMBOL(smp_ctl_clear_bit); |
274 | 279 | ||
275 | /* | ||
276 | * In early ipl state a temp. logically cpu number is needed, so the sigp | ||
277 | * functions can be used to sense other cpus. Since NR_CPUS is >= 2 on | ||
278 | * CONFIG_SMP and the ipl cpu is logical cpu 0, it must be 1. | ||
279 | */ | ||
280 | #define CPU_INIT_NO 1 | ||
281 | |||
282 | #ifdef CONFIG_ZFCPDUMP | 280 | #ifdef CONFIG_ZFCPDUMP |
283 | 281 | ||
284 | static void __init smp_get_save_area(unsigned int cpu, unsigned int phy_cpu) | 282 | static void __init smp_get_save_area(unsigned int cpu, unsigned int phy_cpu) |
@@ -291,9 +289,7 @@ static void __init smp_get_save_area(unsigned int cpu, unsigned int phy_cpu) | |||
291 | return; | 289 | return; |
292 | } | 290 | } |
293 | zfcpdump_save_areas[cpu] = kmalloc(sizeof(struct save_area), GFP_KERNEL); | 291 | zfcpdump_save_areas[cpu] = kmalloc(sizeof(struct save_area), GFP_KERNEL); |
294 | __cpu_logical_map[CPU_INIT_NO] = (__u16) phy_cpu; | 292 | while (raw_sigp(phy_cpu, sigp_stop_and_store_status) == sigp_busy) |
295 | while (signal_processor(CPU_INIT_NO, sigp_stop_and_store_status) == | ||
296 | sigp_busy) | ||
297 | cpu_relax(); | 293 | cpu_relax(); |
298 | memcpy(zfcpdump_save_areas[cpu], | 294 | memcpy(zfcpdump_save_areas[cpu], |
299 | (void *)(unsigned long) store_prefix() + SAVE_AREA_BASE, | 295 | (void *)(unsigned long) store_prefix() + SAVE_AREA_BASE, |
@@ -409,8 +405,7 @@ static void __init smp_detect_cpus(void) | |||
409 | for (cpu = 0; cpu <= MAX_CPU_ADDRESS; cpu++) { | 405 | for (cpu = 0; cpu <= MAX_CPU_ADDRESS; cpu++) { |
410 | if (cpu == boot_cpu_addr) | 406 | if (cpu == boot_cpu_addr) |
411 | continue; | 407 | continue; |
412 | __cpu_logical_map[CPU_INIT_NO] = cpu; | 408 | if (!raw_cpu_stopped(cpu)) |
413 | if (!cpu_stopped(CPU_INIT_NO)) | ||
414 | continue; | 409 | continue; |
415 | smp_get_save_area(c_cpus, cpu); | 410 | smp_get_save_area(c_cpus, cpu); |
416 | c_cpus++; | 411 | c_cpus++; |
@@ -433,8 +428,7 @@ static void __init smp_detect_cpus(void) | |||
433 | cpu_addr = info->cpu[cpu].address; | 428 | cpu_addr = info->cpu[cpu].address; |
434 | if (cpu_addr == boot_cpu_addr) | 429 | if (cpu_addr == boot_cpu_addr) |
435 | continue; | 430 | continue; |
436 | __cpu_logical_map[CPU_INIT_NO] = cpu_addr; | 431 | if (!raw_cpu_stopped(cpu_addr)) { |
437 | if (!cpu_stopped(CPU_INIT_NO)) { | ||
438 | s_cpus++; | 432 | s_cpus++; |
439 | continue; | 433 | continue; |
440 | } | 434 | } |
@@ -553,18 +547,18 @@ static void smp_free_lowcore(int cpu) | |||
553 | /* Upping and downing of CPUs */ | 547 | /* Upping and downing of CPUs */ |
554 | int __cpuinit __cpu_up(unsigned int cpu) | 548 | int __cpuinit __cpu_up(unsigned int cpu) |
555 | { | 549 | { |
556 | struct task_struct *idle; | ||
557 | struct _lowcore *cpu_lowcore; | 550 | struct _lowcore *cpu_lowcore; |
551 | struct task_struct *idle; | ||
558 | struct stack_frame *sf; | 552 | struct stack_frame *sf; |
559 | sigp_ccode ccode; | ||
560 | u32 lowcore; | 553 | u32 lowcore; |
554 | int ccode; | ||
561 | 555 | ||
562 | if (smp_cpu_state[cpu] != CPU_STATE_CONFIGURED) | 556 | if (smp_cpu_state[cpu] != CPU_STATE_CONFIGURED) |
563 | return -EIO; | 557 | return -EIO; |
564 | if (smp_alloc_lowcore(cpu)) | 558 | if (smp_alloc_lowcore(cpu)) |
565 | return -ENOMEM; | 559 | return -ENOMEM; |
566 | do { | 560 | do { |
567 | ccode = signal_processor(cpu, sigp_initial_cpu_reset); | 561 | ccode = sigp(cpu, sigp_initial_cpu_reset); |
568 | if (ccode == sigp_busy) | 562 | if (ccode == sigp_busy) |
569 | udelay(10); | 563 | udelay(10); |
570 | if (ccode == sigp_not_operational) | 564 | if (ccode == sigp_not_operational) |
@@ -572,7 +566,7 @@ int __cpuinit __cpu_up(unsigned int cpu) | |||
572 | } while (ccode == sigp_busy); | 566 | } while (ccode == sigp_busy); |
573 | 567 | ||
574 | lowcore = (u32)(unsigned long)lowcore_ptr[cpu]; | 568 | lowcore = (u32)(unsigned long)lowcore_ptr[cpu]; |
575 | while (signal_processor_p(lowcore, cpu, sigp_set_prefix) == sigp_busy) | 569 | while (sigp_p(lowcore, cpu, sigp_set_prefix) == sigp_busy) |
576 | udelay(10); | 570 | udelay(10); |
577 | 571 | ||
578 | idle = current_set[cpu]; | 572 | idle = current_set[cpu]; |
@@ -598,7 +592,7 @@ int __cpuinit __cpu_up(unsigned int cpu) | |||
598 | cpu_lowcore->ftrace_func = S390_lowcore.ftrace_func; | 592 | cpu_lowcore->ftrace_func = S390_lowcore.ftrace_func; |
599 | eieio(); | 593 | eieio(); |
600 | 594 | ||
601 | while (signal_processor(cpu, sigp_restart) == sigp_busy) | 595 | while (sigp(cpu, sigp_restart) == sigp_busy) |
602 | udelay(10); | 596 | udelay(10); |
603 | 597 | ||
604 | while (!cpu_online(cpu)) | 598 | while (!cpu_online(cpu)) |
@@ -660,7 +654,7 @@ void __cpu_die(unsigned int cpu) | |||
660 | /* Wait until target cpu is down */ | 654 | /* Wait until target cpu is down */ |
661 | while (!cpu_stopped(cpu)) | 655 | while (!cpu_stopped(cpu)) |
662 | cpu_relax(); | 656 | cpu_relax(); |
663 | while (signal_processor_p(0, cpu, sigp_set_prefix) == sigp_busy) | 657 | while (sigp_p(0, cpu, sigp_set_prefix) == sigp_busy) |
664 | udelay(10); | 658 | udelay(10); |
665 | smp_free_lowcore(cpu); | 659 | smp_free_lowcore(cpu); |
666 | pr_info("Processor %d stopped\n", cpu); | 660 | pr_info("Processor %d stopped\n", cpu); |
@@ -669,7 +663,7 @@ void __cpu_die(unsigned int cpu) | |||
669 | void cpu_die(void) | 663 | void cpu_die(void) |
670 | { | 664 | { |
671 | idle_task_exit(); | 665 | idle_task_exit(); |
672 | while (signal_processor(smp_processor_id(), sigp_stop) == sigp_busy) | 666 | while (sigp(smp_processor_id(), sigp_stop) == sigp_busy) |
673 | cpu_relax(); | 667 | cpu_relax(); |
674 | for (;;); | 668 | for (;;); |
675 | } | 669 | } |