aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel/topology.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/kernel/topology.c')
-rw-r--r--arch/s390/kernel/topology.c46
1 files changed, 22 insertions, 24 deletions
diff --git a/arch/s390/kernel/topology.c b/arch/s390/kernel/topology.c
index a947899dcba1..90e9ba11eba1 100644
--- a/arch/s390/kernel/topology.c
+++ b/arch/s390/kernel/topology.c
@@ -3,6 +3,9 @@
3 * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com> 3 * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>
4 */ 4 */
5 5
6#define KMSG_COMPONENT "cpu"
7#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
8
6#include <linux/kernel.h> 9#include <linux/kernel.h>
7#include <linux/mm.h> 10#include <linux/mm.h>
8#include <linux/init.h> 11#include <linux/init.h>
@@ -12,6 +15,7 @@
12#include <linux/workqueue.h> 15#include <linux/workqueue.h>
13#include <linux/cpu.h> 16#include <linux/cpu.h>
14#include <linux/smp.h> 17#include <linux/smp.h>
18#include <linux/cpuset.h>
15#include <asm/delay.h> 19#include <asm/delay.h>
16#include <asm/s390_ext.h> 20#include <asm/s390_ext.h>
17#include <asm/sysinfo.h> 21#include <asm/sysinfo.h>
@@ -57,11 +61,11 @@ struct core_info {
57 cpumask_t mask; 61 cpumask_t mask;
58}; 62};
59 63
64static int topology_enabled;
60static void topology_work_fn(struct work_struct *work); 65static void topology_work_fn(struct work_struct *work);
61static struct tl_info *tl_info; 66static struct tl_info *tl_info;
62static struct core_info core_info; 67static struct core_info core_info;
63static int machine_has_topology; 68static int machine_has_topology;
64static int machine_has_topology_irq;
65static struct timer_list topology_timer; 69static struct timer_list topology_timer;
66static void set_topology_timer(void); 70static void set_topology_timer(void);
67static DECLARE_WORK(topology_work, topology_work_fn); 71static DECLARE_WORK(topology_work, topology_work_fn);
@@ -77,8 +81,8 @@ cpumask_t cpu_coregroup_map(unsigned int cpu)
77 cpumask_t mask; 81 cpumask_t mask;
78 82
79 cpus_clear(mask); 83 cpus_clear(mask);
80 if (!machine_has_topology) 84 if (!topology_enabled || !machine_has_topology)
81 return cpu_present_map; 85 return cpu_possible_map;
82 spin_lock_irqsave(&topology_lock, flags); 86 spin_lock_irqsave(&topology_lock, flags);
83 while (core) { 87 while (core) {
84 if (cpu_isset(cpu, core->mask)) { 88 if (cpu_isset(cpu, core->mask)) {
@@ -168,7 +172,7 @@ static void topology_update_polarization_simple(void)
168 int cpu; 172 int cpu;
169 173
170 mutex_lock(&smp_cpu_state_mutex); 174 mutex_lock(&smp_cpu_state_mutex);
171 for_each_present_cpu(cpu) 175 for_each_possible_cpu(cpu)
172 smp_cpu_polarization[cpu] = POLARIZATION_HRZ; 176 smp_cpu_polarization[cpu] = POLARIZATION_HRZ;
173 mutex_unlock(&smp_cpu_state_mutex); 177 mutex_unlock(&smp_cpu_state_mutex);
174} 178}
@@ -199,7 +203,7 @@ int topology_set_cpu_management(int fc)
199 rc = ptf(PTF_HORIZONTAL); 203 rc = ptf(PTF_HORIZONTAL);
200 if (rc) 204 if (rc)
201 return -EBUSY; 205 return -EBUSY;
202 for_each_present_cpu(cpu) 206 for_each_possible_cpu(cpu)
203 smp_cpu_polarization[cpu] = POLARIZATION_UNKNWN; 207 smp_cpu_polarization[cpu] = POLARIZATION_UNKNWN;
204 return rc; 208 return rc;
205} 209}
@@ -208,11 +212,11 @@ static void update_cpu_core_map(void)
208{ 212{
209 int cpu; 213 int cpu;
210 214
211 for_each_present_cpu(cpu) 215 for_each_possible_cpu(cpu)
212 cpu_core_map[cpu] = cpu_coregroup_map(cpu); 216 cpu_core_map[cpu] = cpu_coregroup_map(cpu);
213} 217}
214 218
215void arch_update_cpu_topology(void) 219int arch_update_cpu_topology(void)
216{ 220{
217 struct tl_info *info = tl_info; 221 struct tl_info *info = tl_info;
218 struct sys_device *sysdev; 222 struct sys_device *sysdev;
@@ -221,7 +225,7 @@ void arch_update_cpu_topology(void)
221 if (!machine_has_topology) { 225 if (!machine_has_topology) {
222 update_cpu_core_map(); 226 update_cpu_core_map();
223 topology_update_polarization_simple(); 227 topology_update_polarization_simple();
224 return; 228 return 0;
225 } 229 }
226 stsi(info, 15, 1, 2); 230 stsi(info, 15, 1, 2);
227 tl_to_cores(info); 231 tl_to_cores(info);
@@ -230,11 +234,12 @@ void arch_update_cpu_topology(void)
230 sysdev = get_cpu_sysdev(cpu); 234 sysdev = get_cpu_sysdev(cpu);
231 kobject_uevent(&sysdev->kobj, KOBJ_CHANGE); 235 kobject_uevent(&sysdev->kobj, KOBJ_CHANGE);
232 } 236 }
237 return 1;
233} 238}
234 239
235static void topology_work_fn(struct work_struct *work) 240static void topology_work_fn(struct work_struct *work)
236{ 241{
237 arch_reinit_sched_domains(); 242 rebuild_sched_domains();
238} 243}
239 244
240void topology_schedule_update(void) 245void topology_schedule_update(void)
@@ -257,10 +262,14 @@ static void set_topology_timer(void)
257 add_timer(&topology_timer); 262 add_timer(&topology_timer);
258} 263}
259 264
260static void topology_interrupt(__u16 code) 265static int __init early_parse_topology(char *p)
261{ 266{
262 schedule_work(&topology_work); 267 if (strncmp(p, "on", 2))
268 return 0;
269 topology_enabled = 1;
270 return 0;
263} 271}
272early_param("topology", early_parse_topology);
264 273
265static int __init init_topology_update(void) 274static int __init init_topology_update(void)
266{ 275{
@@ -272,14 +281,7 @@ static int __init init_topology_update(void)
272 goto out; 281 goto out;
273 } 282 }
274 init_timer_deferrable(&topology_timer); 283 init_timer_deferrable(&topology_timer);
275 if (machine_has_topology_irq) { 284 set_topology_timer();
276 rc = register_external_interrupt(0x2005, topology_interrupt);
277 if (rc)
278 goto out;
279 ctl_set_bit(0, 8);
280 }
281 else
282 set_topology_timer();
283out: 285out:
284 update_cpu_core_map(); 286 update_cpu_core_map();
285 return rc; 287 return rc;
@@ -300,9 +302,6 @@ void __init s390_init_cpu_topology(void)
300 return; 302 return;
301 machine_has_topology = 1; 303 machine_has_topology = 1;
302 304
303 if (facility_bits & (1ULL << 51))
304 machine_has_topology_irq = 1;
305
306 tl_info = alloc_bootmem_pages(PAGE_SIZE); 305 tl_info = alloc_bootmem_pages(PAGE_SIZE);
307 info = tl_info; 306 info = tl_info;
308 stsi(info, 15, 1, 2); 307 stsi(info, 15, 1, 2);
@@ -311,7 +310,7 @@ void __init s390_init_cpu_topology(void)
311 for (i = 0; i < info->mnest - 2; i++) 310 for (i = 0; i < info->mnest - 2; i++)
312 nr_cores *= info->mag[NR_MAG - 3 - i]; 311 nr_cores *= info->mag[NR_MAG - 3 - i];
313 312
314 printk(KERN_INFO "CPU topology:"); 313 pr_info("The CPU configuration topology of the machine is:");
315 for (i = 0; i < NR_MAG; i++) 314 for (i = 0; i < NR_MAG; i++)
316 printk(" %d", info->mag[i]); 315 printk(" %d", info->mag[i]);
317 printk(" / %d\n", info->mnest); 316 printk(" / %d\n", info->mnest);
@@ -326,5 +325,4 @@ void __init s390_init_cpu_topology(void)
326 return; 325 return;
327error: 326error:
328 machine_has_topology = 0; 327 machine_has_topology = 0;
329 machine_has_topology_irq = 0;
330} 328}