* [PATCH 0/2] fix inconsistencies with sysfs configuration in etm
@ 2026-03-17 18:17 Yeoreum Yun
2026-03-17 18:17 ` [PATCH 1/2] coresight: etm4x: fix inconsistencies with sysfs configration Yeoreum Yun
2026-03-17 18:17 ` [PATCH 2/2] coresight: etm3x: " Yeoreum Yun
0 siblings, 2 replies; 5+ messages in thread
From: Yeoreum Yun @ 2026-03-17 18:17 UTC (permalink / raw)
To: coresight, linux-arm-kernel, linux-kernel
Cc: suzuki.poulose, mike.leach, james.clark, alexander.shishkin,
leo.yan, Yeoreum Yun
The current ETMx configuration via sysfs can lead to the following
inconsistencies:
- If a configuration is modified via sysfs while a perf session is
active, the running configuration may differ between before
a sched-out and after a subsequent sched-in.
- Once a perf session is enabled, some read-only register fields
(e.g., TRCSSCSR<n>) may not be reported correctly,
because drvdata->config is cleared while enabling with perf mode,
even though the information was previously read.
To resolve these inconsistencies, the configuration should be separated into:
- active_config, which represents the currently applied configuration
- config, which stores the settings configured via sysfs.
This patch based on v7.0-rc4
Yeoreum Yun (2):
coresight: etm4x: fix inconsistencies with sysfs configration
coresight: etm3x: fix inconsistencies with sysfs configration
drivers/hwtracing/coresight/coresight-etm.h | 2 +
.../coresight/coresight-etm3x-core.c | 11 +++--
.../hwtracing/coresight/coresight-etm4x-cfg.c | 2 +-
.../coresight/coresight-etm4x-core.c | 45 +++++++++++--------
drivers/hwtracing/coresight/coresight-etm4x.h | 2 +
5 files changed, 39 insertions(+), 23 deletions(-)
--
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}
^ permalink raw reply [flat|nested] 5+ messages in thread* [PATCH 1/2] coresight: etm4x: fix inconsistencies with sysfs configration 2026-03-17 18:17 [PATCH 0/2] fix inconsistencies with sysfs configuration in etm Yeoreum Yun @ 2026-03-17 18:17 ` Yeoreum Yun 2026-04-01 16:14 ` Suzuki K Poulose 2026-04-07 14:30 ` Leo Yan 2026-03-17 18:17 ` [PATCH 2/2] coresight: etm3x: " Yeoreum Yun 1 sibling, 2 replies; 5+ messages in thread From: Yeoreum Yun @ 2026-03-17 18:17 UTC (permalink / raw) To: coresight, linux-arm-kernel, linux-kernel Cc: suzuki.poulose, mike.leach, james.clark, alexander.shishkin, leo.yan, Yeoreum Yun The current ETM4x configuration via sysfs can lead to the following inconsistencies: - If a configuration is modified via sysfs while a perf session is active, the running configuration may differ between before a sched-out and after a subsequent sched-in. - Once a perf session is enabled, some read-only register fields (e.g., TRCSSCSR<n>) may not be reported correctly, because drvdata->config is cleared while enabling with perf mode, even though the information was previously read via etm4_init_arch_data(). To resolve these inconsistencies, the configuration should be separated into: - active_config, which represents the currently applied configuration - config, which stores the settings configured via sysfs. Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com> --- .../hwtracing/coresight/coresight-etm4x-cfg.c | 2 +- .../coresight/coresight-etm4x-core.c | 45 +++++++++++-------- drivers/hwtracing/coresight/coresight-etm4x.h | 2 + 3 files changed, 30 insertions(+), 19 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-etm4x-cfg.c b/drivers/hwtracing/coresight/coresight-etm4x-cfg.c index c302072b293a..84213d40d1ae 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x-cfg.c +++ b/drivers/hwtracing/coresight/coresight-etm4x-cfg.c @@ -47,7 +47,7 @@ static int etm4_cfg_map_reg_offset(struct etmv4_drvdata *drvdata, struct cscfg_regval_csdev *reg_csdev, u32 offset) { int err = -EINVAL, idx; - struct etmv4_config *drvcfg = &drvdata->config; + struct etmv4_config *drvcfg = &drvdata->active_config; u32 off_mask; if (((offset >= TRCEVENTCTL0R) && (offset <= TRCVIPCSSCTLR)) || diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c index d565a73f0042..c552129c4a0c 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c @@ -88,9 +88,11 @@ static int etm4_probe_cpu(unsigned int cpu); */ static bool etm4x_sspcicrn_present(struct etmv4_drvdata *drvdata, int n) { + struct etmv4_config *config = &drvdata->active_config; + return (n < drvdata->nr_ss_cmp) && drvdata->nr_pe && - (drvdata->config.ss_status[n] & TRCSSCSRn_PC); + (config->ss_status[n] & TRCSSCSRn_PC); } u64 etm4x_sysreg_read(u32 offset, bool _relaxed, bool _64bit) @@ -266,10 +268,11 @@ static void etm4x_prohibit_trace(struct etmv4_drvdata *drvdata) static u64 etm4x_get_kern_user_filter(struct etmv4_drvdata *drvdata) { u64 trfcr = drvdata->trfcr; + struct etmv4_config *config = &drvdata->active_config; - if (drvdata->config.mode & ETM_MODE_EXCL_KERN) + if (config->mode & ETM_MODE_EXCL_KERN) trfcr &= ~TRFCR_EL1_ExTRE; - if (drvdata->config.mode & ETM_MODE_EXCL_USER) + if (config->mode & ETM_MODE_EXCL_USER) trfcr &= ~TRFCR_EL1_E0TRE; return trfcr; @@ -277,7 +280,7 @@ static u64 etm4x_get_kern_user_filter(struct etmv4_drvdata *drvdata) /* * etm4x_allow_trace - Allow CPU tracing in the respective ELs, - * as configured by the drvdata->config.mode for the current + * as configured by the drvdata->active_config.mode for the current * session. Even though we have TRCVICTLR bits to filter the * trace in the ELs, it doesn't prevent the ETM from generating * a packet (e.g, TraceInfo) that might contain the addresses from @@ -288,12 +291,13 @@ static u64 etm4x_get_kern_user_filter(struct etmv4_drvdata *drvdata) static void etm4x_allow_trace(struct etmv4_drvdata *drvdata) { u64 trfcr, guest_trfcr; + struct etmv4_config *config = &drvdata->active_config; /* If the CPU doesn't support FEAT_TRF, nothing to do */ if (!drvdata->trfcr) return; - if (drvdata->config.mode & ETM_MODE_EXCL_HOST) + if (config->mode & ETM_MODE_EXCL_HOST) trfcr = drvdata->trfcr & ~(TRFCR_EL1_ExTRE | TRFCR_EL1_E0TRE); else trfcr = etm4x_get_kern_user_filter(drvdata); @@ -301,7 +305,7 @@ static void etm4x_allow_trace(struct etmv4_drvdata *drvdata) write_trfcr(trfcr); /* Set filters for guests and pass to KVM */ - if (drvdata->config.mode & ETM_MODE_EXCL_GUEST) + if (config->mode & ETM_MODE_EXCL_GUEST) guest_trfcr = drvdata->trfcr & ~(TRFCR_EL1_ExTRE | TRFCR_EL1_E0TRE); else guest_trfcr = etm4x_get_kern_user_filter(drvdata); @@ -494,7 +498,7 @@ static int etm4_enable_trace_unit(struct etmv4_drvdata *drvdata) static int etm4_enable_hw(struct etmv4_drvdata *drvdata) { int i, rc; - struct etmv4_config *config = &drvdata->config; + struct etmv4_config *config = &drvdata->active_config; struct coresight_device *csdev = drvdata->csdev; struct device *etm_dev = &csdev->dev; struct csdev_access *csa = &csdev->access; @@ -666,7 +670,7 @@ static int etm4_config_timestamp_event(struct etmv4_drvdata *drvdata, { int ctridx; int rselector; - struct etmv4_config *config = &drvdata->config; + struct etmv4_config *config = &drvdata->active_config; /* No point in trying if we don't have at least one counter */ if (!drvdata->nr_cntr) @@ -749,7 +753,7 @@ static int etm4_parse_event_config(struct coresight_device *csdev, { int ret = 0; struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); - struct etmv4_config *config = &drvdata->config; + struct etmv4_config *config = &drvdata->active_config; struct perf_event_attr max_timestamp = { .ATTR_CFG_FLD_timestamp_CFG = U64_MAX, }; @@ -911,14 +915,17 @@ static int etm4_enable_sysfs(struct coresight_device *csdev, struct coresight_pa /* enable any config activated by configfs */ cscfg_config_sysfs_get_active_cfg(&cfg_hash, &preset); + + raw_spin_lock(&drvdata->spinlock); + + drvdata->active_config = drvdata->config; + if (cfg_hash) { ret = cscfg_csdev_enable_active_config(csdev, cfg_hash, preset); if (ret) return ret; } - raw_spin_lock(&drvdata->spinlock); - drvdata->trcid = path->trace_id; /* Tracer will never be paused in sysfs mode */ @@ -1028,7 +1035,7 @@ static void etm4_disable_trace_unit(struct etmv4_drvdata *drvdata) static void etm4_disable_hw(struct etmv4_drvdata *drvdata) { u32 control; - struct etmv4_config *config = &drvdata->config; + struct etmv4_config *config = &drvdata->active_config; struct coresight_device *csdev = drvdata->csdev; struct csdev_access *csa = &csdev->access; int i; @@ -1374,12 +1381,14 @@ static void etm4_init_arch_data(void *info) u32 etmidr5; struct etm4_init_arg *init_arg = info; struct etmv4_drvdata *drvdata; + struct etmv4_config *config; struct csdev_access *csa; struct device *dev = init_arg->dev; int i; drvdata = dev_get_drvdata(init_arg->dev); csa = init_arg->csa; + config = &drvdata->active_config; /* * If we are unable to detect the access mechanism, @@ -1440,7 +1449,7 @@ static void etm4_init_arch_data(void *info) /* EXLEVEL_S, bits[19:16] Secure state instruction tracing */ drvdata->s_ex_level = FIELD_GET(TRCIDR3_EXLEVEL_S_MASK, etmidr3); - drvdata->config.s_ex_level = drvdata->s_ex_level; + config->s_ex_level = drvdata->s_ex_level; /* EXLEVEL_NS, bits[23:20] Non-secure state instruction tracing */ drvdata->ns_ex_level = FIELD_GET(TRCIDR3_EXLEVEL_NS_MASK, etmidr3); /* @@ -1491,8 +1500,7 @@ static void etm4_init_arch_data(void *info) */ drvdata->nr_ss_cmp = FIELD_GET(TRCIDR4_NUMSSCC_MASK, etmidr4); for (i = 0; i < drvdata->nr_ss_cmp; i++) { - drvdata->config.ss_status[i] = - etm4x_relaxed_read32(csa, TRCSSCSRn(i)); + config->ss_status[i] = etm4x_relaxed_read32(csa, TRCSSCSRn(i)); } /* NUMCIDC, bits[27:24] number of Context ID comparators for tracing */ drvdata->numcidc = FIELD_GET(TRCIDR4_NUMCIDC_MASK, etmidr4); @@ -1685,7 +1693,7 @@ static void etm4_set_default(struct etmv4_config *config) static int etm4_get_next_comparator(struct etmv4_drvdata *drvdata, u32 type) { int nr_comparator, index = 0; - struct etmv4_config *config = &drvdata->config; + struct etmv4_config *config = &drvdata->active_config; /* * nr_addr_cmp holds the number of comparator _pair_, so time 2 @@ -1726,7 +1734,7 @@ static int etm4_set_event_filters(struct etmv4_drvdata *drvdata, { int i, comparator, ret = 0; u64 address; - struct etmv4_config *config = &drvdata->config; + struct etmv4_config *config = &drvdata->active_config; struct etm_filters *filters = event->hw.addr_filters; if (!filters) @@ -2246,7 +2254,8 @@ static int etm4_add_coresight_dev(struct etm4_init_arg *init_arg) if (!desc.name) return -ENOMEM; - etm4_set_default(&drvdata->config); + etm4_set_default(&drvdata->active_config); + drvdata->config = drvdata->active_config; pdata = coresight_get_platform_data(dev); if (IS_ERR(pdata)) diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h index 89d81ce4e04e..76beb896f188 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x.h +++ b/drivers/hwtracing/coresight/coresight-etm4x.h @@ -1022,6 +1022,7 @@ struct etmv4_save_state { * allows tracing at all ELs. We don't want to compute this * at runtime, due to the additional setting of TRFCR_CX when * in EL2. Otherwise, 0. + * @active_config: structure holding current applied configuration parameters. * @config: structure holding configuration parameters. * @save_state: State to be preserved across power loss * @skip_power_up: Indicates if an implementation can skip powering up @@ -1079,6 +1080,7 @@ struct etmv4_drvdata { bool skip_power_up : 1; bool paused : 1; u64 trfcr; + struct etmv4_config active_config; struct etmv4_config config; struct etmv4_save_state *save_state; DECLARE_BITMAP(arch_features, ETM4_IMPDEF_FEATURE_MAX); -- LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7} ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 1/2] coresight: etm4x: fix inconsistencies with sysfs configration 2026-03-17 18:17 ` [PATCH 1/2] coresight: etm4x: fix inconsistencies with sysfs configration Yeoreum Yun @ 2026-04-01 16:14 ` Suzuki K Poulose 2026-04-07 14:30 ` Leo Yan 1 sibling, 0 replies; 5+ messages in thread From: Suzuki K Poulose @ 2026-04-01 16:14 UTC (permalink / raw) To: Yeoreum Yun, coresight, linux-arm-kernel, linux-kernel Cc: mike.leach, james.clark, alexander.shishkin, leo.yan Hi Levi On 17/03/2026 18:17, Yeoreum Yun wrote: > The current ETM4x configuration via sysfs can lead to the following > inconsistencies: > > - If a configuration is modified via sysfs while a perf session is > active, the running configuration may differ between before > a sched-out and after a subsequent sched-in. > > - Once a perf session is enabled, some read-only register fields > (e.g., TRCSSCSR<n>) may not be reported correctly, > because drvdata->config is cleared while enabling with perf mode, > even though the information was previously read via etm4_init_arch_data(). Thank you for the patch. The patch looks good to me. Some minor comments below. > > To resolve these inconsistencies, the configuration should be separated into: > > - active_config, which represents the currently applied configuration To be more precise, it is the "Applied configuration for the current session" > - config, which stores the settings configured via sysfs. While we are at it, should we stop using the drvdata->config for the "capabilities" for the ETM (e.g., TRCSSCSRn in ss_status ?) Instead we could save it in "drvdata->ss_status". This keeps everything separated: 1. Boot time probed capabilities of ETM 2. Sysfs configuration for the next Run 3. Current active configuration for the ETM (sysfs or perf) Suzuki > > Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com> > --- > .../hwtracing/coresight/coresight-etm4x-cfg.c | 2 +- > .../coresight/coresight-etm4x-core.c | 45 +++++++++++-------- > drivers/hwtracing/coresight/coresight-etm4x.h | 2 + > 3 files changed, 30 insertions(+), 19 deletions(-) > > diff --git a/drivers/hwtracing/coresight/coresight-etm4x-cfg.c b/drivers/hwtracing/coresight/coresight-etm4x-cfg.c > index c302072b293a..84213d40d1ae 100644 > --- a/drivers/hwtracing/coresight/coresight-etm4x-cfg.c > +++ b/drivers/hwtracing/coresight/coresight-etm4x-cfg.c > @@ -47,7 +47,7 @@ static int etm4_cfg_map_reg_offset(struct etmv4_drvdata *drvdata, > struct cscfg_regval_csdev *reg_csdev, u32 offset) > { > int err = -EINVAL, idx; > - struct etmv4_config *drvcfg = &drvdata->config; > + struct etmv4_config *drvcfg = &drvdata->active_config; > u32 off_mask; > > if (((offset >= TRCEVENTCTL0R) && (offset <= TRCVIPCSSCTLR)) || > diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c > index d565a73f0042..c552129c4a0c 100644 > --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c > +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c > @@ -88,9 +88,11 @@ static int etm4_probe_cpu(unsigned int cpu); > */ > static bool etm4x_sspcicrn_present(struct etmv4_drvdata *drvdata, int n) > { > + struct etmv4_config *config = &drvdata->active_config; > + > return (n < drvdata->nr_ss_cmp) && > drvdata->nr_pe && > - (drvdata->config.ss_status[n] & TRCSSCSRn_PC); > + (config->ss_status[n] & TRCSSCSRn_PC); > } > > u64 etm4x_sysreg_read(u32 offset, bool _relaxed, bool _64bit) > @@ -266,10 +268,11 @@ static void etm4x_prohibit_trace(struct etmv4_drvdata *drvdata) > static u64 etm4x_get_kern_user_filter(struct etmv4_drvdata *drvdata) > { > u64 trfcr = drvdata->trfcr; > + struct etmv4_config *config = &drvdata->active_config; > > - if (drvdata->config.mode & ETM_MODE_EXCL_KERN) > + if (config->mode & ETM_MODE_EXCL_KERN) > trfcr &= ~TRFCR_EL1_ExTRE; > - if (drvdata->config.mode & ETM_MODE_EXCL_USER) > + if (config->mode & ETM_MODE_EXCL_USER) > trfcr &= ~TRFCR_EL1_E0TRE; > > return trfcr; > @@ -277,7 +280,7 @@ static u64 etm4x_get_kern_user_filter(struct etmv4_drvdata *drvdata) > > /* > * etm4x_allow_trace - Allow CPU tracing in the respective ELs, > - * as configured by the drvdata->config.mode for the current > + * as configured by the drvdata->active_config.mode for the current > * session. Even though we have TRCVICTLR bits to filter the > * trace in the ELs, it doesn't prevent the ETM from generating > * a packet (e.g, TraceInfo) that might contain the addresses from > @@ -288,12 +291,13 @@ static u64 etm4x_get_kern_user_filter(struct etmv4_drvdata *drvdata) > static void etm4x_allow_trace(struct etmv4_drvdata *drvdata) > { > u64 trfcr, guest_trfcr; > + struct etmv4_config *config = &drvdata->active_config; > > /* If the CPU doesn't support FEAT_TRF, nothing to do */ > if (!drvdata->trfcr) > return; > > - if (drvdata->config.mode & ETM_MODE_EXCL_HOST) > + if (config->mode & ETM_MODE_EXCL_HOST) > trfcr = drvdata->trfcr & ~(TRFCR_EL1_ExTRE | TRFCR_EL1_E0TRE); > else > trfcr = etm4x_get_kern_user_filter(drvdata); > @@ -301,7 +305,7 @@ static void etm4x_allow_trace(struct etmv4_drvdata *drvdata) > write_trfcr(trfcr); > > /* Set filters for guests and pass to KVM */ > - if (drvdata->config.mode & ETM_MODE_EXCL_GUEST) > + if (config->mode & ETM_MODE_EXCL_GUEST) > guest_trfcr = drvdata->trfcr & ~(TRFCR_EL1_ExTRE | TRFCR_EL1_E0TRE); > else > guest_trfcr = etm4x_get_kern_user_filter(drvdata); > @@ -494,7 +498,7 @@ static int etm4_enable_trace_unit(struct etmv4_drvdata *drvdata) > static int etm4_enable_hw(struct etmv4_drvdata *drvdata) > { > int i, rc; > - struct etmv4_config *config = &drvdata->config; > + struct etmv4_config *config = &drvdata->active_config; > struct coresight_device *csdev = drvdata->csdev; > struct device *etm_dev = &csdev->dev; > struct csdev_access *csa = &csdev->access; > @@ -666,7 +670,7 @@ static int etm4_config_timestamp_event(struct etmv4_drvdata *drvdata, > { > int ctridx; > int rselector; > - struct etmv4_config *config = &drvdata->config; > + struct etmv4_config *config = &drvdata->active_config; > > /* No point in trying if we don't have at least one counter */ > if (!drvdata->nr_cntr) > @@ -749,7 +753,7 @@ static int etm4_parse_event_config(struct coresight_device *csdev, > { > int ret = 0; > struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); > - struct etmv4_config *config = &drvdata->config; > + struct etmv4_config *config = &drvdata->active_config; > struct perf_event_attr max_timestamp = { > .ATTR_CFG_FLD_timestamp_CFG = U64_MAX, > }; > @@ -911,14 +915,17 @@ static int etm4_enable_sysfs(struct coresight_device *csdev, struct coresight_pa > > /* enable any config activated by configfs */ > cscfg_config_sysfs_get_active_cfg(&cfg_hash, &preset); > + > + raw_spin_lock(&drvdata->spinlock); > + > + drvdata->active_config = drvdata->config; > + > if (cfg_hash) { > ret = cscfg_csdev_enable_active_config(csdev, cfg_hash, preset); > if (ret) > return ret; > } > > - raw_spin_lock(&drvdata->spinlock); > - > drvdata->trcid = path->trace_id; > > /* Tracer will never be paused in sysfs mode */ > @@ -1028,7 +1035,7 @@ static void etm4_disable_trace_unit(struct etmv4_drvdata *drvdata) > static void etm4_disable_hw(struct etmv4_drvdata *drvdata) > { > u32 control; > - struct etmv4_config *config = &drvdata->config; > + struct etmv4_config *config = &drvdata->active_config; > struct coresight_device *csdev = drvdata->csdev; > struct csdev_access *csa = &csdev->access; > int i; > @@ -1374,12 +1381,14 @@ static void etm4_init_arch_data(void *info) > u32 etmidr5; > struct etm4_init_arg *init_arg = info; > struct etmv4_drvdata *drvdata; > + struct etmv4_config *config; > struct csdev_access *csa; > struct device *dev = init_arg->dev; > int i; > > drvdata = dev_get_drvdata(init_arg->dev); > csa = init_arg->csa; > + config = &drvdata->active_config; > > /* > * If we are unable to detect the access mechanism, > @@ -1440,7 +1449,7 @@ static void etm4_init_arch_data(void *info) > > /* EXLEVEL_S, bits[19:16] Secure state instruction tracing */ > drvdata->s_ex_level = FIELD_GET(TRCIDR3_EXLEVEL_S_MASK, etmidr3); > - drvdata->config.s_ex_level = drvdata->s_ex_level; > + config->s_ex_level = drvdata->s_ex_level; > /* EXLEVEL_NS, bits[23:20] Non-secure state instruction tracing */ > drvdata->ns_ex_level = FIELD_GET(TRCIDR3_EXLEVEL_NS_MASK, etmidr3); > /* > @@ -1491,8 +1500,7 @@ static void etm4_init_arch_data(void *info) > */ > drvdata->nr_ss_cmp = FIELD_GET(TRCIDR4_NUMSSCC_MASK, etmidr4); > for (i = 0; i < drvdata->nr_ss_cmp; i++) { > - drvdata->config.ss_status[i] = > - etm4x_relaxed_read32(csa, TRCSSCSRn(i)); > + config->ss_status[i] = etm4x_relaxed_read32(csa, TRCSSCSRn(i)); > } > /* NUMCIDC, bits[27:24] number of Context ID comparators for tracing */ > drvdata->numcidc = FIELD_GET(TRCIDR4_NUMCIDC_MASK, etmidr4); > @@ -1685,7 +1693,7 @@ static void etm4_set_default(struct etmv4_config *config) > static int etm4_get_next_comparator(struct etmv4_drvdata *drvdata, u32 type) > { > int nr_comparator, index = 0; > - struct etmv4_config *config = &drvdata->config; > + struct etmv4_config *config = &drvdata->active_config; > > /* > * nr_addr_cmp holds the number of comparator _pair_, so time 2 > @@ -1726,7 +1734,7 @@ static int etm4_set_event_filters(struct etmv4_drvdata *drvdata, > { > int i, comparator, ret = 0; > u64 address; > - struct etmv4_config *config = &drvdata->config; > + struct etmv4_config *config = &drvdata->active_config; > struct etm_filters *filters = event->hw.addr_filters; > > if (!filters) > @@ -2246,7 +2254,8 @@ static int etm4_add_coresight_dev(struct etm4_init_arg *init_arg) > if (!desc.name) > return -ENOMEM; > > - etm4_set_default(&drvdata->config); > + etm4_set_default(&drvdata->active_config); > + drvdata->config = drvdata->active_config; > > pdata = coresight_get_platform_data(dev); > if (IS_ERR(pdata)) > diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h > index 89d81ce4e04e..76beb896f188 100644 > --- a/drivers/hwtracing/coresight/coresight-etm4x.h > +++ b/drivers/hwtracing/coresight/coresight-etm4x.h > @@ -1022,6 +1022,7 @@ struct etmv4_save_state { > * allows tracing at all ELs. We don't want to compute this > * at runtime, due to the additional setting of TRFCR_CX when > * in EL2. Otherwise, 0. > + * @active_config: structure holding current applied configuration parameters. > * @config: structure holding configuration parameters. > * @save_state: State to be preserved across power loss > * @skip_power_up: Indicates if an implementation can skip powering up > @@ -1079,6 +1080,7 @@ struct etmv4_drvdata { > bool skip_power_up : 1; > bool paused : 1; > u64 trfcr; > + struct etmv4_config active_config; > struct etmv4_config config; > struct etmv4_save_state *save_state; > DECLARE_BITMAP(arch_features, ETM4_IMPDEF_FEATURE_MAX); ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 1/2] coresight: etm4x: fix inconsistencies with sysfs configration 2026-03-17 18:17 ` [PATCH 1/2] coresight: etm4x: fix inconsistencies with sysfs configration Yeoreum Yun 2026-04-01 16:14 ` Suzuki K Poulose @ 2026-04-07 14:30 ` Leo Yan 1 sibling, 0 replies; 5+ messages in thread From: Leo Yan @ 2026-04-07 14:30 UTC (permalink / raw) To: Yeoreum Yun Cc: coresight, linux-arm-kernel, linux-kernel, suzuki.poulose, mike.leach, james.clark, alexander.shishkin On Tue, Mar 17, 2026 at 06:17:04PM +0000, Yeoreum Yun wrote: > The current ETM4x configuration via sysfs can lead to the following > inconsistencies: > > - If a configuration is modified via sysfs while a perf session is > active, the running configuration may differ between before > a sched-out and after a subsequent sched-in. > > - Once a perf session is enabled, some read-only register fields > (e.g., TRCSSCSR<n>) may not be reported correctly, > because drvdata->config is cleared while enabling with perf mode, > even though the information was previously read via etm4_init_arch_data(). > > To resolve these inconsistencies, the configuration should be separated into: > > - active_config, which represents the currently applied configuration > - config, which stores the settings configured via sysfs. > > Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com> > --- > .../hwtracing/coresight/coresight-etm4x-cfg.c | 2 +- > .../coresight/coresight-etm4x-core.c | 45 +++++++++++-------- > drivers/hwtracing/coresight/coresight-etm4x.h | 2 + > 3 files changed, 30 insertions(+), 19 deletions(-) > > diff --git a/drivers/hwtracing/coresight/coresight-etm4x-cfg.c b/drivers/hwtracing/coresight/coresight-etm4x-cfg.c > index c302072b293a..84213d40d1ae 100644 > --- a/drivers/hwtracing/coresight/coresight-etm4x-cfg.c > +++ b/drivers/hwtracing/coresight/coresight-etm4x-cfg.c > @@ -47,7 +47,7 @@ static int etm4_cfg_map_reg_offset(struct etmv4_drvdata *drvdata, > struct cscfg_regval_csdev *reg_csdev, u32 offset) > { > int err = -EINVAL, idx; > - struct etmv4_config *drvcfg = &drvdata->config; > + struct etmv4_config *drvcfg = &drvdata->active_config; I'd suggest we leave out complex cfg things, we can refactor it later. In this series, let us first separate active_config and config, and keep using drvdata->config to save complex cfg ? > u32 off_mask; > > if (((offset >= TRCEVENTCTL0R) && (offset <= TRCVIPCSSCTLR)) || > diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c > index d565a73f0042..c552129c4a0c 100644 > --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c > +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c > @@ -88,9 +88,11 @@ static int etm4_probe_cpu(unsigned int cpu); > */ > static bool etm4x_sspcicrn_present(struct etmv4_drvdata *drvdata, int n) > { > + struct etmv4_config *config = &drvdata->active_config; > + > return (n < drvdata->nr_ss_cmp) && > drvdata->nr_pe && > - (drvdata->config.ss_status[n] & TRCSSCSRn_PC); > + (config->ss_status[n] & TRCSSCSRn_PC); As Suzuki suggested in another reply, we need to extract capabilities into a separate structure. I'd also extract status related registers into a new structure: struct etm4_cap { int nr_ss_cmp; bool pe_comparator; // TRCSSCSRn.PC bool dv_comparator; // TRCSSCSRn.DV bool da_comparator; // TRCSSCSRn.DA bool inst_comparator; // TRCSSCSRn.INST int ns_ex_level; int nr_pe; int nr_pe_cmp; int nr_resource; ... } struct etm4_status_reg { u32 ss_status[ETM_MAX_SS_CMP]; u32 cntr_val[ETMv4_MAX_CNTR]; } [...] > @@ -911,14 +915,17 @@ static int etm4_enable_sysfs(struct coresight_device *csdev, struct coresight_pa > > /* enable any config activated by configfs */ > cscfg_config_sysfs_get_active_cfg(&cfg_hash, &preset); > + > + raw_spin_lock(&drvdata->spinlock); > + > + drvdata->active_config = drvdata->config; This is not an issue introduced by this patch, but we might need to consider to copy active config until it has acquired SYSFS mode. Otherwise, it might update config here but will disturb a perf session has been running. > @@ -2246,7 +2254,8 @@ static int etm4_add_coresight_dev(struct etm4_init_arg *init_arg) > if (!desc.name) > return -ENOMEM; > > - etm4_set_default(&drvdata->config); > + etm4_set_default(&drvdata->active_config); Should we set default values to drvdata->config ? My understanding is drvdata->active_config would be always set at the runtime, but "drvdata->config" should be initialized properly so it can be consumed by sysfs knobs. Thanks, Leo ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 2/2] coresight: etm3x: fix inconsistencies with sysfs configration 2026-03-17 18:17 [PATCH 0/2] fix inconsistencies with sysfs configuration in etm Yeoreum Yun 2026-03-17 18:17 ` [PATCH 1/2] coresight: etm4x: fix inconsistencies with sysfs configration Yeoreum Yun @ 2026-03-17 18:17 ` Yeoreum Yun 1 sibling, 0 replies; 5+ messages in thread From: Yeoreum Yun @ 2026-03-17 18:17 UTC (permalink / raw) To: coresight, linux-arm-kernel, linux-kernel Cc: suzuki.poulose, mike.leach, james.clark, alexander.shishkin, leo.yan, Yeoreum Yun The current ETM3x configuration via sysfs can lead to the following inconsistencies: - If a configuration is modified via sysfs while a perf session is active, the running configuration may differ between before a sched-out and after a subsequent sched-in. To resolve these inconsistencies, the configuration should be separated into: - active_config, which represents the currently applied configuration - config, which stores the settings configured via sysfs. Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com> --- drivers/hwtracing/coresight/coresight-etm.h | 2 ++ drivers/hwtracing/coresight/coresight-etm3x-core.c | 11 +++++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-etm.h b/drivers/hwtracing/coresight/coresight-etm.h index 1d753cca2943..d94adb08a235 100644 --- a/drivers/hwtracing/coresight/coresight-etm.h +++ b/drivers/hwtracing/coresight/coresight-etm.h @@ -226,6 +226,7 @@ struct etm_config { * @etmccr: value of register ETMCCR. * @etmccer: value of register ETMCCER. * @traceid: value of the current ID for this component. + * @active_config: structure holding current running configuration parameters. * @config: structure holding configuration parameters. */ struct etm_drvdata { @@ -248,6 +249,7 @@ struct etm_drvdata { u32 etmccr; u32 etmccer; u32 traceid; + struct etm_config active_config; struct etm_config config; }; diff --git a/drivers/hwtracing/coresight/coresight-etm3x-core.c b/drivers/hwtracing/coresight/coresight-etm3x-core.c index a547a6d2e0bd..30390ec38762 100644 --- a/drivers/hwtracing/coresight/coresight-etm3x-core.c +++ b/drivers/hwtracing/coresight/coresight-etm3x-core.c @@ -308,7 +308,7 @@ void etm_config_trace_mode(struct etm_config *config) static int etm_parse_event_config(struct etm_drvdata *drvdata, struct perf_event *event) { - struct etm_config *config = &drvdata->config; + struct etm_config *config = &drvdata->active_config; struct perf_event_attr *attr = &event->attr; u8 ts_level; @@ -367,7 +367,7 @@ static int etm_enable_hw(struct etm_drvdata *drvdata) { int i, rc; u32 etmcr; - struct etm_config *config = &drvdata->config; + struct etm_config *config = &drvdata->active_config; struct coresight_device *csdev = drvdata->csdev; CS_UNLOCK(drvdata->csa.base); @@ -513,6 +513,8 @@ static int etm_enable_sysfs(struct coresight_device *csdev, struct coresight_pat spin_lock(&drvdata->spinlock); + drvdata->active_config = drvdata->config; + drvdata->traceid = path->trace_id; /* @@ -563,7 +565,7 @@ static int etm_enable(struct coresight_device *csdev, struct perf_event *event, static void etm_disable_hw(struct etm_drvdata *drvdata) { int i; - struct etm_config *config = &drvdata->config; + struct etm_config *config = &drvdata->active_config; struct coresight_device *csdev = drvdata->csdev; CS_UNLOCK(drvdata->csa.base); @@ -877,7 +879,8 @@ static int etm_probe(struct amba_device *adev, const struct amba_id *id) if (etm_arch_supported(drvdata->arch) == false) return -EINVAL; - etm_set_default(&drvdata->config); + etm_set_default(&drvdata->active_config); + drvdata->config = drvdata->active_config; pdata = coresight_get_platform_data(dev); if (IS_ERR(pdata)) -- LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7} ^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-04-07 14:30 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-03-17 18:17 [PATCH 0/2] fix inconsistencies with sysfs configuration in etm Yeoreum Yun 2026-03-17 18:17 ` [PATCH 1/2] coresight: etm4x: fix inconsistencies with sysfs configration Yeoreum Yun 2026-04-01 16:14 ` Suzuki K Poulose 2026-04-07 14:30 ` Leo Yan 2026-03-17 18:17 ` [PATCH 2/2] coresight: etm3x: " Yeoreum Yun
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox