diff options
Diffstat (limited to 'arch/s390/kernel/topology.c')
-rw-r--r-- | arch/s390/kernel/topology.c | 46 |
1 files changed, 22 insertions, 24 deletions
diff --git a/arch/s390/kernel/topology.c b/arch/s390/kernel/topology.c index 0601cd3231e4..cc362c9ea8f1 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 | ||
64 | static int topology_enabled; | ||
60 | static void topology_work_fn(struct work_struct *work); | 65 | static void topology_work_fn(struct work_struct *work); |
61 | static struct tl_info *tl_info; | 66 | static struct tl_info *tl_info; |
62 | static struct core_info core_info; | 67 | static struct core_info core_info; |
63 | static int machine_has_topology; | 68 | static int machine_has_topology; |
64 | static int machine_has_topology_irq; | ||
65 | static struct timer_list topology_timer; | 69 | static struct timer_list topology_timer; |
66 | static void set_topology_timer(void); | 70 | static void set_topology_timer(void); |
67 | static DECLARE_WORK(topology_work, topology_work_fn); | 71 | static 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)) { |
@@ -173,7 +177,7 @@ static void topology_update_polarization_simple(void) | |||
173 | int cpu; | 177 | int cpu; |
174 | 178 | ||
175 | mutex_lock(&smp_cpu_state_mutex); | 179 | mutex_lock(&smp_cpu_state_mutex); |
176 | for_each_present_cpu(cpu) | 180 | for_each_possible_cpu(cpu) |
177 | smp_cpu_polarization[cpu] = POLARIZATION_HRZ; | 181 | smp_cpu_polarization[cpu] = POLARIZATION_HRZ; |
178 | mutex_unlock(&smp_cpu_state_mutex); | 182 | mutex_unlock(&smp_cpu_state_mutex); |
179 | } | 183 | } |
@@ -204,7 +208,7 @@ int topology_set_cpu_management(int fc) | |||
204 | rc = ptf(PTF_HORIZONTAL); | 208 | rc = ptf(PTF_HORIZONTAL); |
205 | if (rc) | 209 | if (rc) |
206 | return -EBUSY; | 210 | return -EBUSY; |
207 | for_each_present_cpu(cpu) | 211 | for_each_possible_cpu(cpu) |
208 | smp_cpu_polarization[cpu] = POLARIZATION_UNKNWN; | 212 | smp_cpu_polarization[cpu] = POLARIZATION_UNKNWN; |
209 | return rc; | 213 | return rc; |
210 | } | 214 | } |
@@ -213,11 +217,11 @@ static void update_cpu_core_map(void) | |||
213 | { | 217 | { |
214 | int cpu; | 218 | int cpu; |
215 | 219 | ||
216 | for_each_present_cpu(cpu) | 220 | for_each_possible_cpu(cpu) |
217 | cpu_core_map[cpu] = cpu_coregroup_map(cpu); | 221 | cpu_core_map[cpu] = cpu_coregroup_map(cpu); |
218 | } | 222 | } |
219 | 223 | ||
220 | void arch_update_cpu_topology(void) | 224 | int arch_update_cpu_topology(void) |
221 | { | 225 | { |
222 | struct tl_info *info = tl_info; | 226 | struct tl_info *info = tl_info; |
223 | struct sys_device *sysdev; | 227 | struct sys_device *sysdev; |
@@ -226,7 +230,7 @@ void arch_update_cpu_topology(void) | |||
226 | if (!machine_has_topology) { | 230 | if (!machine_has_topology) { |
227 | update_cpu_core_map(); | 231 | update_cpu_core_map(); |
228 | topology_update_polarization_simple(); | 232 | topology_update_polarization_simple(); |
229 | return; | 233 | return 0; |
230 | } | 234 | } |
231 | stsi(info, 15, 1, 2); | 235 | stsi(info, 15, 1, 2); |
232 | tl_to_cores(info); | 236 | tl_to_cores(info); |
@@ -235,11 +239,12 @@ void arch_update_cpu_topology(void) | |||
235 | sysdev = get_cpu_sysdev(cpu); | 239 | sysdev = get_cpu_sysdev(cpu); |
236 | kobject_uevent(&sysdev->kobj, KOBJ_CHANGE); | 240 | kobject_uevent(&sysdev->kobj, KOBJ_CHANGE); |
237 | } | 241 | } |
242 | return 1; | ||
238 | } | 243 | } |
239 | 244 | ||
240 | static void topology_work_fn(struct work_struct *work) | 245 | static void topology_work_fn(struct work_struct *work) |
241 | { | 246 | { |
242 | arch_reinit_sched_domains(); | 247 | rebuild_sched_domains(); |
243 | } | 248 | } |
244 | 249 | ||
245 | void topology_schedule_update(void) | 250 | void topology_schedule_update(void) |
@@ -262,10 +267,14 @@ static void set_topology_timer(void) | |||
262 | add_timer(&topology_timer); | 267 | add_timer(&topology_timer); |
263 | } | 268 | } |
264 | 269 | ||
265 | static void topology_interrupt(__u16 code) | 270 | static int __init early_parse_topology(char *p) |
266 | { | 271 | { |
267 | schedule_work(&topology_work); | 272 | if (strncmp(p, "on", 2)) |
273 | return 0; | ||
274 | topology_enabled = 1; | ||
275 | return 0; | ||
268 | } | 276 | } |
277 | early_param("topology", early_parse_topology); | ||
269 | 278 | ||
270 | static int __init init_topology_update(void) | 279 | static int __init init_topology_update(void) |
271 | { | 280 | { |
@@ -277,14 +286,7 @@ static int __init init_topology_update(void) | |||
277 | goto out; | 286 | goto out; |
278 | } | 287 | } |
279 | init_timer_deferrable(&topology_timer); | 288 | init_timer_deferrable(&topology_timer); |
280 | if (machine_has_topology_irq) { | 289 | set_topology_timer(); |
281 | rc = register_external_interrupt(0x2005, topology_interrupt); | ||
282 | if (rc) | ||
283 | goto out; | ||
284 | ctl_set_bit(0, 8); | ||
285 | } | ||
286 | else | ||
287 | set_topology_timer(); | ||
288 | out: | 290 | out: |
289 | update_cpu_core_map(); | 291 | update_cpu_core_map(); |
290 | return rc; | 292 | return rc; |
@@ -305,9 +307,6 @@ void __init s390_init_cpu_topology(void) | |||
305 | return; | 307 | return; |
306 | machine_has_topology = 1; | 308 | machine_has_topology = 1; |
307 | 309 | ||
308 | if (facility_bits & (1ULL << 51)) | ||
309 | machine_has_topology_irq = 1; | ||
310 | |||
311 | tl_info = alloc_bootmem_pages(PAGE_SIZE); | 310 | tl_info = alloc_bootmem_pages(PAGE_SIZE); |
312 | info = tl_info; | 311 | info = tl_info; |
313 | stsi(info, 15, 1, 2); | 312 | stsi(info, 15, 1, 2); |
@@ -316,7 +315,7 @@ void __init s390_init_cpu_topology(void) | |||
316 | for (i = 0; i < info->mnest - 2; i++) | 315 | for (i = 0; i < info->mnest - 2; i++) |
317 | nr_cores *= info->mag[NR_MAG - 3 - i]; | 316 | nr_cores *= info->mag[NR_MAG - 3 - i]; |
318 | 317 | ||
319 | printk(KERN_INFO "CPU topology:"); | 318 | pr_info("The CPU configuration topology of the machine is:"); |
320 | for (i = 0; i < NR_MAG; i++) | 319 | for (i = 0; i < NR_MAG; i++) |
321 | printk(" %d", info->mag[i]); | 320 | printk(" %d", info->mag[i]); |
322 | printk(" / %d\n", info->mnest); | 321 | printk(" / %d\n", info->mnest); |
@@ -331,5 +330,4 @@ void __init s390_init_cpu_topology(void) | |||
331 | return; | 330 | return; |
332 | error: | 331 | error: |
333 | machine_has_topology = 0; | 332 | machine_has_topology = 0; |
334 | machine_has_topology_irq = 0; | ||
335 | } | 333 | } |