aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel/smp.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-07-24 12:49:09 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-07-24 12:49:09 -0400
commite017507f37d5cb8b541df165a824958bc333bec3 (patch)
tree87ab0986474486623d9957efda9f3f9ea3b14069 /arch/s390/kernel/smp.c
parent759e2a253aaefbb6da9253d517a5a8fe1801ce0f (diff)
parent27f6b416626a240e1b46f646d2e0c5266f4eac95 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 changes from Martin Schwidefsky: "No new functions, a few changes to make the code more robust, some cleanups and bug fixes." * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: (21 commits) s390/vtimer: rework virtual timer interface s390/dis: Add the servc instruction to the disassembler. s390/comments: unify copyright messages and remove file names s390/lgr: Add init check to lgr_info_log() s390/cpu init: use __get_cpu_var instead of per_cpu s390/idle: reduce size of s390_idle_data structure s390/idle: fix sequence handling vs cpu hotplug s390/ap: resend enable adapter interrupt request. s390/hypfs: Add missing get_next_ino() s390/dasd: add shutdown action s390/ipl: Fix ipib handling for "dumpreipl" shutdown action s390/smp: make absolute lowcore / cpu restart parameter accesses more robust s390/vmlogrdr: cleanup driver attribute usage s390/vmlogrdr: cleanup device attribute usage s390/ccwgroup: remove unused ccwgroup_device member s390/cio/chp: cleanup attribute usage s390/sigp: use sigp order code defines in assembly code s390/smp: use sigp cpu status definitions s390/smp/kvm: unifiy sigp definitions s390/smp: remove redundant check ...
Diffstat (limited to 'arch/s390/kernel/smp.c')
-rw-r--r--arch/s390/kernel/smp.c114
1 files changed, 43 insertions, 71 deletions
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 8dca9c248ac7..720fda1620f2 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * SMP related functions 2 * SMP related functions
3 * 3 *
4 * Copyright IBM Corp. 1999,2012 4 * Copyright IBM Corp. 1999, 2012
5 * Author(s): Denis Joseph Barrow, 5 * Author(s): Denis Joseph Barrow,
6 * Martin Schwidefsky <schwidefsky@de.ibm.com>, 6 * Martin Schwidefsky <schwidefsky@de.ibm.com>,
7 * Heiko Carstens <heiko.carstens@de.ibm.com>, 7 * Heiko Carstens <heiko.carstens@de.ibm.com>,
@@ -38,40 +38,16 @@
38#include <asm/setup.h> 38#include <asm/setup.h>
39#include <asm/irq.h> 39#include <asm/irq.h>
40#include <asm/tlbflush.h> 40#include <asm/tlbflush.h>
41#include <asm/timer.h> 41#include <asm/vtimer.h>
42#include <asm/lowcore.h> 42#include <asm/lowcore.h>
43#include <asm/sclp.h> 43#include <asm/sclp.h>
44#include <asm/vdso.h> 44#include <asm/vdso.h>
45#include <asm/debug.h> 45#include <asm/debug.h>
46#include <asm/os_info.h> 46#include <asm/os_info.h>
47#include <asm/sigp.h>
47#include "entry.h" 48#include "entry.h"
48 49
49enum { 50enum {
50 sigp_sense = 1,
51 sigp_external_call = 2,
52 sigp_emergency_signal = 3,
53 sigp_start = 4,
54 sigp_stop = 5,
55 sigp_restart = 6,
56 sigp_stop_and_store_status = 9,
57 sigp_initial_cpu_reset = 11,
58 sigp_cpu_reset = 12,
59 sigp_set_prefix = 13,
60 sigp_store_status_at_address = 14,
61 sigp_store_extended_status_at_address = 15,
62 sigp_set_architecture = 18,
63 sigp_conditional_emergency_signal = 19,
64 sigp_sense_running = 21,
65};
66
67enum {
68 sigp_order_code_accepted = 0,
69 sigp_status_stored = 1,
70 sigp_busy = 2,
71 sigp_not_operational = 3,
72};
73
74enum {
75 ec_schedule = 0, 51 ec_schedule = 0,
76 ec_call_function, 52 ec_call_function,
77 ec_call_function_single, 53 ec_call_function_single,
@@ -124,7 +100,7 @@ static inline int __pcpu_sigp_relax(u16 addr, u8 order, u32 parm, u32 *status)
124 100
125 while (1) { 101 while (1) {
126 cc = __pcpu_sigp(addr, order, parm, status); 102 cc = __pcpu_sigp(addr, order, parm, status);
127 if (cc != sigp_busy) 103 if (cc != SIGP_CC_BUSY)
128 return cc; 104 return cc;
129 cpu_relax(); 105 cpu_relax();
130 } 106 }
@@ -136,7 +112,7 @@ static int pcpu_sigp_retry(struct pcpu *pcpu, u8 order, u32 parm)
136 112
137 for (retry = 0; ; retry++) { 113 for (retry = 0; ; retry++) {
138 cc = __pcpu_sigp(pcpu->address, order, parm, &pcpu->status); 114 cc = __pcpu_sigp(pcpu->address, order, parm, &pcpu->status);
139 if (cc != sigp_busy) 115 if (cc != SIGP_CC_BUSY)
140 break; 116 break;
141 if (retry >= 3) 117 if (retry >= 3)
142 udelay(10); 118 udelay(10);
@@ -146,20 +122,19 @@ static int pcpu_sigp_retry(struct pcpu *pcpu, u8 order, u32 parm)
146 122
147static inline int pcpu_stopped(struct pcpu *pcpu) 123static inline int pcpu_stopped(struct pcpu *pcpu)
148{ 124{
149 if (__pcpu_sigp(pcpu->address, sigp_sense, 125 if (__pcpu_sigp(pcpu->address, SIGP_SENSE,
150 0, &pcpu->status) != sigp_status_stored) 126 0, &pcpu->status) != SIGP_CC_STATUS_STORED)
151 return 0; 127 return 0;
152 /* Check for stopped and check stop state */ 128 return !!(pcpu->status & (SIGP_STATUS_CHECK_STOP|SIGP_STATUS_STOPPED));
153 return !!(pcpu->status & 0x50);
154} 129}
155 130
156static inline int pcpu_running(struct pcpu *pcpu) 131static inline int pcpu_running(struct pcpu *pcpu)
157{ 132{
158 if (__pcpu_sigp(pcpu->address, sigp_sense_running, 133 if (__pcpu_sigp(pcpu->address, SIGP_SENSE_RUNNING,
159 0, &pcpu->status) != sigp_status_stored) 134 0, &pcpu->status) != SIGP_CC_STATUS_STORED)
160 return 1; 135 return 1;
161 /* Check for running status */ 136 /* Status stored condition code is equivalent to cpu not running. */
162 return !(pcpu->status & 0x400); 137 return 0;
163} 138}
164 139
165/* 140/*
@@ -181,7 +156,7 @@ static void pcpu_ec_call(struct pcpu *pcpu, int ec_bit)
181 156
182 set_bit(ec_bit, &pcpu->ec_mask); 157 set_bit(ec_bit, &pcpu->ec_mask);
183 order = pcpu_running(pcpu) ? 158 order = pcpu_running(pcpu) ?
184 sigp_external_call : sigp_emergency_signal; 159 SIGP_EXTERNAL_CALL : SIGP_EMERGENCY_SIGNAL;
185 pcpu_sigp_retry(pcpu, order, 0); 160 pcpu_sigp_retry(pcpu, order, 0);
186} 161}
187 162
@@ -214,7 +189,7 @@ static int __cpuinit pcpu_alloc_lowcore(struct pcpu *pcpu, int cpu)
214 goto out; 189 goto out;
215#endif 190#endif
216 lowcore_ptr[cpu] = lc; 191 lowcore_ptr[cpu] = lc;
217 pcpu_sigp_retry(pcpu, sigp_set_prefix, (u32)(unsigned long) lc); 192 pcpu_sigp_retry(pcpu, SIGP_SET_PREFIX, (u32)(unsigned long) lc);
218 return 0; 193 return 0;
219out: 194out:
220 if (pcpu != &pcpu_devices[0]) { 195 if (pcpu != &pcpu_devices[0]) {
@@ -229,7 +204,7 @@ out:
229 204
230static void pcpu_free_lowcore(struct pcpu *pcpu) 205static void pcpu_free_lowcore(struct pcpu *pcpu)
231{ 206{
232 pcpu_sigp_retry(pcpu, sigp_set_prefix, 0); 207 pcpu_sigp_retry(pcpu, SIGP_SET_PREFIX, 0);
233 lowcore_ptr[pcpu - pcpu_devices] = NULL; 208 lowcore_ptr[pcpu - pcpu_devices] = NULL;
234#ifndef CONFIG_64BIT 209#ifndef CONFIG_64BIT
235 if (MACHINE_HAS_IEEE) { 210 if (MACHINE_HAS_IEEE) {
@@ -288,7 +263,7 @@ static void pcpu_start_fn(struct pcpu *pcpu, void (*func)(void *), void *data)
288 lc->restart_fn = (unsigned long) func; 263 lc->restart_fn = (unsigned long) func;
289 lc->restart_data = (unsigned long) data; 264 lc->restart_data = (unsigned long) data;
290 lc->restart_source = -1UL; 265 lc->restart_source = -1UL;
291 pcpu_sigp_retry(pcpu, sigp_restart, 0); 266 pcpu_sigp_retry(pcpu, SIGP_RESTART, 0);
292} 267}
293 268
294/* 269/*
@@ -298,26 +273,26 @@ static void pcpu_delegate(struct pcpu *pcpu, void (*func)(void *),
298 void *data, unsigned long stack) 273 void *data, unsigned long stack)
299{ 274{
300 struct _lowcore *lc = lowcore_ptr[pcpu - pcpu_devices]; 275 struct _lowcore *lc = lowcore_ptr[pcpu - pcpu_devices];
301 struct { 276 unsigned long source_cpu = stap();
302 unsigned long stack;
303 void *func;
304 void *data;
305 unsigned long source;
306 } restart = { stack, func, data, stap() };
307 277
308 __load_psw_mask(psw_kernel_bits); 278 __load_psw_mask(psw_kernel_bits);
309 if (pcpu->address == restart.source) 279 if (pcpu->address == source_cpu)
310 func(data); /* should not return */ 280 func(data); /* should not return */
311 /* Stop target cpu (if func returns this stops the current cpu). */ 281 /* Stop target cpu (if func returns this stops the current cpu). */
312 pcpu_sigp_retry(pcpu, sigp_stop, 0); 282 pcpu_sigp_retry(pcpu, SIGP_STOP, 0);
313 /* Restart func on the target cpu and stop the current cpu. */ 283 /* Restart func on the target cpu and stop the current cpu. */
314 memcpy_absolute(&lc->restart_stack, &restart, sizeof(restart)); 284 mem_assign_absolute(lc->restart_stack, stack);
285 mem_assign_absolute(lc->restart_fn, (unsigned long) func);
286 mem_assign_absolute(lc->restart_data, (unsigned long) data);
287 mem_assign_absolute(lc->restart_source, source_cpu);
315 asm volatile( 288 asm volatile(
316 "0: sigp 0,%0,6 # sigp restart to target cpu\n" 289 "0: sigp 0,%0,%2 # sigp restart to target cpu\n"
317 " brc 2,0b # busy, try again\n" 290 " brc 2,0b # busy, try again\n"
318 "1: sigp 0,%1,5 # sigp stop to current cpu\n" 291 "1: sigp 0,%1,%3 # sigp stop to current cpu\n"
319 " brc 2,1b # busy, try again\n" 292 " brc 2,1b # busy, try again\n"
320 : : "d" (pcpu->address), "d" (restart.source) : "0", "1", "cc"); 293 : : "d" (pcpu->address), "d" (source_cpu),
294 "K" (SIGP_RESTART), "K" (SIGP_STOP)
295 : "0", "1", "cc");
321 for (;;) ; 296 for (;;) ;
322} 297}
323 298
@@ -388,8 +363,8 @@ void smp_emergency_stop(cpumask_t *cpumask)
388 for_each_cpu(cpu, cpumask) { 363 for_each_cpu(cpu, cpumask) {
389 struct pcpu *pcpu = pcpu_devices + cpu; 364 struct pcpu *pcpu = pcpu_devices + cpu;
390 set_bit(ec_stop_cpu, &pcpu->ec_mask); 365 set_bit(ec_stop_cpu, &pcpu->ec_mask);
391 while (__pcpu_sigp(pcpu->address, sigp_emergency_signal, 366 while (__pcpu_sigp(pcpu->address, SIGP_EMERGENCY_SIGNAL,
392 0, NULL) == sigp_busy && 367 0, NULL) == SIGP_CC_BUSY &&
393 get_clock() < end) 368 get_clock() < end)
394 cpu_relax(); 369 cpu_relax();
395 } 370 }
@@ -425,7 +400,7 @@ void smp_send_stop(void)
425 /* stop all processors */ 400 /* stop all processors */
426 for_each_cpu(cpu, &cpumask) { 401 for_each_cpu(cpu, &cpumask) {
427 struct pcpu *pcpu = pcpu_devices + cpu; 402 struct pcpu *pcpu = pcpu_devices + cpu;
428 pcpu_sigp_retry(pcpu, sigp_stop, 0); 403 pcpu_sigp_retry(pcpu, SIGP_STOP, 0);
429 while (!pcpu_stopped(pcpu)) 404 while (!pcpu_stopped(pcpu))
430 cpu_relax(); 405 cpu_relax();
431 } 406 }
@@ -436,7 +411,7 @@ void smp_send_stop(void)
436 */ 411 */
437void smp_stop_cpu(void) 412void smp_stop_cpu(void)
438{ 413{
439 pcpu_sigp_retry(pcpu_devices + smp_processor_id(), sigp_stop, 0); 414 pcpu_sigp_retry(pcpu_devices + smp_processor_id(), SIGP_STOP, 0);
440 for (;;) ; 415 for (;;) ;
441} 416}
442 417
@@ -590,7 +565,7 @@ static void __init smp_get_save_area(int cpu, u16 address)
590 } 565 }
591#endif 566#endif
592 /* Get the registers of a non-boot cpu. */ 567 /* Get the registers of a non-boot cpu. */
593 __pcpu_sigp_relax(address, sigp_stop_and_store_status, 0, NULL); 568 __pcpu_sigp_relax(address, SIGP_STOP_AND_STORE_STATUS, 0, NULL);
594 memcpy_real(save_area, lc + SAVE_AREA_BASE, sizeof(*save_area)); 569 memcpy_real(save_area, lc + SAVE_AREA_BASE, sizeof(*save_area));
595} 570}
596 571
@@ -599,8 +574,8 @@ int smp_store_status(int cpu)
599 struct pcpu *pcpu; 574 struct pcpu *pcpu;
600 575
601 pcpu = pcpu_devices + cpu; 576 pcpu = pcpu_devices + cpu;
602 if (__pcpu_sigp_relax(pcpu->address, sigp_stop_and_store_status, 577 if (__pcpu_sigp_relax(pcpu->address, SIGP_STOP_AND_STORE_STATUS,
603 0, NULL) != sigp_order_code_accepted) 578 0, NULL) != SIGP_CC_ORDER_CODE_ACCEPTED)
604 return -EIO; 579 return -EIO;
605 return 0; 580 return 0;
606} 581}
@@ -621,8 +596,8 @@ static struct sclp_cpu_info *smp_get_cpu_info(void)
621 if (info && (use_sigp_detection || sclp_get_cpu_info(info))) { 596 if (info && (use_sigp_detection || sclp_get_cpu_info(info))) {
622 use_sigp_detection = 1; 597 use_sigp_detection = 1;
623 for (address = 0; address <= MAX_CPU_ADDRESS; address++) { 598 for (address = 0; address <= MAX_CPU_ADDRESS; address++) {
624 if (__pcpu_sigp_relax(address, sigp_sense, 0, NULL) == 599 if (__pcpu_sigp_relax(address, SIGP_SENSE, 0, NULL) ==
625 sigp_not_operational) 600 SIGP_CC_NOT_OPERATIONAL)
626 continue; 601 continue;
627 info->cpu[info->configured].address = address; 602 info->cpu[info->configured].address = address;
628 info->configured++; 603 info->configured++;
@@ -732,8 +707,8 @@ int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
732 pcpu = pcpu_devices + cpu; 707 pcpu = pcpu_devices + cpu;
733 if (pcpu->state != CPU_STATE_CONFIGURED) 708 if (pcpu->state != CPU_STATE_CONFIGURED)
734 return -EIO; 709 return -EIO;
735 if (pcpu_sigp_retry(pcpu, sigp_initial_cpu_reset, 0) != 710 if (pcpu_sigp_retry(pcpu, SIGP_INITIAL_CPU_RESET, 0) !=
736 sigp_order_code_accepted) 711 SIGP_CC_ORDER_CODE_ACCEPTED)
737 return -EIO; 712 return -EIO;
738 713
739 rc = pcpu_alloc_lowcore(pcpu, cpu); 714 rc = pcpu_alloc_lowcore(pcpu, cpu);
@@ -793,7 +768,7 @@ void __cpu_die(unsigned int cpu)
793void __noreturn cpu_die(void) 768void __noreturn cpu_die(void)
794{ 769{
795 idle_task_exit(); 770 idle_task_exit();
796 pcpu_sigp_retry(pcpu_devices + smp_processor_id(), sigp_stop, 0); 771 pcpu_sigp_retry(pcpu_devices + smp_processor_id(), SIGP_STOP, 0);
797 for (;;) ; 772 for (;;) ;
798} 773}
799 774
@@ -940,7 +915,7 @@ static ssize_t show_idle_count(struct device *dev,
940 do { 915 do {
941 sequence = ACCESS_ONCE(idle->sequence); 916 sequence = ACCESS_ONCE(idle->sequence);
942 idle_count = ACCESS_ONCE(idle->idle_count); 917 idle_count = ACCESS_ONCE(idle->idle_count);
943 if (ACCESS_ONCE(idle->idle_enter)) 918 if (ACCESS_ONCE(idle->clock_idle_enter))
944 idle_count++; 919 idle_count++;
945 } while ((sequence & 1) || (idle->sequence != sequence)); 920 } while ((sequence & 1) || (idle->sequence != sequence));
946 return sprintf(buf, "%llu\n", idle_count); 921 return sprintf(buf, "%llu\n", idle_count);
@@ -958,8 +933,8 @@ static ssize_t show_idle_time(struct device *dev,
958 now = get_clock(); 933 now = get_clock();
959 sequence = ACCESS_ONCE(idle->sequence); 934 sequence = ACCESS_ONCE(idle->sequence);
960 idle_time = ACCESS_ONCE(idle->idle_time); 935 idle_time = ACCESS_ONCE(idle->idle_time);
961 idle_enter = ACCESS_ONCE(idle->idle_enter); 936 idle_enter = ACCESS_ONCE(idle->clock_idle_enter);
962 idle_exit = ACCESS_ONCE(idle->idle_exit); 937 idle_exit = ACCESS_ONCE(idle->clock_idle_exit);
963 } while ((sequence & 1) || (idle->sequence != sequence)); 938 } while ((sequence & 1) || (idle->sequence != sequence));
964 idle_time += idle_enter ? ((idle_exit ? : now) - idle_enter) : 0; 939 idle_time += idle_enter ? ((idle_exit ? : now) - idle_enter) : 0;
965 return sprintf(buf, "%llu\n", idle_time >> 12); 940 return sprintf(buf, "%llu\n", idle_time >> 12);
@@ -982,14 +957,11 @@ static int __cpuinit smp_cpu_notify(struct notifier_block *self,
982 unsigned int cpu = (unsigned int)(long)hcpu; 957 unsigned int cpu = (unsigned int)(long)hcpu;
983 struct cpu *c = &pcpu_devices[cpu].cpu; 958 struct cpu *c = &pcpu_devices[cpu].cpu;
984 struct device *s = &c->dev; 959 struct device *s = &c->dev;
985 struct s390_idle_data *idle;
986 int err = 0; 960 int err = 0;
987 961
988 switch (action) { 962 switch (action) {
989 case CPU_ONLINE: 963 case CPU_ONLINE:
990 case CPU_ONLINE_FROZEN: 964 case CPU_ONLINE_FROZEN:
991 idle = &per_cpu(s390_idle, cpu);
992 memset(idle, 0, sizeof(struct s390_idle_data));
993 err = sysfs_create_group(&s->kobj, &cpu_online_attr_group); 965 err = sysfs_create_group(&s->kobj, &cpu_online_attr_group);
994 break; 966 break;
995 case CPU_DEAD: 967 case CPU_DEAD: