summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSasha Levin <sashal@kernel.org>2020-11-08 08:28:09 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2020-11-10 12:37:31 +0100
commitcfd9d7137759127d67adf5b1f9a7b171a1bac52f (patch)
treec8f8e924103b3b33efe56552ac10ea30fa225943
parent8ee6a0f25457605e4f2c72dddebd1f73f7140fab (diff)
Revert "coresight: Make sysfs functional on topologies with per core sink"
This reverts commit 8fd52a21ab570e80f84f39e12affce42a5300e91. Guenter Roeck <linux@roeck-us.net> writes: I get the following build warning in v5.4.75. drivers/hwtracing/coresight/coresight-etm-perf.c: In function 'etm_setup_aux': drivers/hwtracing/coresight/coresight-etm-perf.c:226:37: warning: passing argument 1 of 'coresight_get_enabled_sink' makes pointer from integer without a cast Actually, the warning is fatal, since the call is sink = coresight_get_enabled_sink(true); However, the argument to coresight_get_enabled_sink() is now a pointer. The parameter change was introduced with commit 8fd52a21ab57 ("coresight: Make sysfs functional on topologies with per core sink"). In the upstream kernel, the call is removed with commit bb1860efc817 ("coresight: etm: perf: Sink selection using sysfs is deprecated"). That commit alone would, however, likely not solve the problem. It looks like at least two more commits would be needed. 716f5652a131 coresight: etm: perf: Fix warning caused by etm_setup_aux failure 8e264c52e1da coresight: core: Allow the coresight core driver to be built as a module 39a7661dcf65 coresight: Fix uninitialised pointer bug in etm_setup_aux() Looking into the coresight code, I see several additional commits affecting the sysfs interface since v5.4. I have no idea what would actually be needed for stable code in v5.4.y, short of applying them all. With all this in mind, I would suggest to revert commit 8fd52a21ab57 ("coresight: Make sysfs functional on topologies with per core sink") from v5.4.y, especially since it is not marked as bug fix or for stable. Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r--drivers/hwtracing/coresight/coresight-priv.h3
-rw-r--r--drivers/hwtracing/coresight/coresight.c62
2 files changed, 36 insertions, 29 deletions
diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h
index dfd24b85a577..82e563cdc879 100644
--- a/drivers/hwtracing/coresight/coresight-priv.h
+++ b/drivers/hwtracing/coresight/coresight-priv.h
@@ -147,8 +147,7 @@ static inline void coresight_write_reg_pair(void __iomem *addr, u64 val,
void coresight_disable_path(struct list_head *path);
int coresight_enable_path(struct list_head *path, u32 mode, void *sink_data);
struct coresight_device *coresight_get_sink(struct list_head *path);
-struct coresight_device *
-coresight_get_enabled_sink(struct coresight_device *source);
+struct coresight_device *coresight_get_enabled_sink(bool reset);
struct coresight_device *coresight_get_sink_by_id(u32 id);
struct list_head *coresight_build_path(struct coresight_device *csdev,
struct coresight_device *sink);
diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c
index 90ecd04a2f20..0bbce0d29158 100644
--- a/drivers/hwtracing/coresight/coresight.c
+++ b/drivers/hwtracing/coresight/coresight.c
@@ -481,46 +481,50 @@ struct coresight_device *coresight_get_sink(struct list_head *path)
return csdev;
}
-static struct coresight_device *
-coresight_find_enabled_sink(struct coresight_device *csdev)
+static int coresight_enabled_sink(struct device *dev, const void *data)
{
- int i;
- struct coresight_device *sink;
+ const bool *reset = data;
+ struct coresight_device *csdev = to_coresight_device(dev);
if ((csdev->type == CORESIGHT_DEV_TYPE_SINK ||
csdev->type == CORESIGHT_DEV_TYPE_LINKSINK) &&
- csdev->activated)
- return csdev;
-
- /*
- * Recursively explore each port found on this element.
- */
- for (i = 0; i < csdev->pdata->nr_outport; i++) {
- struct coresight_device *child_dev;
+ csdev->activated) {
+ /*
+ * Now that we have a handle on the sink for this session,
+ * disable the sysFS "enable_sink" flag so that possible
+ * concurrent perf session that wish to use another sink don't
+ * trip on it. Doing so has no ramification for the current
+ * session.
+ */
+ if (*reset)
+ csdev->activated = false;
- child_dev = csdev->pdata->conns[i].child_dev;
- if (child_dev)
- sink = coresight_find_enabled_sink(child_dev);
- if (sink)
- return sink;
+ return 1;
}
- return NULL;
+ return 0;
}
/**
- * coresight_get_enabled_sink - returns the first enabled sink using
- * connection based search starting from the source reference
+ * coresight_get_enabled_sink - returns the first enabled sink found on the bus
+ * @deactivate: Whether the 'enable_sink' flag should be reset
*
- * @source: Coresight source device reference
+ * When operated from perf the deactivate parameter should be set to 'true'.
+ * That way the "enabled_sink" flag of the sink that was selected can be reset,
+ * allowing for other concurrent perf sessions to choose a different sink.
+ *
+ * When operated from sysFS users have full control and as such the deactivate
+ * parameter should be set to 'false', hence mandating users to explicitly
+ * clear the flag.
*/
-struct coresight_device *
-coresight_get_enabled_sink(struct coresight_device *source)
+struct coresight_device *coresight_get_enabled_sink(bool deactivate)
{
- if (!source)
- return NULL;
+ struct device *dev = NULL;
+
+ dev = bus_find_device(&coresight_bustype, NULL, &deactivate,
+ coresight_enabled_sink);
- return coresight_find_enabled_sink(source);
+ return dev ? to_coresight_device(dev) : NULL;
}
static int coresight_sink_by_id(struct device *dev, const void *data)
@@ -760,7 +764,11 @@ int coresight_enable(struct coresight_device *csdev)
goto out;
}
- sink = coresight_get_enabled_sink(csdev);
+ /*
+ * Search for a valid sink for this session but don't reset the
+ * "enable_sink" flag in sysFS. Users get to do that explicitly.
+ */
+ sink = coresight_get_enabled_sink(false);
if (!sink) {
ret = -EINVAL;
goto out;