powerpc/hotplug: Improve responsiveness of hotplug change
authorMichael Bringmann <mwb@linux.vnet.ibm.com>
Fri, 8 Sep 2017 20:47:47 +0000 (15:47 -0500)
committerMichael Ellerman <mpe@ellerman.id.au>
Mon, 16 Oct 2017 12:12:04 +0000 (23:12 +1100)
powerpc/hotplug: On Power systems with shared configurations of CPUs
and memory, there are some issues with the association of additional
CPUs and memory to nodes when hot-adding resources.  During hotplug
CPU operations, this patch resets the timer on topology update work
function to a small value to better ensure that the CPU topology is
detected and configured sooner.

Signed-off-by: Michael Bringmann <mwb@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
arch/powerpc/include/asm/topology.h
arch/powerpc/mm/numa.c
arch/powerpc/platforms/pseries/hotplug-cpu.c

index 2d84bca8d053e9ae6f2ca5a0ac323cb4cc10caf8..34da2c5fd1df038954de777b48756c7b903b7b3b 100644 (file)
@@ -96,6 +96,14 @@ static inline int prrn_is_enabled(void)
 }
 #endif /* CONFIG_NUMA && CONFIG_PPC_SPLPAR */
 
+#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_NEED_MULTIPLE_NODES)
+#if defined(CONFIG_PPC_SPLPAR)
+extern int timed_topology_update(int nsecs);
+#else
+#define        timed_topology_update(nsecs)
+#endif /* CONFIG_PPC_SPLPAR */
+#endif /* CONFIG_HOTPLUG_CPU || CONFIG_NEED_MULTIPLE_NODES */
+
 #include <asm-generic/topology.h>
 
 #ifdef CONFIG_SMP
index 5f5ff46ae76dc91cc91b9c3f62862a39c6ccde8c..32f5f8db46ec11f5072ead290d16b5e6aad1b251 100644 (file)
@@ -1148,14 +1148,34 @@ struct topology_update_data {
        int new_nid;
 };
 
+#define TOPOLOGY_DEF_TIMER_SECS        60
+
 static u8 vphn_cpu_change_counts[NR_CPUS][MAX_DISTANCE_REF_POINTS];
 static cpumask_t cpu_associativity_changes_mask;
 static int vphn_enabled;
 static int prrn_enabled;
 static void reset_topology_timer(void);
+static int topology_timer_secs = 1;
 static int topology_inited;
 static int topology_update_needed;
 
+/*
+ * Change polling interval for associativity changes.
+ */
+int timed_topology_update(int nsecs)
+{
+       if (vphn_enabled) {
+               if (nsecs > 0)
+                       topology_timer_secs = nsecs;
+               else
+                       topology_timer_secs = TOPOLOGY_DEF_TIMER_SECS;
+
+               reset_topology_timer();
+       }
+
+       return 0;
+}
+
 /*
  * Store the current values of the associativity change counters in the
  * hypervisor.
@@ -1251,6 +1271,7 @@ static long vphn_get_associativity(unsigned long cpu,
                break;
        case H_SUCCESS:
                dbg("VPHN hcall succeeded. Reset polling...\n");
+               timed_topology_update(0);
                break;
        }
 
@@ -1481,7 +1502,7 @@ static struct timer_list topology_timer =
 static void reset_topology_timer(void)
 {
        topology_timer.data = 0;
-       topology_timer.expires = jiffies + 60 * HZ;
+       topology_timer.expires = jiffies + topology_timer_secs * HZ;
        mod_timer(&topology_timer, topology_timer.expires);
 }
 
index fadb95efbb9e1856ed8a7182cf870dcf3a5f5331..a7d14aa7bb7c5c2d67fdd0e522d271f71f05a738 100644 (file)
@@ -363,6 +363,7 @@ static int dlpar_online_cpu(struct device_node *dn)
                        BUG_ON(get_cpu_current_state(cpu)
                                        != CPU_STATE_OFFLINE);
                        cpu_maps_update_done();
+                       timed_topology_update(1);
                        rc = device_online(get_cpu_device(cpu));
                        if (rc)
                                goto out;
@@ -533,6 +534,7 @@ static int dlpar_offline_cpu(struct device_node *dn)
                                set_preferred_offline_state(cpu,
                                                            CPU_STATE_OFFLINE);
                                cpu_maps_update_done();
+                               timed_topology_update(1);
                                rc = device_offline(get_cpu_device(cpu));
                                if (rc)
                                        goto out;