[PATCH 11/13] powerpc/powernv: Add device shutdown function for Core IMC

Madhavan Srinivasan maddy at linux.vnet.ibm.com
Thu Mar 16 18:35:05 AEDT 2017


Core In Memory Collection device programs the hardware
counters and have them runing always. But if the hardware
counter were not stopped at device shutdown (like kexec),
could lead to memory corruption. Patch to stop the hardware
counters via device "shutdown" callback.

Cc: Gautham R. Shenoy <ego at linux.vnet.ibm.com>
Cc: Balbir Singh <bsingharora at gmail.com>
Cc: Benjamin Herrenschmidt <benh at kernel.crashing.org>
Cc: Paul Mackerras <paulus at samba.org>
Cc: Anton Blanchard <anton at samba.org>
Cc: Sukadev Bhattiprolu <sukadev at linux.vnet.ibm.com>
Cc: Michael Neuling <mikey at neuling.org>
Cc: Stewart Smith <stewart at linux.vnet.ibm.com>
Cc: Daniel Axtens <dja at axtens.net>
Cc: Stephane Eranian <eranian at google.com>
Signed-off-by: Anju T Sudhakar <anju at linux.vnet.ibm.com>
Signed-off-by: Madhavan Srinivasan <maddy at linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/imc-pmu.h        |  2 ++
 arch/powerpc/perf/imc-pmu.c               | 12 +++++++++++-
 arch/powerpc/platforms/powernv/opal-imc.c |  9 +++++++++
 3 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/imc-pmu.h b/arch/powerpc/include/asm/imc-pmu.h
index 8b7141ba2f2b..00f380fce1a5 100644
--- a/arch/powerpc/include/asm/imc-pmu.h
+++ b/arch/powerpc/include/asm/imc-pmu.h
@@ -80,4 +80,6 @@ struct imc_pmu {
 #define UNKNOWN_DOMAIN		-1
 
 int imc_get_domain(struct device_node *pmu_dev);
+void core_imc_disable(void);
+void thread_imc_disable(void);
 #endif /* PPC_POWERNV_IMC_PMU_DEF_H */
diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c
index 6fc1fbc0067c..6802960db51c 100644
--- a/arch/powerpc/perf/imc-pmu.c
+++ b/arch/powerpc/perf/imc-pmu.c
@@ -317,7 +317,7 @@ static void core_imc_control_disable(void)
 	opal_core_imc_counters_control(OPAL_CORE_IMC_DISABLE, 0, 0, 0);
 }
 
-static void core_imc_disable(void)
+void core_imc_disable(void)
 {
 	on_each_cpu_mask(&core_imc_cpumask,
 			 (smp_call_func_t)core_imc_control_disable, NULL, 1);
@@ -710,6 +710,16 @@ void thread_imc_cpu_init(void)
 	on_each_cpu(thread_imc_mem_alloc, NULL, 1);
 }
 
+static void thread_imc_ldbar_disable(void *dummy)
+{
+        mtspr(SPRN_LDBAR, 0);
+}
+
+void thread_imc_disable(void)
+{
+        on_each_cpu(thread_imc_ldbar_disable, NULL, 1);
+}
+
 /*
  * init_imc_pmu : Setup the IMC pmu device in "pmu_ptr" and its events
  *                "events".
diff --git a/arch/powerpc/platforms/powernv/opal-imc.c b/arch/powerpc/platforms/powernv/opal-imc.c
index 70f4b0924fae..2bc05ba19e3b 100644
--- a/arch/powerpc/platforms/powernv/opal-imc.c
+++ b/arch/powerpc/platforms/powernv/opal-imc.c
@@ -34,6 +34,8 @@
 extern struct perchip_nest_info nest_perchip_info[IMC_MAX_CHIPS];
 extern struct imc_pmu *per_nest_pmu_arr[IMC_MAX_PMUS];
 extern struct imc_pmu *core_imc_pmu;
+extern void core_imc_disable(void);
+extern void thread_imc_disable(void);
 
 extern int init_imc_pmu(struct imc_events *events,
 			int idx, struct imc_pmu *pmu_ptr);
@@ -532,6 +534,12 @@ static int opal_imc_counters_probe(struct platform_device *pdev)
 	return -ENODEV;
 }
 
+static void opal_imc_counters_shutdown(struct platform_device *pdev)
+{
+	core_imc_disable();
+	thread_imc_disable();
+}
+
 static const struct of_device_id opal_imc_match[] = {
 	{ .compatible = IMC_DTB_COMPAT },
 	{},
@@ -543,6 +551,7 @@ static struct platform_driver opal_imc_driver = {
 		.of_match_table = opal_imc_match,
 	},
 	.probe = opal_imc_counters_probe,
+	.shutdown = opal_imc_counters_shutdown,
 };
 
 MODULE_DEVICE_TABLE(of, opal_imc_match);
-- 
2.7.4



More information about the Linuxppc-dev mailing list