diff options
author | Heiko Carstens <heiko.carstens@de.ibm.com> | 2015-02-04 08:21:31 -0500 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2015-02-12 03:37:22 -0500 |
commit | d05d15da18f521c4fb5a35b923ce33955c848d99 (patch) | |
tree | ebcecd24578e12e06eedb25fab426d208e75885e /arch | |
parent | 49253925c0be02ed4eb7d94a426731107dd8059d (diff) |
s390/topology: delay initialization of topology cpu masks
There is no reason to initialize the topology cpu masks already while
setup_arch() is being called. It is sufficient to initialize the masks
before the scheduler becomes SMP aware.
Therefore a pre-SMP initcall aka early_initcall is suffucient.
This also allows to convert the cpu_topology array into a per cpu
variable with a later patch. Without this patch this wouldn't be
possible since the per cpu memory areas are not allocated while setup_arch
is executed.
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/s390/include/asm/topology.h | 8 | ||||
-rw-r--r-- | arch/s390/kernel/setup.c | 1 | ||||
-rw-r--r-- | arch/s390/kernel/topology.c | 100 |
3 files changed, 47 insertions, 62 deletions
diff --git a/arch/s390/include/asm/topology.h b/arch/s390/include/asm/topology.h index c4fbb9527c5c..9454231c9f23 100644 --- a/arch/s390/include/asm/topology.h +++ b/arch/s390/include/asm/topology.h | |||
@@ -51,14 +51,6 @@ static inline void topology_expect_change(void) { } | |||
51 | #define POLARIZATION_VM (2) | 51 | #define POLARIZATION_VM (2) |
52 | #define POLARIZATION_VH (3) | 52 | #define POLARIZATION_VH (3) |
53 | 53 | ||
54 | #ifdef CONFIG_SCHED_BOOK | ||
55 | void s390_init_cpu_topology(void); | ||
56 | #else | ||
57 | static inline void s390_init_cpu_topology(void) | ||
58 | { | ||
59 | }; | ||
60 | #endif | ||
61 | |||
62 | #include <asm-generic/topology.h> | 54 | #include <asm-generic/topology.h> |
63 | 55 | ||
64 | #endif /* _ASM_S390_TOPOLOGY_H */ | 56 | #endif /* _ASM_S390_TOPOLOGY_H */ |
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index bfac77ada4f2..a5ea8bc17cb3 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c | |||
@@ -909,7 +909,6 @@ void __init setup_arch(char **cmdline_p) | |||
909 | setup_lowcore(); | 909 | setup_lowcore(); |
910 | smp_fill_possible_mask(); | 910 | smp_fill_possible_mask(); |
911 | cpu_init(); | 911 | cpu_init(); |
912 | s390_init_cpu_topology(); | ||
913 | 912 | ||
914 | /* | 913 | /* |
915 | * Setup capabilities (ELF_HWCAP & ELF_PLATFORM). | 914 | * Setup capabilities (ELF_HWCAP & ELF_PLATFORM). |
diff --git a/arch/s390/kernel/topology.c b/arch/s390/kernel/topology.c index 24ee33f1af24..d2303f6340ab 100644 --- a/arch/s390/kernel/topology.c +++ b/arch/s390/kernel/topology.c | |||
@@ -7,14 +7,14 @@ | |||
7 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt | 7 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt |
8 | 8 | ||
9 | #include <linux/workqueue.h> | 9 | #include <linux/workqueue.h> |
10 | #include <linux/bootmem.h> | ||
11 | #include <linux/cpuset.h> | 10 | #include <linux/cpuset.h> |
12 | #include <linux/device.h> | 11 | #include <linux/device.h> |
13 | #include <linux/export.h> | 12 | #include <linux/export.h> |
14 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
15 | #include <linux/sched.h> | 14 | #include <linux/sched.h> |
16 | #include <linux/init.h> | ||
17 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
16 | #include <linux/init.h> | ||
17 | #include <linux/slab.h> | ||
18 | #include <linux/cpu.h> | 18 | #include <linux/cpu.h> |
19 | #include <linux/smp.h> | 19 | #include <linux/smp.h> |
20 | #include <linux/mm.h> | 20 | #include <linux/mm.h> |
@@ -334,50 +334,6 @@ void topology_expect_change(void) | |||
334 | set_topology_timer(); | 334 | set_topology_timer(); |
335 | } | 335 | } |
336 | 336 | ||
337 | static int __init early_parse_topology(char *p) | ||
338 | { | ||
339 | if (strncmp(p, "off", 3)) | ||
340 | return 0; | ||
341 | topology_enabled = 0; | ||
342 | return 0; | ||
343 | } | ||
344 | early_param("topology", early_parse_topology); | ||
345 | |||
346 | static void __init alloc_masks(struct sysinfo_15_1_x *info, | ||
347 | struct mask_info *mask, int offset) | ||
348 | { | ||
349 | int i, nr_masks; | ||
350 | |||
351 | nr_masks = info->mag[TOPOLOGY_NR_MAG - offset]; | ||
352 | for (i = 0; i < info->mnest - offset; i++) | ||
353 | nr_masks *= info->mag[TOPOLOGY_NR_MAG - offset - 1 - i]; | ||
354 | nr_masks = max(nr_masks, 1); | ||
355 | for (i = 0; i < nr_masks; i++) { | ||
356 | mask->next = alloc_bootmem_align( | ||
357 | roundup_pow_of_two(sizeof(struct mask_info)), | ||
358 | roundup_pow_of_two(sizeof(struct mask_info))); | ||
359 | mask = mask->next; | ||
360 | } | ||
361 | } | ||
362 | |||
363 | void __init s390_init_cpu_topology(void) | ||
364 | { | ||
365 | struct sysinfo_15_1_x *info; | ||
366 | int i; | ||
367 | |||
368 | if (!MACHINE_HAS_TOPOLOGY) | ||
369 | return; | ||
370 | tl_info = alloc_bootmem_pages(PAGE_SIZE); | ||
371 | info = tl_info; | ||
372 | store_topology(info); | ||
373 | pr_info("The CPU configuration topology of the machine is:"); | ||
374 | for (i = 0; i < TOPOLOGY_NR_MAG; i++) | ||
375 | printk(KERN_CONT " %d", info->mag[i]); | ||
376 | printk(KERN_CONT " / %d\n", info->mnest); | ||
377 | alloc_masks(info, &socket_info, 1); | ||
378 | alloc_masks(info, &book_info, 2); | ||
379 | } | ||
380 | |||
381 | static int cpu_management; | 337 | static int cpu_management; |
382 | 338 | ||
383 | static ssize_t dispatching_show(struct device *dev, | 339 | static ssize_t dispatching_show(struct device *dev, |
@@ -481,6 +437,15 @@ static const struct cpumask *cpu_book_mask(int cpu) | |||
481 | return &cpu_topology[cpu].book_mask; | 437 | return &cpu_topology[cpu].book_mask; |
482 | } | 438 | } |
483 | 439 | ||
440 | static int __init early_parse_topology(char *p) | ||
441 | { | ||
442 | if (strncmp(p, "off", 3)) | ||
443 | return 0; | ||
444 | topology_enabled = 0; | ||
445 | return 0; | ||
446 | } | ||
447 | early_param("topology", early_parse_topology); | ||
448 | |||
484 | static struct sched_domain_topology_level s390_topology[] = { | 449 | static struct sched_domain_topology_level s390_topology[] = { |
485 | { cpu_thread_mask, cpu_smt_flags, SD_INIT_NAME(SMT) }, | 450 | { cpu_thread_mask, cpu_smt_flags, SD_INIT_NAME(SMT) }, |
486 | { cpu_coregroup_mask, cpu_core_flags, SD_INIT_NAME(MC) }, | 451 | { cpu_coregroup_mask, cpu_core_flags, SD_INIT_NAME(MC) }, |
@@ -489,6 +454,42 @@ static struct sched_domain_topology_level s390_topology[] = { | |||
489 | { NULL, }, | 454 | { NULL, }, |
490 | }; | 455 | }; |
491 | 456 | ||
457 | static void __init alloc_masks(struct sysinfo_15_1_x *info, | ||
458 | struct mask_info *mask, int offset) | ||
459 | { | ||
460 | int i, nr_masks; | ||
461 | |||
462 | nr_masks = info->mag[TOPOLOGY_NR_MAG - offset]; | ||
463 | for (i = 0; i < info->mnest - offset; i++) | ||
464 | nr_masks *= info->mag[TOPOLOGY_NR_MAG - offset - 1 - i]; | ||
465 | nr_masks = max(nr_masks, 1); | ||
466 | for (i = 0; i < nr_masks; i++) { | ||
467 | mask->next = kzalloc(sizeof(*mask->next), GFP_KERNEL); | ||
468 | mask = mask->next; | ||
469 | } | ||
470 | } | ||
471 | |||
472 | static int __init s390_topology_init(void) | ||
473 | { | ||
474 | struct sysinfo_15_1_x *info; | ||
475 | int i; | ||
476 | |||
477 | if (!MACHINE_HAS_TOPOLOGY) | ||
478 | return 0; | ||
479 | tl_info = (struct sysinfo_15_1_x *)__get_free_page(GFP_KERNEL); | ||
480 | info = tl_info; | ||
481 | store_topology(info); | ||
482 | pr_info("The CPU configuration topology of the machine is:"); | ||
483 | for (i = 0; i < TOPOLOGY_NR_MAG; i++) | ||
484 | printk(KERN_CONT " %d", info->mag[i]); | ||
485 | printk(KERN_CONT " / %d\n", info->mnest); | ||
486 | alloc_masks(info, &socket_info, 1); | ||
487 | alloc_masks(info, &book_info, 2); | ||
488 | set_sched_topology(s390_topology); | ||
489 | return 0; | ||
490 | } | ||
491 | early_initcall(s390_topology_init); | ||
492 | |||
492 | static int __init topology_init(void) | 493 | static int __init topology_init(void) |
493 | { | 494 | { |
494 | if (MACHINE_HAS_TOPOLOGY) | 495 | if (MACHINE_HAS_TOPOLOGY) |
@@ -498,10 +499,3 @@ static int __init topology_init(void) | |||
498 | return device_create_file(cpu_subsys.dev_root, &dev_attr_dispatching); | 499 | return device_create_file(cpu_subsys.dev_root, &dev_attr_dispatching); |
499 | } | 500 | } |
500 | device_initcall(topology_init); | 501 | device_initcall(topology_init); |
501 | |||
502 | static int __init early_topology_init(void) | ||
503 | { | ||
504 | set_sched_topology(s390_topology); | ||
505 | return 0; | ||
506 | } | ||
507 | early_initcall(early_topology_init); | ||