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