Skip to content

Commit 487eec8

Browse files
James-A-ClarkSuzuki K Poulose
authored andcommitted
coresight: Emit sink ID in the HW_ID packets
For Perf to be able to decode when per-sink trace IDs are used, emit the sink that's being written to for each ETM. Perf currently errors out if it sees a newer packet version so instead of bumping it, add a new minor version field. This can be used to signify new versions that have backwards compatible fields. Considering this change is only for high core count machines, it doesn't make sense to make a breaking change for everyone. Signed-off-by: James Clark <[email protected]> Tested-by: Leo Yan <[email protected]> Reviewed-by: Mike Leach <[email protected]> Signed-off-by: James Clark <[email protected]> Signed-off-by: Suzuki K Poulose <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent de0029f commit 487eec8

File tree

4 files changed

+39
-21
lines changed

4 files changed

+39
-21
lines changed

drivers/hwtracing/coresight/coresight-core.c

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -487,23 +487,25 @@ struct coresight_device *coresight_get_sink(struct list_head *path)
487487
return csdev;
488488
}
489489

490+
u32 coresight_get_sink_id(struct coresight_device *csdev)
491+
{
492+
if (!csdev->ea)
493+
return 0;
494+
495+
/*
496+
* See function etm_perf_add_symlink_sink() to know where
497+
* this comes from.
498+
*/
499+
return (u32) (unsigned long) csdev->ea->var;
500+
}
501+
490502
static int coresight_sink_by_id(struct device *dev, const void *data)
491503
{
492504
struct coresight_device *csdev = to_coresight_device(dev);
493-
unsigned long hash;
494505

495506
if (csdev->type == CORESIGHT_DEV_TYPE_SINK ||
496-
csdev->type == CORESIGHT_DEV_TYPE_LINKSINK) {
497-
498-
if (!csdev->ea)
499-
return 0;
500-
/*
501-
* See function etm_perf_add_symlink_sink() to know where
502-
* this comes from.
503-
*/
504-
hash = (unsigned long)csdev->ea->var;
505-
506-
if ((u32)hash == *(u32 *)data)
507+
csdev->type == CORESIGHT_DEV_TYPE_LINKSINK) {
508+
if (coresight_get_sink_id(csdev) == *(u32 *)data)
507509
return 1;
508510
}
509511

drivers/hwtracing/coresight/coresight-etm-perf.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,7 @@ static void etm_event_start(struct perf_event *event, int flags)
460460
struct coresight_device *sink, *csdev = per_cpu(csdev_src, cpu);
461461
struct list_head *path;
462462
u64 hw_id;
463+
u8 trace_id;
463464

464465
if (!csdev)
465466
goto fail;
@@ -512,11 +513,16 @@ static void etm_event_start(struct perf_event *event, int flags)
512513
*/
513514
if (!cpumask_test_cpu(cpu, &event_data->aux_hwid_done)) {
514515
cpumask_set_cpu(cpu, &event_data->aux_hwid_done);
515-
hw_id = FIELD_PREP(CS_AUX_HW_ID_VERSION_MASK,
516-
CS_AUX_HW_ID_CURR_VERSION);
517-
hw_id |= FIELD_PREP(CS_AUX_HW_ID_TRACE_ID_MASK,
518-
coresight_trace_id_read_cpu_id_map(cpu,
519-
&sink->perf_sink_id_map));
516+
517+
trace_id = coresight_trace_id_read_cpu_id_map(cpu, &sink->perf_sink_id_map);
518+
519+
hw_id = FIELD_PREP(CS_AUX_HW_ID_MAJOR_VERSION_MASK,
520+
CS_AUX_HW_ID_MAJOR_VERSION);
521+
hw_id |= FIELD_PREP(CS_AUX_HW_ID_MINOR_VERSION_MASK,
522+
CS_AUX_HW_ID_MINOR_VERSION);
523+
hw_id |= FIELD_PREP(CS_AUX_HW_ID_TRACE_ID_MASK, trace_id);
524+
hw_id |= FIELD_PREP(CS_AUX_HW_ID_SINK_ID_MASK, coresight_get_sink_id(sink));
525+
520526
perf_report_aux_output_id(event, hw_id);
521527
}
522528

drivers/hwtracing/coresight/coresight-priv.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ int coresight_make_links(struct coresight_device *orig,
148148
struct coresight_device *target);
149149
void coresight_remove_links(struct coresight_device *orig,
150150
struct coresight_connection *conn);
151+
u32 coresight_get_sink_id(struct coresight_device *csdev);
151152

152153
#if IS_ENABLED(CONFIG_CORESIGHT_SOURCE_ETM3X)
153154
extern int etm_readl_cp14(u32 off, unsigned int *val);

include/linux/coresight-pmu.h

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,21 @@
4949
* Interpretation of the PERF_RECORD_AUX_OUTPUT_HW_ID payload.
5050
* Used to associate a CPU with the CoreSight Trace ID.
5151
* [07:00] - Trace ID - uses 8 bits to make value easy to read in file.
52-
* [59:08] - Unused (SBZ)
53-
* [63:60] - Version
52+
* [39:08] - Sink ID - as reported in /sys/bus/event_source/devices/cs_etm/sinks/
53+
* Added in minor version 1.
54+
* [55:40] - Unused (SBZ)
55+
* [59:56] - Minor Version - previously existing fields are compatible with
56+
* all minor versions.
57+
* [63:60] - Major Version - previously existing fields mean different things
58+
* in new major versions.
5459
*/
5560
#define CS_AUX_HW_ID_TRACE_ID_MASK GENMASK_ULL(7, 0)
56-
#define CS_AUX_HW_ID_VERSION_MASK GENMASK_ULL(63, 60)
61+
#define CS_AUX_HW_ID_SINK_ID_MASK GENMASK_ULL(39, 8)
5762

58-
#define CS_AUX_HW_ID_CURR_VERSION 0
63+
#define CS_AUX_HW_ID_MINOR_VERSION_MASK GENMASK_ULL(59, 56)
64+
#define CS_AUX_HW_ID_MAJOR_VERSION_MASK GENMASK_ULL(63, 60)
65+
66+
#define CS_AUX_HW_ID_MAJOR_VERSION 0
67+
#define CS_AUX_HW_ID_MINOR_VERSION 1
5968

6069
#endif

0 commit comments

Comments
 (0)