| .. | .. |
|---|
| 8 | 8 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt |
|---|
| 9 | 9 | |
|---|
| 10 | 10 | #include <linux/workqueue.h> |
|---|
| 11 | | -#include <linux/bootmem.h> |
|---|
| 11 | +#include <linux/memblock.h> |
|---|
| 12 | 12 | #include <linux/uaccess.h> |
|---|
| 13 | 13 | #include <linux/sysctl.h> |
|---|
| 14 | 14 | #include <linux/cpuset.h> |
|---|
| .. | .. |
|---|
| 26 | 26 | #include <linux/nodemask.h> |
|---|
| 27 | 27 | #include <linux/node.h> |
|---|
| 28 | 28 | #include <asm/sysinfo.h> |
|---|
| 29 | | -#include <asm/numa.h> |
|---|
| 30 | 29 | |
|---|
| 31 | 30 | #define PTF_HORIZONTAL (0UL) |
|---|
| 32 | 31 | #define PTF_VERTICAL (1UL) |
|---|
| .. | .. |
|---|
| 63 | 62 | struct cpu_topology_s390 cpu_topology[NR_CPUS]; |
|---|
| 64 | 63 | EXPORT_SYMBOL_GPL(cpu_topology); |
|---|
| 65 | 64 | |
|---|
| 66 | | -cpumask_t cpus_with_topology; |
|---|
| 67 | | - |
|---|
| 68 | 65 | static cpumask_t cpu_group_map(struct mask_info *info, unsigned int cpu) |
|---|
| 69 | 66 | { |
|---|
| 70 | 67 | cpumask_t mask; |
|---|
| .. | .. |
|---|
| 86 | 83 | cpumask_copy(&mask, cpu_present_mask); |
|---|
| 87 | 84 | break; |
|---|
| 88 | 85 | default: |
|---|
| 89 | | - /* fallthrough */ |
|---|
| 86 | + fallthrough; |
|---|
| 90 | 87 | case TOPOLOGY_MODE_SINGLE: |
|---|
| 91 | 88 | cpumask_copy(&mask, cpumask_of(cpu)); |
|---|
| 92 | 89 | break; |
|---|
| 93 | 90 | } |
|---|
| 91 | + cpumask_and(&mask, &mask, cpu_online_mask); |
|---|
| 94 | 92 | return mask; |
|---|
| 95 | 93 | } |
|---|
| 96 | 94 | |
|---|
| .. | .. |
|---|
| 106 | 104 | for (i = 0; i <= smp_cpu_mtid; i++) |
|---|
| 107 | 105 | if (cpu_present(cpu + i)) |
|---|
| 108 | 106 | cpumask_set_cpu(cpu + i, &mask); |
|---|
| 107 | + cpumask_and(&mask, &mask, cpu_online_mask); |
|---|
| 109 | 108 | return mask; |
|---|
| 110 | 109 | } |
|---|
| 111 | 110 | |
|---|
| .. | .. |
|---|
| 138 | 137 | cpumask_set_cpu(lcpu + i, &drawer->mask); |
|---|
| 139 | 138 | cpumask_set_cpu(lcpu + i, &book->mask); |
|---|
| 140 | 139 | cpumask_set_cpu(lcpu + i, &socket->mask); |
|---|
| 141 | | - cpumask_set_cpu(lcpu + i, &cpus_with_topology); |
|---|
| 142 | 140 | smp_cpu_set_polarization(lcpu + i, tl_core->pp); |
|---|
| 143 | 141 | } |
|---|
| 144 | 142 | } |
|---|
| .. | .. |
|---|
| 245 | 243 | return rc; |
|---|
| 246 | 244 | } |
|---|
| 247 | 245 | |
|---|
| 248 | | -static void update_cpu_masks(void) |
|---|
| 246 | +void update_cpu_masks(void) |
|---|
| 249 | 247 | { |
|---|
| 250 | | - struct cpu_topology_s390 *topo; |
|---|
| 251 | | - int cpu, id; |
|---|
| 248 | + struct cpu_topology_s390 *topo, *topo_package, *topo_sibling; |
|---|
| 249 | + int cpu, sibling, pkg_first, smt_first, id; |
|---|
| 252 | 250 | |
|---|
| 253 | 251 | for_each_possible_cpu(cpu) { |
|---|
| 254 | 252 | topo = &cpu_topology[cpu]; |
|---|
| .. | .. |
|---|
| 256 | 254 | topo->core_mask = cpu_group_map(&socket_info, cpu); |
|---|
| 257 | 255 | topo->book_mask = cpu_group_map(&book_info, cpu); |
|---|
| 258 | 256 | topo->drawer_mask = cpu_group_map(&drawer_info, cpu); |
|---|
| 257 | + topo->booted_cores = 0; |
|---|
| 259 | 258 | if (topology_mode != TOPOLOGY_MODE_HW) { |
|---|
| 260 | 259 | id = topology_mode == TOPOLOGY_MODE_PACKAGE ? 0 : cpu; |
|---|
| 261 | 260 | topo->thread_id = cpu; |
|---|
| .. | .. |
|---|
| 263 | 262 | topo->socket_id = id; |
|---|
| 264 | 263 | topo->book_id = id; |
|---|
| 265 | 264 | topo->drawer_id = id; |
|---|
| 266 | | - if (cpu_present(cpu)) |
|---|
| 267 | | - cpumask_set_cpu(cpu, &cpus_with_topology); |
|---|
| 268 | 265 | } |
|---|
| 269 | 266 | } |
|---|
| 270 | | - numa_update_cpu_topology(); |
|---|
| 267 | + for_each_online_cpu(cpu) { |
|---|
| 268 | + topo = &cpu_topology[cpu]; |
|---|
| 269 | + pkg_first = cpumask_first(&topo->core_mask); |
|---|
| 270 | + topo_package = &cpu_topology[pkg_first]; |
|---|
| 271 | + if (cpu == pkg_first) { |
|---|
| 272 | + for_each_cpu(sibling, &topo->core_mask) { |
|---|
| 273 | + topo_sibling = &cpu_topology[sibling]; |
|---|
| 274 | + smt_first = cpumask_first(&topo_sibling->thread_mask); |
|---|
| 275 | + if (sibling == smt_first) |
|---|
| 276 | + topo_package->booted_cores++; |
|---|
| 277 | + } |
|---|
| 278 | + } else { |
|---|
| 279 | + topo->booted_cores = topo_package->booted_cores; |
|---|
| 280 | + } |
|---|
| 281 | + } |
|---|
| 271 | 282 | } |
|---|
| 272 | 283 | |
|---|
| 273 | 284 | void store_topology(struct sysinfo_15_1_x *info) |
|---|
| .. | .. |
|---|
| 289 | 300 | int rc = 0; |
|---|
| 290 | 301 | |
|---|
| 291 | 302 | mutex_lock(&smp_cpu_state_mutex); |
|---|
| 292 | | - cpumask_clear(&cpus_with_topology); |
|---|
| 293 | 303 | if (MACHINE_HAS_TOPOLOGY) { |
|---|
| 294 | 304 | rc = 1; |
|---|
| 295 | 305 | store_topology(info); |
|---|
| .. | .. |
|---|
| 346 | 356 | static void set_topology_timer(void) |
|---|
| 347 | 357 | { |
|---|
| 348 | 358 | if (atomic_add_unless(&topology_poll, -1, 0)) |
|---|
| 349 | | - mod_timer(&topology_timer, jiffies + HZ / 10); |
|---|
| 359 | + mod_timer(&topology_timer, jiffies + msecs_to_jiffies(100)); |
|---|
| 350 | 360 | else |
|---|
| 351 | | - mod_timer(&topology_timer, jiffies + HZ * 60); |
|---|
| 361 | + mod_timer(&topology_timer, jiffies + msecs_to_jiffies(60 * MSEC_PER_SEC)); |
|---|
| 352 | 362 | } |
|---|
| 353 | 363 | |
|---|
| 354 | 364 | void topology_expect_change(void) |
|---|
| .. | .. |
|---|
| 520 | 530 | nr_masks *= info->mag[TOPOLOGY_NR_MAG - offset - 1 - i]; |
|---|
| 521 | 531 | nr_masks = max(nr_masks, 1); |
|---|
| 522 | 532 | for (i = 0; i < nr_masks; i++) { |
|---|
| 523 | | - mask->next = memblock_virt_alloc(sizeof(*mask->next), 8); |
|---|
| 533 | + mask->next = memblock_alloc(sizeof(*mask->next), 8); |
|---|
| 534 | + if (!mask->next) |
|---|
| 535 | + panic("%s: Failed to allocate %zu bytes align=0x%x\n", |
|---|
| 536 | + __func__, sizeof(*mask->next), 8); |
|---|
| 524 | 537 | mask = mask->next; |
|---|
| 525 | 538 | } |
|---|
| 526 | 539 | } |
|---|
| .. | .. |
|---|
| 538 | 551 | } |
|---|
| 539 | 552 | if (!MACHINE_HAS_TOPOLOGY) |
|---|
| 540 | 553 | goto out; |
|---|
| 541 | | - tl_info = memblock_virt_alloc(PAGE_SIZE, PAGE_SIZE); |
|---|
| 554 | + tl_info = memblock_alloc(PAGE_SIZE, PAGE_SIZE); |
|---|
| 555 | + if (!tl_info) |
|---|
| 556 | + panic("%s: Failed to allocate %lu bytes align=0x%lx\n", |
|---|
| 557 | + __func__, PAGE_SIZE, PAGE_SIZE); |
|---|
| 542 | 558 | info = tl_info; |
|---|
| 543 | 559 | store_topology(info); |
|---|
| 544 | 560 | pr_info("The CPU configuration topology of the machine is: %d %d %d %d %d %d / %d\n", |
|---|
| .. | .. |
|---|
| 578 | 594 | early_param("topology", topology_setup); |
|---|
| 579 | 595 | |
|---|
| 580 | 596 | static int topology_ctl_handler(struct ctl_table *ctl, int write, |
|---|
| 581 | | - void __user *buffer, size_t *lenp, loff_t *ppos) |
|---|
| 597 | + void *buffer, size_t *lenp, loff_t *ppos) |
|---|
| 582 | 598 | { |
|---|
| 583 | 599 | int enabled = topology_is_enabled(); |
|---|
| 584 | 600 | int new_mode; |
|---|
| 585 | | - int zero = 0; |
|---|
| 586 | | - int one = 1; |
|---|
| 587 | 601 | int rc; |
|---|
| 588 | 602 | struct ctl_table ctl_entry = { |
|---|
| 589 | 603 | .procname = ctl->procname, |
|---|
| 590 | 604 | .data = &enabled, |
|---|
| 591 | 605 | .maxlen = sizeof(int), |
|---|
| 592 | | - .extra1 = &zero, |
|---|
| 593 | | - .extra2 = &one, |
|---|
| 606 | + .extra1 = SYSCTL_ZERO, |
|---|
| 607 | + .extra2 = SYSCTL_ONE, |
|---|
| 594 | 608 | }; |
|---|
| 595 | 609 | |
|---|
| 596 | 610 | rc = proc_douintvec_minmax(&ctl_entry, write, buffer, lenp, ppos); |
|---|