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 | |
| 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>
| -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); | ||
