From 7122beeee7bc1757682049780179d7c216dd1c83 Mon Sep 17 00:00:00 2001 From: Vaidyanathan Srinivasan Date: Fri, 22 Mar 2013 05:49:35 +0000 Subject: powerpc: fix numa distance for form0 device tree The following commit breaks numa distance setup for old powerpc systems that use form0 encoding in device tree. commit 41eab6f88f24124df89e38067b3766b7bef06ddb powerpc/numa: Use form 1 affinity to setup node distance Device tree node /rtas/ibm,associativity-reference-points would index into /cpus/PowerPCxxxx/ibm,associativity based on form0 or form1 encoding detected by ibm,architecture-vec-5 property. All modern systems use form1 and current kernel code is correct. However, on older systems with form0 encoding, the numa distance will get hard coded as LOCAL_DISTANCE for all nodes. This causes task scheduling anomaly since scheduler will skip building numa level domain (topmost domain with all cpus) if all numa distances are same. (value of 'level' in sched_init_numa() will remain 0) Prior to the above commit: ((from) == (to) ? LOCAL_DISTANCE : REMOTE_DISTANCE) Restoring compatible behavior with this patch for old powerpc systems with device tree where numa distance are encoded as form0. Signed-off-by: Vaidyanathan Srinivasan Signed-off-by: Michael Ellerman --- arch/powerpc/mm/numa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/powerpc/mm/numa.c') diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index bba87ca2b4d7..6a252c468d68 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -201,7 +201,7 @@ int __node_distance(int a, int b) int distance = LOCAL_DISTANCE; if (!form1_affinity) - return distance; + return ((a == b) ? LOCAL_DISTANCE : REMOTE_DISTANCE); for (i = 0; i < distance_ref_points_depth; i++) { if (distance_lookup_table[a][i] == distance_lookup_table[b][i]) -- cgit v1.2.1 From 55671f3cc29c31681278b7782de4f6a4edb97a7e Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Mon, 25 Mar 2013 18:44:44 +0000 Subject: powerpc: fix annotation of fake_numa_create_new_node() This function has always been marked as __cpuinit, but is only called from functions marked as __init and references an __initdata variable. So change its annotation to __init. Fixes this build warning: WARNING: arch/powerpc/mm/built-in.o(.cpuinit.text+0x86): Section mismatch in reference from the function .fake_numa_create_new_node() to the variable .init.data:cmdline The function __cpuinit .fake_numa_create_new_node() references a variable __initdata cmdline. If cmdline is only used by .fake_numa_create_new_node then annotate cmdline with a matching annotation. Signed-off-by: Stephen Rothwell Signed-off-by: Michael Ellerman --- arch/powerpc/mm/numa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/powerpc/mm/numa.c') diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index 6a252c468d68..7218e9d3a0bc 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -79,7 +79,7 @@ static void __init setup_node_to_cpumask_map(void) dbg("Node to cpumask map for %d nodes\n", nr_node_ids); } -static int __cpuinit fake_numa_create_new_node(unsigned long end_pfn, +static int __init fake_numa_create_new_node(unsigned long end_pfn, unsigned int *nid) { unsigned long long mem; -- cgit v1.2.1 From 8002b0c54b16931ad71771e6c97e46aca1be4456 Mon Sep 17 00:00:00 2001 From: Nathan Fontenot Date: Wed, 24 Apr 2013 05:58:23 +0000 Subject: powerpc/pseries: Update numa.c to use updated firmware_has_feature() Update the numa code to use the updated firmware_has_feature() when checking for type 1 affinity. Signed-off-by: Nathan Fontenot Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/mm/numa.c | 22 +++------------------- 1 file changed, 3 insertions(+), 19 deletions(-) (limited to 'arch/powerpc/mm/numa.c') diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index 7218e9d3a0bc..4cee83592b0c 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -291,9 +291,7 @@ EXPORT_SYMBOL_GPL(of_node_to_nid); static int __init find_min_common_depth(void) { int depth; - struct device_node *chosen; struct device_node *root; - const char *vec5; if (firmware_has_feature(FW_FEATURE_OPAL)) root = of_find_node_by_path("/ibm,opal"); @@ -325,24 +323,10 @@ static int __init find_min_common_depth(void) distance_ref_points_depth /= sizeof(int); -#define VEC5_AFFINITY_BYTE 5 -#define VEC5_AFFINITY 0x80 - - if (firmware_has_feature(FW_FEATURE_OPAL)) + if (firmware_has_feature(FW_FEATURE_OPAL) || + firmware_has_feature(FW_FEATURE_TYPE1_AFFINITY)) { + dbg("Using form 1 affinity\n"); form1_affinity = 1; - else { - chosen = of_find_node_by_path("/chosen"); - if (chosen) { - vec5 = of_get_property(chosen, - "ibm,architecture-vec-5", NULL); - if (vec5 && (vec5[VEC5_AFFINITY_BYTE] & - VEC5_AFFINITY)) { - dbg("Using form 1 affinity\n"); - form1_affinity = 1; - } - - of_node_put(chosen); - } } if (form1_affinity) { -- cgit v1.2.1 From 5d88aa85c00bb4026dd986430dc496effc637d42 Mon Sep 17 00:00:00 2001 From: Jesse Larrew Date: Wed, 24 Apr 2013 06:00:35 +0000 Subject: powerpc/pseries: Update CPU maps when device tree is updated Platform events such as partition migration or the new PRRN firmware feature can cause the NUMA characteristics of a CPU to change, and these changes will be reflected in the device tree nodes for the affected CPUs. This patch registers a handler for Open Firmware device tree updates and reconfigures the CPU and node maps whenever the associativity changes. Currently, this is accomplished by marking the affected CPUs in the cpu_associativity_changes_mask and allowing arch_update_cpu_topology() to retrieve the new associativity information using hcall_vphn(). Protecting the NUMA cpu maps from concurrent access during an update operation will be addressed in a subsequent patch in this series. Signed-off-by: Nathan Fontenot Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/mm/numa.c | 99 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 75 insertions(+), 24 deletions(-) (limited to 'arch/powerpc/mm/numa.c') diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index 4cee83592b0c..42f50c352242 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -1257,7 +1257,8 @@ u64 memory_hotplug_max(void) static u8 vphn_cpu_change_counts[NR_CPUS][MAX_DISTANCE_REF_POINTS]; static cpumask_t cpu_associativity_changes_mask; static int vphn_enabled; -static void set_topology_timer(void); +static int prrn_enabled; +static void reset_topology_timer(void); /* * Store the current values of the associativity change counters in the @@ -1293,11 +1294,9 @@ static void setup_cpu_associativity_change_counters(void) */ static int update_cpu_associativity_changes_mask(void) { - int cpu, nr_cpus = 0; + int cpu; cpumask_t *changes = &cpu_associativity_changes_mask; - cpumask_clear(changes); - for_each_possible_cpu(cpu) { int i, changed = 0; u8 *counts = vphn_cpu_change_counts[cpu]; @@ -1311,11 +1310,10 @@ static int update_cpu_associativity_changes_mask(void) } if (changed) { cpumask_set_cpu(cpu, changes); - nr_cpus++; } } - return nr_cpus; + return cpumask_weight(changes); } /* @@ -1416,7 +1414,7 @@ int arch_update_cpu_topology(void) unsigned int associativity[VPHN_ASSOC_BUFSIZE] = {0}; struct device *dev; - for_each_cpu(cpu,&cpu_associativity_changes_mask) { + for_each_cpu(cpu, &cpu_associativity_changes_mask) { vphn_get_associativity(cpu, associativity); nid = associativity_to_nid(associativity); @@ -1438,6 +1436,7 @@ int arch_update_cpu_topology(void) dev = get_cpu_device(cpu); if (dev) kobject_uevent(&dev->kobj, KOBJ_CHANGE); + cpumask_clear_cpu(cpu, &cpu_associativity_changes_mask); changed = 1; } @@ -1457,37 +1456,80 @@ void topology_schedule_update(void) static void topology_timer_fn(unsigned long ignored) { - if (!vphn_enabled) - return; - if (update_cpu_associativity_changes_mask() > 0) + if (prrn_enabled && cpumask_weight(&cpu_associativity_changes_mask)) topology_schedule_update(); - set_topology_timer(); + else if (vphn_enabled) { + if (update_cpu_associativity_changes_mask() > 0) + topology_schedule_update(); + reset_topology_timer(); + } } static struct timer_list topology_timer = TIMER_INITIALIZER(topology_timer_fn, 0, 0); -static void set_topology_timer(void) +static void reset_topology_timer(void) { topology_timer.data = 0; topology_timer.expires = jiffies + 60 * HZ; - add_timer(&topology_timer); + mod_timer(&topology_timer, topology_timer.expires); +} + +static void stage_topology_update(int core_id) +{ + cpumask_or(&cpu_associativity_changes_mask, + &cpu_associativity_changes_mask, cpu_sibling_mask(core_id)); + reset_topology_timer(); +} + +static int dt_update_callback(struct notifier_block *nb, + unsigned long action, void *data) +{ + struct of_prop_reconfig *update; + int rc = NOTIFY_DONE; + + switch (action) { + case OF_RECONFIG_ADD_PROPERTY: + case OF_RECONFIG_UPDATE_PROPERTY: + update = (struct of_prop_reconfig *)data; + if (!of_prop_cmp(update->dn->type, "cpu")) { + u32 core_id; + of_property_read_u32(update->dn, "reg", &core_id); + stage_topology_update(core_id); + rc = NOTIFY_OK; + } + break; + } + + return rc; } +static struct notifier_block dt_update_nb = { + .notifier_call = dt_update_callback, +}; + /* - * Start polling for VPHN associativity changes. + * Start polling for associativity changes. */ int start_topology_update(void) { int rc = 0; - /* Disabled until races with load balancing are fixed */ - if (0 && firmware_has_feature(FW_FEATURE_VPHN) && - get_lppaca()->shared_proc) { - vphn_enabled = 1; - setup_cpu_associativity_change_counters(); - init_timer_deferrable(&topology_timer); - set_topology_timer(); - rc = 1; + if (firmware_has_feature(FW_FEATURE_PRRN)) { + if (!prrn_enabled) { + prrn_enabled = 1; + vphn_enabled = 0; + rc = of_reconfig_notifier_register(&dt_update_nb); + } + } else if (0 && firmware_has_feature(FW_FEATURE_VPHN) && + get_lppaca()->shared_proc) { + /* Disabled until races with load balancing are fixed */ + if (!vphn_enabled) { + prrn_enabled = 0; + vphn_enabled = 1; + setup_cpu_associativity_change_counters(); + init_timer_deferrable(&topology_timer); + reset_topology_timer(); + } } return rc; @@ -1499,7 +1541,16 @@ __initcall(start_topology_update); */ int stop_topology_update(void) { - vphn_enabled = 0; - return del_timer_sync(&topology_timer); + int rc = 0; + + if (prrn_enabled) { + prrn_enabled = 0; + rc = of_reconfig_notifier_unregister(&dt_update_nb); + } else if (vphn_enabled) { + vphn_enabled = 0; + rc = del_timer_sync(&topology_timer); + } + + return rc; } #endif /* CONFIG_PPC_SPLPAR */ -- cgit v1.2.1 From 30c05350c39de6c17132cfee649518b842d89dd5 Mon Sep 17 00:00:00 2001 From: Nathan Fontenot Date: Wed, 24 Apr 2013 06:02:13 +0000 Subject: powerpc/pseries: Use stop machine to update cpu maps The new PRRN firmware feature allows CPU and memory resources to be transparently reassigned across NUMA boundaries. When this happens, the kernel must update the node maps to reflect the new affinity information. Although the NUMA maps can be protected by locking primitives during the update itself, this is insufficient to prevent concurrent accesses to these structures. Since cpumask_of_node() hands out a pointer to these structures, they can still be modified outside of the lock. Furthermore, tracking down each usage of these pointers and adding locks would be quite invasive and difficult to maintain. The approach used is to make a list of affected cpus and call stop_machine to have the update routine run on each of the affected cpus allowing them to update themselves. Each cpu finds itself in the list of cpus and makes the appropriate updates. We need to have each cpu do this for themselves to handle calls to vdso_getcpu_init() added in a subsequent patch. Situations like these are best handled using stop_machine(). Since the NUMA affinity updates are exceptionally rare events, this approach has the benefit of not adding any overhead while accessing the NUMA maps during normal operation. Signed-off-by: Nathan Fontenot Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/mm/numa.c | 84 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 65 insertions(+), 19 deletions(-) (limited to 'arch/powerpc/mm/numa.c') diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index 42f50c352242..e8d1aeb6348c 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -1254,6 +1255,13 @@ u64 memory_hotplug_max(void) /* Virtual Processor Home Node (VPHN) support */ #ifdef CONFIG_PPC_SPLPAR +struct topology_update_data { + struct topology_update_data *next; + unsigned int cpu; + int old_nid; + int new_nid; +}; + static u8 vphn_cpu_change_counts[NR_CPUS][MAX_DISTANCE_REF_POINTS]; static cpumask_t cpu_associativity_changes_mask; static int vphn_enabled; @@ -1404,42 +1412,80 @@ static long vphn_get_associativity(unsigned long cpu, return rc; } +/* + * Update the CPU maps and sysfs entries for a single CPU when its NUMA + * characteristics change. This function doesn't perform any locking and is + * only safe to call from stop_machine(). + */ +static int update_cpu_topology(void *data) +{ + struct topology_update_data *update; + unsigned long cpu; + + if (!data) + return -EINVAL; + + cpu = get_cpu(); + + for (update = data; update; update = update->next) { + if (cpu != update->cpu) + continue; + + unregister_cpu_under_node(update->cpu, update->old_nid); + unmap_cpu_from_node(update->cpu); + map_cpu_to_node(update->cpu, update->new_nid); + register_cpu_under_node(update->cpu, update->new_nid); + } + + return 0; +} + /* * Update the node maps and sysfs entries for each cpu whose home node * has changed. Returns 1 when the topology has changed, and 0 otherwise. */ int arch_update_cpu_topology(void) { - int cpu, nid, old_nid, changed = 0; + unsigned int cpu, changed = 0; + struct topology_update_data *updates, *ud; unsigned int associativity[VPHN_ASSOC_BUFSIZE] = {0}; struct device *dev; + int weight, i = 0; + + weight = cpumask_weight(&cpu_associativity_changes_mask); + if (!weight) + return 0; + + updates = kzalloc(weight * (sizeof(*updates)), GFP_KERNEL); + if (!updates) + return 0; for_each_cpu(cpu, &cpu_associativity_changes_mask) { + ud = &updates[i++]; + ud->cpu = cpu; vphn_get_associativity(cpu, associativity); - nid = associativity_to_nid(associativity); + ud->new_nid = associativity_to_nid(associativity); - if (nid < 0 || !node_online(nid)) - nid = first_online_node; + if (ud->new_nid < 0 || !node_online(ud->new_nid)) + ud->new_nid = first_online_node; - old_nid = numa_cpu_lookup_table[cpu]; + ud->old_nid = numa_cpu_lookup_table[cpu]; - /* Disable hotplug while we update the cpu - * masks and sysfs. - */ - get_online_cpus(); - unregister_cpu_under_node(cpu, old_nid); - unmap_cpu_from_node(cpu); - map_cpu_to_node(cpu, nid); - register_cpu_under_node(cpu, nid); - put_online_cpus(); - - dev = get_cpu_device(cpu); + if (i < weight) + ud->next = &updates[i]; + } + + stop_machine(update_cpu_topology, &updates[0], cpu_online_mask); + + for (ud = &updates[0]; ud; ud = ud->next) { + dev = get_cpu_device(ud->cpu); if (dev) kobject_uevent(&dev->kobj, KOBJ_CHANGE); - cpumask_clear_cpu(cpu, &cpu_associativity_changes_mask); + cpumask_clear_cpu(ud->cpu, &cpu_associativity_changes_mask); changed = 1; } + kfree(updates); return changed; } @@ -1488,10 +1534,10 @@ static int dt_update_callback(struct notifier_block *nb, int rc = NOTIFY_DONE; switch (action) { - case OF_RECONFIG_ADD_PROPERTY: case OF_RECONFIG_UPDATE_PROPERTY: update = (struct of_prop_reconfig *)data; - if (!of_prop_cmp(update->dn->type, "cpu")) { + if (!of_prop_cmp(update->dn->type, "cpu") && + !of_prop_cmp(update->prop->name, "ibm,associativity")) { u32 core_id; of_property_read_u32(update->dn, "reg", &core_id); stage_topology_update(core_id); -- cgit v1.2.1 From 176bbf142461a000901df4ec6b8fac04969dd4e5 Mon Sep 17 00:00:00 2001 From: Jesse Larrew Date: Wed, 24 Apr 2013 06:03:48 +0000 Subject: powerpc/pseries: Update NUMA VDSO information when updating CPU maps The following patch adds vdso_getcpu_init(), which stores the NUMA node for a cpu in SPRG3: Commit 18ad51dd34 ("powerpc: Add VDSO version of getcpu") adds vdso_getcpu_init(), which stores the NUMA node for a cpu in SPRG3. This patch ensures that this information is also updated when the NUMA affinity of a cpu changes. Signed-off-by: Nathan Fontenot Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/mm/numa.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'arch/powerpc/mm/numa.c') diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index e8d1aeb6348c..f298a7d4b2ce 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -30,6 +30,7 @@ #include #include #include +#include static int numa_enabled = 1; @@ -1434,6 +1435,7 @@ static int update_cpu_topology(void *data) unregister_cpu_under_node(update->cpu, update->old_nid); unmap_cpu_from_node(update->cpu); map_cpu_to_node(update->cpu, update->new_nid); + vdso_getcpu_init(); register_cpu_under_node(update->cpu, update->new_nid); } @@ -1449,6 +1451,7 @@ int arch_update_cpu_topology(void) unsigned int cpu, changed = 0; struct topology_update_data *updates, *ud; unsigned int associativity[VPHN_ASSOC_BUFSIZE] = {0}; + cpumask_t updated_cpus; struct device *dev; int weight, i = 0; @@ -1460,6 +1463,8 @@ int arch_update_cpu_topology(void) if (!updates) return 0; + cpumask_clear(&updated_cpus); + for_each_cpu(cpu, &cpu_associativity_changes_mask) { ud = &updates[i++]; ud->cpu = cpu; @@ -1470,12 +1475,13 @@ int arch_update_cpu_topology(void) ud->new_nid = first_online_node; ud->old_nid = numa_cpu_lookup_table[cpu]; + cpumask_set_cpu(cpu, &updated_cpus); if (i < weight) ud->next = &updates[i]; } - stop_machine(update_cpu_topology, &updates[0], cpu_online_mask); + stop_machine(update_cpu_topology, &updates[0], &updated_cpus); for (ud = &updates[0]; ud; ud = ud->next) { dev = get_cpu_device(ud->cpu); -- cgit v1.2.1 From b7abef045fdacdb40eef7f22ebbb566d63f9f240 Mon Sep 17 00:00:00 2001 From: Jesse Larrew Date: Wed, 24 Apr 2013 06:05:22 +0000 Subject: powerpc/pseries: RE-enable Virtual Processor Home Node updating The new PRRN firmware feature provides a more convenient and event-driven interface than VPHN for notifying Linux of changes to the NUMA affinity of platform resources. However, for practical reasons, it may not be feasible for some customers to update to the latest firmware. For these customers, the VPHN feature supported on previous firmware versions may still be the best option. The VPHN feature was previously disabled due to races with the load balancing code when accessing the NUMA cpu maps, but the new stop_machine() approach protects the NUMA cpu maps from these concurrent accesses. It should be safe to re-enable this feature now. Signed-off-by: Nathan Fontenot Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/mm/numa.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'arch/powerpc/mm/numa.c') diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index f298a7d4b2ce..908699fb61c9 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -1572,9 +1572,8 @@ int start_topology_update(void) vphn_enabled = 0; rc = of_reconfig_notifier_register(&dt_update_nb); } - } else if (0 && firmware_has_feature(FW_FEATURE_VPHN) && + } else if (firmware_has_feature(FW_FEATURE_VPHN) && get_lppaca()->shared_proc) { - /* Disabled until races with load balancing are fixed */ if (!vphn_enabled) { prrn_enabled = 0; vphn_enabled = 1; -- cgit v1.2.1 From e04fa61214a3e586282490af7e1b023522c1472a Mon Sep 17 00:00:00 2001 From: Nathan Fontenot Date: Wed, 24 Apr 2013 06:07:39 +0000 Subject: powerpc/pseries: Add /proc interface to control topology updates There are instances in which we do not want topology updates to occur. In order to allow this a /proc interface (/proc/powerpc/topology_updates) is introduced so that topology updates can be enabled and disabled. This patch also adds a prrn_is_enabled() call so that PRRN events are handled in the kernel only if topology updating is enabled. Signed-off-by: Nathan Fontenot Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/mm/numa.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) (limited to 'arch/powerpc/mm/numa.c') diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index 908699fb61c9..2d13f90476bd 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -23,6 +23,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -1585,7 +1588,6 @@ int start_topology_update(void) return rc; } -__initcall(start_topology_update); /* * Disable polling for VPHN associativity changes. @@ -1604,4 +1606,62 @@ int stop_topology_update(void) return rc; } + +int prrn_is_enabled(void) +{ + return prrn_enabled; +} + +static int topology_read(struct seq_file *file, void *v) +{ + if (vphn_enabled || prrn_enabled) + seq_puts(file, "on\n"); + else + seq_puts(file, "off\n"); + + return 0; +} + +static int topology_open(struct inode *inode, struct file *file) +{ + return single_open(file, topology_read, NULL); +} + +static ssize_t topology_write(struct file *file, const char __user *buf, + size_t count, loff_t *off) +{ + char kbuf[4]; /* "on" or "off" plus null. */ + int read_len; + + read_len = count < 3 ? count : 3; + if (copy_from_user(kbuf, buf, read_len)) + return -EINVAL; + + kbuf[read_len] = '\0'; + + if (!strncmp(kbuf, "on", 2)) + start_topology_update(); + else if (!strncmp(kbuf, "off", 3)) + stop_topology_update(); + else + return -EINVAL; + + return count; +} + +static const struct file_operations topology_ops = { + .read = seq_read, + .write = topology_write, + .open = topology_open, + .release = single_release +}; + +static int topology_update_init(void) +{ + start_topology_update(); + proc_create("powerpc/topology_updates", 644, NULL, &topology_ops); + + return 0; +} +device_initcall(topology_update_init); #endif /* CONFIG_PPC_SPLPAR */ -- cgit v1.2.1 From 9f3a90e89d2503ce4c40159526e446f1fca92f10 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Sun, 28 Apr 2013 18:04:33 +0000 Subject: powerpc: Fix build failure after merge of the cgroup tree After merging the cgroup tree, today's linux-next build (powerpc ppc64_defconfig) failed like this: arch/powerpc/mm/numa.c: In function 'arch_update_cpu_topology': arch/powerpc/mm/numa.c:1465:2: error: implicit declaration of function 'kzalloc' [-Werror=implicit-function-declaration] arch/powerpc/mm/numa.c:1465:10: error: assignment makes pointer from integer without a cast [-Werror] arch/powerpc/mm/numa.c:1497:2: error: implicit declaration of function 'kfree' [-Werror=implicit-function-declaration] Caused by commit 30c05350c39d ("powerpc/pseries: Use stop machine to update cpu maps") from the powerpc tree interacting with (probably) commit ff794dea52ea ("cpuset: remove include of cgroup.h from cpuset.h") from the cgroup tree. Removing includes from header files is fraught with danger ... The former should have added an include of linux/slab.h to arch/powerpc/mm/numa.c. I have added the following merge fix patch for today (but it should be applied to the powerpc tree ASAP). From: Stephen Rothwell Date: Mon, 29 Apr 2013 14:01:44 +1000 Subject: [PATCH] powerpc: numa.c: using kzalloc/kfree requires including slab.h fixes these build errors: arch/powerpc/mm/numa.c: In function 'arch_update_cpu_topology': arch/powerpc/mm/numa.c:1465:2: error: implicit declaration of function 'kzalloc' [-Werror=implicit-function-declaration] arch/powerpc/mm/numa.c:1465:10: error: assignment makes pointer from integer without a cast [-Werror] arch/powerpc/mm/numa.c:1497:2: error: implicit declaration of function 'kfree' [-Werror=implicit-function-declaration] Signed-off-by: Stephen Rothwell Acked-by: Tejun Heo Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/mm/numa.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/powerpc/mm/numa.c') diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index 2d13f90476bd..490e39c8d8f6 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include -- cgit v1.2.1 From 601abdc3b4773afb9a80afc9c4c024724b7c5f4e Mon Sep 17 00:00:00 2001 From: Nathan Fontenot Date: Mon, 29 Apr 2013 03:45:36 +0000 Subject: powerpc/pseries: Correct builds break when CONFIG_SMP not defined MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Correct build failure for powerpc/pseries builds with CONFIG_SMP not defined. The function cpu_sibling_mask has no meaning (or definition) when CONFIG_SMP is not defined. Additionally, the updating of NUMA affinity for a CPU in a UP system doesn't really make sense. This patch ifdef's out the code making the affinity updates for PRRN events to fix the following build break. arch/powerpc/mm/numa.c: In function ‘stage_topology_update’: arch/powerpc/mm/numa.c:1535: error: implicit declaration of function ‘cpu_sibling_mask’ arch/powerpc/mm/numa.c:1535: warning: passing argument 3 of ‘cpumask_or’ makes pointer from integer without a cast make[1]: *** [arch/powerpc/mm/numa.o] Error 1 Signed-off-by: Nathan Fontenot Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/mm/numa.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'arch/powerpc/mm/numa.c') diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index 490e39c8d8f6..c3bd046f801a 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -1530,6 +1530,8 @@ static void reset_topology_timer(void) mod_timer(&topology_timer, topology_timer.expires); } +#ifdef CONFIG_SMP + static void stage_topology_update(int core_id) { cpumask_or(&cpu_associativity_changes_mask, @@ -1563,6 +1565,8 @@ static struct notifier_block dt_update_nb = { .notifier_call = dt_update_callback, }; +#endif + /* * Start polling for associativity changes. */ @@ -1574,7 +1578,9 @@ int start_topology_update(void) if (!prrn_enabled) { prrn_enabled = 1; vphn_enabled = 0; +#ifdef CONFIG_SMP rc = of_reconfig_notifier_register(&dt_update_nb); +#endif } } else if (firmware_has_feature(FW_FEATURE_VPHN) && get_lppaca()->shared_proc) { @@ -1599,7 +1605,9 @@ int stop_topology_update(void) if (prrn_enabled) { prrn_enabled = 0; +#ifdef CONFIG_SMP rc = of_reconfig_notifier_unregister(&dt_update_nb); +#endif } else if (vphn_enabled) { vphn_enabled = 0; rc = del_timer_sync(&topology_timer); -- cgit v1.2.1