diff options
Diffstat (limited to 'arch/powerpc/mm/numa.c')
-rw-r--r-- | arch/powerpc/mm/numa.c | 48 |
1 files changed, 44 insertions, 4 deletions
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index 649666d5d1c2..b9d1dfdbe5bb 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c | |||
@@ -8,6 +8,8 @@ | |||
8 | * as published by the Free Software Foundation; either version | 8 | * as published by the Free Software Foundation; either version |
9 | * 2 of the License, or (at your option) any later version. | 9 | * 2 of the License, or (at your option) any later version. |
10 | */ | 10 | */ |
11 | #define pr_fmt(fmt) "numa: " fmt | ||
12 | |||
11 | #include <linux/threads.h> | 13 | #include <linux/threads.h> |
12 | #include <linux/bootmem.h> | 14 | #include <linux/bootmem.h> |
13 | #include <linux/init.h> | 15 | #include <linux/init.h> |
@@ -1153,6 +1155,22 @@ static int __init early_numa(char *p) | |||
1153 | } | 1155 | } |
1154 | early_param("numa", early_numa); | 1156 | early_param("numa", early_numa); |
1155 | 1157 | ||
1158 | static bool topology_updates_enabled = true; | ||
1159 | |||
1160 | static int __init early_topology_updates(char *p) | ||
1161 | { | ||
1162 | if (!p) | ||
1163 | return 0; | ||
1164 | |||
1165 | if (!strcmp(p, "off")) { | ||
1166 | pr_info("Disabling topology updates\n"); | ||
1167 | topology_updates_enabled = false; | ||
1168 | } | ||
1169 | |||
1170 | return 0; | ||
1171 | } | ||
1172 | early_param("topology_updates", early_topology_updates); | ||
1173 | |||
1156 | #ifdef CONFIG_MEMORY_HOTPLUG | 1174 | #ifdef CONFIG_MEMORY_HOTPLUG |
1157 | /* | 1175 | /* |
1158 | * Find the node associated with a hot added memory section for | 1176 | * Find the node associated with a hot added memory section for |
@@ -1442,8 +1460,11 @@ static long hcall_vphn(unsigned long cpu, __be32 *associativity) | |||
1442 | long retbuf[PLPAR_HCALL9_BUFSIZE] = {0}; | 1460 | long retbuf[PLPAR_HCALL9_BUFSIZE] = {0}; |
1443 | u64 flags = 1; | 1461 | u64 flags = 1; |
1444 | int hwcpu = get_hard_smp_processor_id(cpu); | 1462 | int hwcpu = get_hard_smp_processor_id(cpu); |
1463 | int i; | ||
1445 | 1464 | ||
1446 | rc = plpar_hcall9(H_HOME_NODE_ASSOCIATIVITY, retbuf, flags, hwcpu); | 1465 | rc = plpar_hcall9(H_HOME_NODE_ASSOCIATIVITY, retbuf, flags, hwcpu); |
1466 | for (i = 0; i < 6; i++) | ||
1467 | retbuf[i] = cpu_to_be64(retbuf[i]); | ||
1447 | vphn_unpack_associativity(retbuf, associativity); | 1468 | vphn_unpack_associativity(retbuf, associativity); |
1448 | 1469 | ||
1449 | return rc; | 1470 | return rc; |
@@ -1488,11 +1509,14 @@ static int update_cpu_topology(void *data) | |||
1488 | cpu = smp_processor_id(); | 1509 | cpu = smp_processor_id(); |
1489 | 1510 | ||
1490 | for (update = data; update; update = update->next) { | 1511 | for (update = data; update; update = update->next) { |
1512 | int new_nid = update->new_nid; | ||
1491 | if (cpu != update->cpu) | 1513 | if (cpu != update->cpu) |
1492 | continue; | 1514 | continue; |
1493 | 1515 | ||
1494 | unmap_cpu_from_node(update->cpu); | 1516 | unmap_cpu_from_node(cpu); |
1495 | map_cpu_to_node(update->cpu, update->new_nid); | 1517 | map_cpu_to_node(cpu, new_nid); |
1518 | set_cpu_numa_node(cpu, new_nid); | ||
1519 | set_cpu_numa_mem(cpu, local_memory_node(new_nid)); | ||
1496 | vdso_getcpu_init(); | 1520 | vdso_getcpu_init(); |
1497 | } | 1521 | } |
1498 | 1522 | ||
@@ -1539,6 +1563,9 @@ int arch_update_cpu_topology(void) | |||
1539 | struct device *dev; | 1563 | struct device *dev; |
1540 | int weight, new_nid, i = 0; | 1564 | int weight, new_nid, i = 0; |
1541 | 1565 | ||
1566 | if (!prrn_enabled && !vphn_enabled) | ||
1567 | return 0; | ||
1568 | |||
1542 | weight = cpumask_weight(&cpu_associativity_changes_mask); | 1569 | weight = cpumask_weight(&cpu_associativity_changes_mask); |
1543 | if (!weight) | 1570 | if (!weight) |
1544 | return 0; | 1571 | return 0; |
@@ -1592,6 +1619,15 @@ int arch_update_cpu_topology(void) | |||
1592 | cpu = cpu_last_thread_sibling(cpu); | 1619 | cpu = cpu_last_thread_sibling(cpu); |
1593 | } | 1620 | } |
1594 | 1621 | ||
1622 | pr_debug("Topology update for the following CPUs:\n"); | ||
1623 | if (cpumask_weight(&updated_cpus)) { | ||
1624 | for (ud = &updates[0]; ud; ud = ud->next) { | ||
1625 | pr_debug("cpu %d moving from node %d " | ||
1626 | "to %d\n", ud->cpu, | ||
1627 | ud->old_nid, ud->new_nid); | ||
1628 | } | ||
1629 | } | ||
1630 | |||
1595 | /* | 1631 | /* |
1596 | * In cases where we have nothing to update (because the updates list | 1632 | * In cases where we have nothing to update (because the updates list |
1597 | * is too short or because the new topology is same as the old one), | 1633 | * is too short or because the new topology is same as the old one), |
@@ -1800,8 +1836,12 @@ static const struct file_operations topology_ops = { | |||
1800 | 1836 | ||
1801 | static int topology_update_init(void) | 1837 | static int topology_update_init(void) |
1802 | { | 1838 | { |
1803 | start_topology_update(); | 1839 | /* Do not poll for changes if disabled at boot */ |
1804 | proc_create("powerpc/topology_updates", 0644, NULL, &topology_ops); | 1840 | if (topology_updates_enabled) |
1841 | start_topology_update(); | ||
1842 | |||
1843 | if (!proc_create("powerpc/topology_updates", 0644, NULL, &topology_ops)) | ||
1844 | return -ENOMEM; | ||
1805 | 1845 | ||
1806 | return 0; | 1846 | return 0; |
1807 | } | 1847 | } |