Re: [PATCH] coresight: etm4x: Fix etm4_count race using atomic variable

From: Sai Prakash Ranjan
Date: Mon Jul 27 2020 - 04:56:14 EST


On 2020-07-27 11:37, Sai Prakash Ranjan wrote:
etm4_count keeps track of number of ETMv4 registered and on some
systems, a race is observed on etm4_count variable which can
lead to multiple calls to cpuhp_setup_state_nocalls_cpuslocked().
This function internally calls cpuhp_store_callbacks() which
prevents multiple registrations of callbacks for a given state
and due to this race, it returns -EBUSY leading to ETM probe
failures like below.

coresight-etm4x: probe of 7040000.etm failed with error -16

This race can easily be triggered with async probe by setting
probe type as PROBE_PREFER_ASYNCHRONOUS and with ETM power
management property "arm,coresight-loses-context-with-cpu".

Prevent this race by converting etm4_count variable to atomic.

Fixes: 9b6a3f3633a5 ("coresight: etmv4: Fix CPU power management setup
in probe() function")
Fixes: 58eb457be028 ("hwtracing/coresight-etm4x: Convert to hotplug
state machine")
Suggested-by: Mike Leach <mike.leach@xxxxxxxxxx>
(Mike: Rootcause and context for commit message)
Signed-off-by: Sai Prakash Ranjan <saiprakash.ranjan@xxxxxxxxxxxxxx>
---
drivers/hwtracing/coresight/coresight-etm4x.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c
b/drivers/hwtracing/coresight/coresight-etm4x.c
index 6d7d2169bfb2..f256ea744c51 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x.c
@@ -49,7 +49,7 @@ MODULE_PARM_DESC(pm_save_enable,
"Save/restore state on power down: 1 = never, 2 = self-hosted");

/* The number of ETMv4 currently registered */
-static int etm4_count;
+static atomic_t etm4_count;
static struct etmv4_drvdata *etmdrvdata[NR_CPUS];
static void etm4_set_default_config(struct etmv4_config *config);
static int etm4_set_event_filters(struct etmv4_drvdata *drvdata,
@@ -1403,7 +1403,7 @@ static int etm4_pm_setup_cpuslocked(void)
{
int ret;

- if (etm4_count++)
+ if (atomic_inc_return(&etm4_count))
return 0;


Sorry, I messed up here, will send a next version fixing this.

Thanks,
Sai

--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation