aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel/smp.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/kernel/smp.c')
-rw-r--r--arch/s390/kernel/smp.c46
1 files changed, 28 insertions, 18 deletions
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 720fda1620f..ea431e551c6 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -66,7 +66,7 @@ struct pcpu {
66 unsigned long panic_stack; /* panic stack for the cpu */ 66 unsigned long panic_stack; /* panic stack for the cpu */
67 unsigned long ec_mask; /* bit mask for ec_xxx functions */ 67 unsigned long ec_mask; /* bit mask for ec_xxx functions */
68 int state; /* physical cpu state */ 68 int state; /* physical cpu state */
69 u32 status; /* last status received via sigp */ 69 int polarization; /* physical polarization */
70 u16 address; /* physical cpu address */ 70 u16 address; /* physical cpu address */
71}; 71};
72 72
@@ -74,6 +74,10 @@ static u8 boot_cpu_type;
74static u16 boot_cpu_address; 74static u16 boot_cpu_address;
75static struct pcpu pcpu_devices[NR_CPUS]; 75static struct pcpu pcpu_devices[NR_CPUS];
76 76
77/*
78 * The smp_cpu_state_mutex must be held when changing the state or polarization
79 * member of a pcpu data structure within the pcpu_devices arreay.
80 */
77DEFINE_MUTEX(smp_cpu_state_mutex); 81DEFINE_MUTEX(smp_cpu_state_mutex);
78 82
79/* 83/*
@@ -99,7 +103,7 @@ static inline int __pcpu_sigp_relax(u16 addr, u8 order, u32 parm, u32 *status)
99 int cc; 103 int cc;
100 104
101 while (1) { 105 while (1) {
102 cc = __pcpu_sigp(addr, order, parm, status); 106 cc = __pcpu_sigp(addr, order, parm, NULL);
103 if (cc != SIGP_CC_BUSY) 107 if (cc != SIGP_CC_BUSY)
104 return cc; 108 return cc;
105 cpu_relax(); 109 cpu_relax();
@@ -111,7 +115,7 @@ static int pcpu_sigp_retry(struct pcpu *pcpu, u8 order, u32 parm)
111 int cc, retry; 115 int cc, retry;
112 116
113 for (retry = 0; ; retry++) { 117 for (retry = 0; ; retry++) {
114 cc = __pcpu_sigp(pcpu->address, order, parm, &pcpu->status); 118 cc = __pcpu_sigp(pcpu->address, order, parm, NULL);
115 if (cc != SIGP_CC_BUSY) 119 if (cc != SIGP_CC_BUSY)
116 break; 120 break;
117 if (retry >= 3) 121 if (retry >= 3)
@@ -122,16 +126,18 @@ static int pcpu_sigp_retry(struct pcpu *pcpu, u8 order, u32 parm)
122 126
123static inline int pcpu_stopped(struct pcpu *pcpu) 127static inline int pcpu_stopped(struct pcpu *pcpu)
124{ 128{
129 u32 uninitialized_var(status);
130
125 if (__pcpu_sigp(pcpu->address, SIGP_SENSE, 131 if (__pcpu_sigp(pcpu->address, SIGP_SENSE,
126 0, &pcpu->status) != SIGP_CC_STATUS_STORED) 132 0, &status) != SIGP_CC_STATUS_STORED)
127 return 0; 133 return 0;
128 return !!(pcpu->status & (SIGP_STATUS_CHECK_STOP|SIGP_STATUS_STOPPED)); 134 return !!(status & (SIGP_STATUS_CHECK_STOP|SIGP_STATUS_STOPPED));
129} 135}
130 136
131static inline int pcpu_running(struct pcpu *pcpu) 137static inline int pcpu_running(struct pcpu *pcpu)
132{ 138{
133 if (__pcpu_sigp(pcpu->address, SIGP_SENSE_RUNNING, 139 if (__pcpu_sigp(pcpu->address, SIGP_SENSE_RUNNING,
134 0, &pcpu->status) != SIGP_CC_STATUS_STORED) 140 0, NULL) != SIGP_CC_STATUS_STORED)
135 return 1; 141 return 1;
136 /* Status stored condition code is equivalent to cpu not running. */ 142 /* Status stored condition code is equivalent to cpu not running. */
137 return 0; 143 return 0;
@@ -586,6 +592,16 @@ static inline void smp_get_save_area(int cpu, u16 address) { }
586 592
587#endif /* CONFIG_ZFCPDUMP || CONFIG_CRASH_DUMP */ 593#endif /* CONFIG_ZFCPDUMP || CONFIG_CRASH_DUMP */
588 594
595void smp_cpu_set_polarization(int cpu, int val)
596{
597 pcpu_devices[cpu].polarization = val;
598}
599
600int smp_cpu_get_polarization(int cpu)
601{
602 return pcpu_devices[cpu].polarization;
603}
604
589static struct sclp_cpu_info *smp_get_cpu_info(void) 605static struct sclp_cpu_info *smp_get_cpu_info(void)
590{ 606{
591 static int use_sigp_detection; 607 static int use_sigp_detection;
@@ -628,7 +644,7 @@ static int __devinit __smp_rescan_cpus(struct sclp_cpu_info *info,
628 pcpu->address = info->cpu[i].address; 644 pcpu->address = info->cpu[i].address;
629 pcpu->state = (cpu >= info->configured) ? 645 pcpu->state = (cpu >= info->configured) ?
630 CPU_STATE_STANDBY : CPU_STATE_CONFIGURED; 646 CPU_STATE_STANDBY : CPU_STATE_CONFIGURED;
631 cpu_set_polarization(cpu, POLARIZATION_UNKNOWN); 647 smp_cpu_set_polarization(cpu, POLARIZATION_UNKNOWN);
632 set_cpu_present(cpu, true); 648 set_cpu_present(cpu, true);
633 if (sysfs_add && smp_add_present_cpu(cpu) != 0) 649 if (sysfs_add && smp_add_present_cpu(cpu) != 0)
634 set_cpu_present(cpu, false); 650 set_cpu_present(cpu, false);
@@ -796,7 +812,7 @@ void __init smp_prepare_boot_cpu(void)
796 pcpu->async_stack = S390_lowcore.async_stack - ASYNC_SIZE; 812 pcpu->async_stack = S390_lowcore.async_stack - ASYNC_SIZE;
797 pcpu->panic_stack = S390_lowcore.panic_stack - PAGE_SIZE; 813 pcpu->panic_stack = S390_lowcore.panic_stack - PAGE_SIZE;
798 S390_lowcore.percpu_offset = __per_cpu_offset[0]; 814 S390_lowcore.percpu_offset = __per_cpu_offset[0];
799 cpu_set_polarization(0, POLARIZATION_UNKNOWN); 815 smp_cpu_set_polarization(0, POLARIZATION_UNKNOWN);
800 set_cpu_present(0, true); 816 set_cpu_present(0, true);
801 set_cpu_online(0, true); 817 set_cpu_online(0, true);
802} 818}
@@ -862,7 +878,7 @@ static ssize_t cpu_configure_store(struct device *dev,
862 if (rc) 878 if (rc)
863 break; 879 break;
864 pcpu->state = CPU_STATE_STANDBY; 880 pcpu->state = CPU_STATE_STANDBY;
865 cpu_set_polarization(cpu, POLARIZATION_UNKNOWN); 881 smp_cpu_set_polarization(cpu, POLARIZATION_UNKNOWN);
866 topology_expect_change(); 882 topology_expect_change();
867 break; 883 break;
868 case 1: 884 case 1:
@@ -872,7 +888,7 @@ static ssize_t cpu_configure_store(struct device *dev,
872 if (rc) 888 if (rc)
873 break; 889 break;
874 pcpu->state = CPU_STATE_CONFIGURED; 890 pcpu->state = CPU_STATE_CONFIGURED;
875 cpu_set_polarization(cpu, POLARIZATION_UNKNOWN); 891 smp_cpu_set_polarization(cpu, POLARIZATION_UNKNOWN);
876 topology_expect_change(); 892 topology_expect_change();
877 break; 893 break;
878 default: 894 default:
@@ -959,23 +975,17 @@ static int __cpuinit smp_cpu_notify(struct notifier_block *self,
959 struct device *s = &c->dev; 975 struct device *s = &c->dev;
960 int err = 0; 976 int err = 0;
961 977
962 switch (action) { 978 switch (action & ~CPU_TASKS_FROZEN) {
963 case CPU_ONLINE: 979 case CPU_ONLINE:
964 case CPU_ONLINE_FROZEN:
965 err = sysfs_create_group(&s->kobj, &cpu_online_attr_group); 980 err = sysfs_create_group(&s->kobj, &cpu_online_attr_group);
966 break; 981 break;
967 case CPU_DEAD: 982 case CPU_DEAD:
968 case CPU_DEAD_FROZEN:
969 sysfs_remove_group(&s->kobj, &cpu_online_attr_group); 983 sysfs_remove_group(&s->kobj, &cpu_online_attr_group);
970 break; 984 break;
971 } 985 }
972 return notifier_from_errno(err); 986 return notifier_from_errno(err);
973} 987}
974 988
975static struct notifier_block __cpuinitdata smp_cpu_nb = {
976 .notifier_call = smp_cpu_notify,
977};
978
979static int __devinit smp_add_present_cpu(int cpu) 989static int __devinit smp_add_present_cpu(int cpu)
980{ 990{
981 struct cpu *c = &pcpu_devices[cpu].cpu; 991 struct cpu *c = &pcpu_devices[cpu].cpu;
@@ -1050,7 +1060,7 @@ static int __init s390_smp_init(void)
1050{ 1060{
1051 int cpu, rc; 1061 int cpu, rc;
1052 1062
1053 register_cpu_notifier(&smp_cpu_nb); 1063 hotcpu_notifier(smp_cpu_notify, 0);
1054#ifdef CONFIG_HOTPLUG_CPU 1064#ifdef CONFIG_HOTPLUG_CPU
1055 rc = device_create_file(cpu_subsys.dev_root, &dev_attr_rescan); 1065 rc = device_create_file(cpu_subsys.dev_root, &dev_attr_rescan);
1056 if (rc) 1066 if (rc)