aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/mm/numa.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/mm/numa.c')
-rw-r--r--arch/powerpc/mm/numa.c84
1 files changed, 62 insertions, 22 deletions
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index 3b181b22cd46..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>
@@ -538,7 +540,7 @@ static int of_drconf_to_nid_single(struct of_drconf_cell *drmem,
538 */ 540 */
539static int numa_setup_cpu(unsigned long lcpu) 541static int numa_setup_cpu(unsigned long lcpu)
540{ 542{
541 int nid; 543 int nid = -1;
542 struct device_node *cpu; 544 struct device_node *cpu;
543 545
544 /* 546 /*
@@ -555,19 +557,21 @@ static int numa_setup_cpu(unsigned long lcpu)
555 557
556 if (!cpu) { 558 if (!cpu) {
557 WARN_ON(1); 559 WARN_ON(1);
558 nid = 0; 560 if (cpu_present(lcpu))
559 goto out; 561 goto out_present;
562 else
563 goto out;
560 } 564 }
561 565
562 nid = of_node_to_nid_single(cpu); 566 nid = of_node_to_nid_single(cpu);
563 567
568out_present:
564 if (nid < 0 || !node_online(nid)) 569 if (nid < 0 || !node_online(nid))
565 nid = first_online_node; 570 nid = first_online_node;
566out:
567 map_cpu_to_node(lcpu, nid);
568 571
572 map_cpu_to_node(lcpu, nid);
569 of_node_put(cpu); 573 of_node_put(cpu);
570 574out:
571 return nid; 575 return nid;
572} 576}
573 577
@@ -611,8 +615,8 @@ static int cpu_numa_callback(struct notifier_block *nfb, unsigned long action,
611 case CPU_UP_CANCELED: 615 case CPU_UP_CANCELED:
612 case CPU_UP_CANCELED_FROZEN: 616 case CPU_UP_CANCELED_FROZEN:
613 unmap_cpu_from_node(lcpu); 617 unmap_cpu_from_node(lcpu);
614 break;
615 ret = NOTIFY_OK; 618 ret = NOTIFY_OK;
619 break;
616#endif 620#endif
617 } 621 }
618 return ret; 622 return ret;
@@ -1049,7 +1053,7 @@ static void __init mark_reserved_regions_for_nid(int nid)
1049 1053
1050void __init do_init_bootmem(void) 1054void __init do_init_bootmem(void)
1051{ 1055{
1052 int nid; 1056 int nid, cpu;
1053 1057
1054 min_low_pfn = 0; 1058 min_low_pfn = 0;
1055 max_low_pfn = memblock_end_of_DRAM() >> PAGE_SHIFT; 1059 max_low_pfn = memblock_end_of_DRAM() >> PAGE_SHIFT;
@@ -1122,16 +1126,14 @@ void __init do_init_bootmem(void)
1122 1126
1123 reset_numa_cpu_lookup_table(); 1127 reset_numa_cpu_lookup_table();
1124 register_cpu_notifier(&ppc64_numa_nb); 1128 register_cpu_notifier(&ppc64_numa_nb);
1125 cpu_numa_callback(&ppc64_numa_nb, CPU_UP_PREPARE, 1129 /*
1126 (void *)(unsigned long)boot_cpuid); 1130 * We need the numa_cpu_lookup_table to be accurate for all CPUs,
1127} 1131 * even before we online them, so that we can use cpu_to_{node,mem}
1128 1132 * early in boot, cf. smp_prepare_cpus().
1129void __init paging_init(void) 1133 */
1130{ 1134 for_each_present_cpu(cpu) {
1131 unsigned long max_zone_pfns[MAX_NR_ZONES]; 1135 numa_setup_cpu((unsigned long)cpu);
1132 memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); 1136 }
1133 max_zone_pfns[ZONE_DMA] = memblock_end_of_DRAM() >> PAGE_SHIFT;
1134 free_area_init_nodes(max_zone_pfns);
1135} 1137}
1136 1138
1137static int __init early_numa(char *p) 1139static int __init early_numa(char *p)
@@ -1153,6 +1155,22 @@ static int __init early_numa(char *p)
1153} 1155}
1154early_param("numa", early_numa); 1156early_param("numa", early_numa);
1155 1157
1158static bool topology_updates_enabled = true;
1159
1160static 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}
1172early_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
1801static int topology_update_init(void) 1837static 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}