[PATCH v1 3/9]powerpc/powernv: Add cpu hotplug support
Madhavan Srinivasan
maddy at linux.vnet.ibm.com
Wed Jun 3 01:59:32 AEST 2015
Patch adds cpu hotplug support. First online cpu in a node is picked as
designated thread to read the Nest pmu counter data, and at the time of
hotplug, next online cpu from the same node is picked up.
Cc: Michael Ellerman <mpe at ellerman.id.au>
Cc: Benjamin Herrenschmidt <benh at kernel.crashing.org>
Cc: Paul Mackerras <paulus at samba.org>
Cc: Sukadev Bhattiprolu <sukadev at linux.vnet.ibm.com>
Cc: Anshuman Khandual <khandual at linux.vnet.ibm.com>
Cc: Stephane Eranian <eranian at google.com>
Cc: Preeti U Murthy <preeti at linux.vnet.ibm.com>
Cc: Ingo Molnar <mingo at kernel.org>
Cc: Peter Zijlstra <peterz at infradead.org>
Signed-off-by: Madhavan Srinivasan <maddy at linux.vnet.ibm.com>
---
arch/powerpc/perf/nest-pmu.c | 84 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 84 insertions(+)
diff --git a/arch/powerpc/perf/nest-pmu.c b/arch/powerpc/perf/nest-pmu.c
index d4413bb..3e7010e 100644
--- a/arch/powerpc/perf/nest-pmu.c
+++ b/arch/powerpc/perf/nest-pmu.c
@@ -30,6 +30,86 @@ static struct attribute_group cpumask_nest_pmu_attr_group = {
.attrs = cpumask_nest_pmu_attrs,
};
+static void nest_init(void *dummy)
+{
+ opal_nest_ima_control(P8_NEST_ENGINE_START);
+}
+
+static void nest_change_cpu_context(int old_cpu, int new_cpu)
+{
+ int i;
+
+ for (i=0; per_nestpmu_arr[i] != NULL; i++)
+ perf_pmu_migrate_context(&per_nestpmu_arr[i]->pmu,
+ old_cpu, new_cpu);
+ return;
+}
+
+static void nest_exit_cpu(int cpu)
+{
+ int i, nid, target = -1;
+ const struct cpumask *l_cpumask;
+ int src_chipid;
+
+ if (!cpumask_test_and_clear_cpu(cpu, &cpu_mask_nest_pmu))
+ return;
+
+ nid = cpu_to_node(cpu);
+ src_chipid = topology_physical_package_id(cpu);
+ l_cpumask = cpumask_of_node(nid);
+ for_each_cpu(i, l_cpumask) {
+ if (i == cpu)
+ continue;
+ if (src_chipid == topology_physical_package_id(i)) {
+ target = i;
+ break;
+ }
+ }
+
+ cpumask_set_cpu(target, &cpu_mask_nest_pmu);
+ nest_change_cpu_context (cpu, target);
+ return;
+}
+
+static void nest_init_cpu(int cpu)
+{
+ int i, src_chipid;
+
+ src_chipid = topology_physical_package_id(cpu);
+ for_each_cpu(i, &cpu_mask_nest_pmu)
+ if (src_chipid == topology_physical_package_id(i))
+ return;
+
+ cpumask_set_cpu(cpu, &cpu_mask_nest_pmu);
+ nest_change_cpu_context ( -1, cpu);
+ return;
+}
+
+static int nest_cpu_notifier(struct notifier_block *self,
+ unsigned long action, void *hcpu)
+{
+ unsigned int cpu = (long)hcpu;
+
+ switch (action & ~CPU_TASKS_FROZEN) {
+ case CPU_DOWN_FAILED:
+ case CPU_STARTING:
+ nest_init_cpu(cpu);
+ break;
+ case CPU_DOWN_PREPARE:
+ nest_exit_cpu(cpu);
+ break;
+ default:
+ break;
+ }
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block nest_cpu_nb = {
+ .notifier_call = nest_cpu_notifier,
+ .priority = CPU_PRI_PERF + 1,
+}
+
void cpumask_chip(void)
{
const struct cpumask *l_cpumask;
@@ -47,6 +127,10 @@ void cpumask_chip(void)
cpumask_set_cpu(cpu, &cpu_mask_nest_pmu);
}
+ on_each_cpu_mask(&cpu_mask_nest_pmu, (smp_call_func_t)nest_init, NULL, 1);
+
+ __register_cpu_notifier(&nest_cpu_nb);
+
cpu_notifier_register_done();
}
--
1.9.1
More information about the Linuxppc-dev
mailing list