summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Clark <james.clark@arm.com>2024-01-29 18:40:43 +0300
committerSuzuki K Poulose <suzuki.poulose@arm.com>2024-02-12 13:21:38 +0300
commitbcaabb95f0c9883fb8e1112bd13eaba9cfd62c15 (patch)
tree1c4f20c44753bd4254fd382dfd88eb739b474afc
parentc95c2733e5feb1f6848923f166849b2d1c7bf682 (diff)
downloadlinux-bcaabb95f0c9883fb8e1112bd13eaba9cfd62c15.tar.xz
coresight: Add helper for setting csdev->mode
Now that mode is in struct coresight_device, sets can be wrapped. This also allows us to add a sanity check that there have been no concurrent modifications of mode. Currently all usages of local_set() were inside the device's spin locks so this new warning shouldn't be triggered. coresight_take_mode() could maybe have been used in place of adding the warning, but there may be use cases which set the mode to the same mode which are valid but would fail in coresight_take_mode() because it requires the device to only be in the disabled state. Signed-off-by: James Clark <james.clark@arm.com> Link: https://lore.kernel.org/r/20240129154050.569566-13-james.clark@arm.com Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
-rw-r--r--drivers/hwtracing/coresight/coresight-etb10.c6
-rw-r--r--drivers/hwtracing/coresight/coresight-etm3x-core.c4
-rw-r--r--drivers/hwtracing/coresight/coresight-etm4x-core.c4
-rw-r--r--drivers/hwtracing/coresight/coresight-stm.c2
-rw-r--r--drivers/hwtracing/coresight/coresight-tmc-etf.c10
-rw-r--r--drivers/hwtracing/coresight/coresight-tmc-etr.c6
-rw-r--r--drivers/hwtracing/coresight/ultrasoc-smb.c6
-rw-r--r--include/linux/coresight.h16
8 files changed, 35 insertions, 19 deletions
diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c
index e3a54f7038ad..3aab182b562f 100644
--- a/drivers/hwtracing/coresight/coresight-etb10.c
+++ b/drivers/hwtracing/coresight/coresight-etb10.c
@@ -158,7 +158,7 @@ static int etb_enable_sysfs(struct coresight_device *csdev)
if (ret)
goto out;
- local_set(&csdev->mode, CS_MODE_SYSFS);
+ coresight_set_mode(csdev, CS_MODE_SYSFS);
}
csdev->refcnt++;
@@ -214,7 +214,7 @@ static int etb_enable_perf(struct coresight_device *csdev, void *data)
if (!ret) {
/* Associate with monitored process. */
drvdata->pid = pid;
- local_set(&drvdata->csdev->mode, CS_MODE_PERF);
+ coresight_set_mode(drvdata->csdev, CS_MODE_PERF);
csdev->refcnt++;
}
@@ -365,7 +365,7 @@ static int etb_disable(struct coresight_device *csdev)
etb_disable_hw(drvdata);
/* Dissociate from monitored process. */
drvdata->pid = -1;
- local_set(&csdev->mode, CS_MODE_DISABLED);
+ coresight_set_mode(csdev, CS_MODE_DISABLED);
spin_unlock_irqrestore(&drvdata->spinlock, flags);
dev_dbg(&csdev->dev, "ETB disabled\n");
diff --git a/drivers/hwtracing/coresight/coresight-etm3x-core.c b/drivers/hwtracing/coresight/coresight-etm3x-core.c
index 64ff53887ef5..9d5c1391ffb1 100644
--- a/drivers/hwtracing/coresight/coresight-etm3x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm3x-core.c
@@ -576,7 +576,7 @@ static int etm_enable(struct coresight_device *csdev, struct perf_event *event,
/* The tracer didn't start */
if (ret)
- local_set(&drvdata->csdev->mode, CS_MODE_DISABLED);
+ coresight_set_mode(drvdata->csdev, CS_MODE_DISABLED);
return ret;
}
@@ -693,7 +693,7 @@ static void etm_disable(struct coresight_device *csdev,
}
if (mode)
- local_set(&csdev->mode, CS_MODE_DISABLED);
+ coresight_set_mode(csdev, CS_MODE_DISABLED);
}
static const struct coresight_ops_source etm_source_ops = {
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
index e65232e982a7..f087bc8d1da6 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
@@ -859,7 +859,7 @@ static int etm4_enable(struct coresight_device *csdev, struct perf_event *event,
/* The tracer didn't start */
if (ret)
- local_set(&csdev->mode, CS_MODE_DISABLED);
+ coresight_set_mode(csdev, CS_MODE_DISABLED);
return ret;
}
@@ -1021,7 +1021,7 @@ static void etm4_disable(struct coresight_device *csdev,
}
if (mode)
- local_set(&csdev->mode, CS_MODE_DISABLED);
+ coresight_set_mode(csdev, CS_MODE_DISABLED);
}
static const struct coresight_ops_source etm4_source_ops = {
diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c
index 1d02d42bea83..974d37e5f94c 100644
--- a/drivers/hwtracing/coresight/coresight-stm.c
+++ b/drivers/hwtracing/coresight/coresight-stm.c
@@ -272,7 +272,7 @@ static void stm_disable(struct coresight_device *csdev,
pm_runtime_put(csdev->dev.parent);
- local_set(&csdev->mode, CS_MODE_DISABLED);
+ coresight_set_mode(csdev, CS_MODE_DISABLED);
dev_dbg(&csdev->dev, "STM tracing disabled\n");
}
}
diff --git a/drivers/hwtracing/coresight/coresight-tmc-etf.c b/drivers/hwtracing/coresight/coresight-tmc-etf.c
index 77ef67c976e9..d4f641cd9de6 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-etf.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-etf.c
@@ -228,7 +228,7 @@ static int tmc_enable_etf_sink_sysfs(struct coresight_device *csdev)
ret = tmc_etb_enable_hw(drvdata);
if (!ret) {
- local_set(&csdev->mode, CS_MODE_SYSFS);
+ coresight_set_mode(csdev, CS_MODE_SYSFS);
csdev->refcnt++;
} else {
/* Free up the buffer if we failed to enable */
@@ -292,7 +292,7 @@ static int tmc_enable_etf_sink_perf(struct coresight_device *csdev, void *data)
if (!ret) {
/* Associate with monitored process. */
drvdata->pid = pid;
- local_set(&csdev->mode, CS_MODE_PERF);
+ coresight_set_mode(csdev, CS_MODE_PERF);
csdev->refcnt++;
}
} while (0);
@@ -349,7 +349,7 @@ static int tmc_disable_etf_sink(struct coresight_device *csdev)
tmc_etb_disable_hw(drvdata);
/* Dissociate from monitored process. */
drvdata->pid = -1;
- local_set(&csdev->mode, CS_MODE_DISABLED);
+ coresight_set_mode(csdev, CS_MODE_DISABLED);
spin_unlock_irqrestore(&drvdata->spinlock, flags);
@@ -375,7 +375,7 @@ static int tmc_enable_etf_link(struct coresight_device *csdev,
if (csdev->refcnt == 0) {
ret = tmc_etf_enable_hw(drvdata);
if (!ret) {
- local_set(&csdev->mode, CS_MODE_SYSFS);
+ coresight_set_mode(csdev, CS_MODE_SYSFS);
first_enable = true;
}
}
@@ -405,7 +405,7 @@ static void tmc_disable_etf_link(struct coresight_device *csdev,
csdev->refcnt--;
if (csdev->refcnt == 0) {
tmc_etf_disable_hw(drvdata);
- local_set(&csdev->mode, CS_MODE_DISABLED);
+ coresight_set_mode(csdev, CS_MODE_DISABLED);
last_disable = true;
}
spin_unlock_irqrestore(&drvdata->spinlock, flags);
diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c
index 383cb8647589..e75428fa1592 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
@@ -1237,7 +1237,7 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev)
ret = tmc_etr_enable_hw(drvdata, sysfs_buf);
if (!ret) {
- local_set(&csdev->mode, CS_MODE_SYSFS);
+ coresight_set_mode(csdev, CS_MODE_SYSFS);
csdev->refcnt++;
}
@@ -1684,7 +1684,7 @@ static int tmc_enable_etr_sink_perf(struct coresight_device *csdev, void *data)
if (!rc) {
/* Associate with monitored process. */
drvdata->pid = pid;
- local_set(&csdev->mode, CS_MODE_PERF);
+ coresight_set_mode(csdev, CS_MODE_PERF);
drvdata->perf_buf = etr_perf->etr_buf;
csdev->refcnt++;
}
@@ -1730,7 +1730,7 @@ static int tmc_disable_etr_sink(struct coresight_device *csdev)
tmc_etr_disable_hw(drvdata);
/* Dissociate from monitored process. */
drvdata->pid = -1;
- local_set(&csdev->mode, CS_MODE_DISABLED);
+ coresight_set_mode(csdev, CS_MODE_DISABLED);
/* Reset perf specific data */
drvdata->perf_buf = NULL;
diff --git a/drivers/hwtracing/coresight/ultrasoc-smb.c b/drivers/hwtracing/coresight/ultrasoc-smb.c
index 903cfffe0bcd..f9ebf20c91e6 100644
--- a/drivers/hwtracing/coresight/ultrasoc-smb.c
+++ b/drivers/hwtracing/coresight/ultrasoc-smb.c
@@ -211,7 +211,7 @@ static void smb_enable_sysfs(struct coresight_device *csdev)
return;
smb_enable_hw(drvdata);
- local_set(&csdev->mode, CS_MODE_SYSFS);
+ coresight_set_mode(csdev, CS_MODE_SYSFS);
}
static int smb_enable_perf(struct coresight_device *csdev, void *data)
@@ -234,7 +234,7 @@ static int smb_enable_perf(struct coresight_device *csdev, void *data)
if (drvdata->pid == -1) {
smb_enable_hw(drvdata);
drvdata->pid = pid;
- local_set(&csdev->mode, CS_MODE_PERF);
+ coresight_set_mode(csdev, CS_MODE_PERF);
}
return 0;
@@ -297,7 +297,7 @@ static int smb_disable(struct coresight_device *csdev)
/* Dissociate from the target process. */
drvdata->pid = -1;
- local_set(&csdev->mode, CS_MODE_DISABLED);
+ coresight_set_mode(csdev, CS_MODE_DISABLED);
dev_dbg(&csdev->dev, "Ultrasoc SMB disabled\n");
return 0;
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index a49e4e20e899..5f288d475490 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -596,6 +596,22 @@ static inline enum cs_mode coresight_get_mode(struct coresight_device *csdev)
return local_read(&csdev->mode);
}
+static inline void coresight_set_mode(struct coresight_device *csdev,
+ enum cs_mode new_mode)
+{
+ enum cs_mode current_mode = coresight_get_mode(csdev);
+
+ /*
+ * Changing to a new mode must be done from an already disabled state
+ * unless it's synchronized with coresight_take_mode(). Otherwise the
+ * device is already in use and signifies a locking issue.
+ */
+ WARN(new_mode != CS_MODE_DISABLED && current_mode != CS_MODE_DISABLED &&
+ current_mode != new_mode, "Device already in use\n");
+
+ local_set(&csdev->mode, new_mode);
+}
+
extern struct coresight_device *
coresight_register(struct coresight_desc *desc);
extern void coresight_unregister(struct coresight_device *csdev);