Message ID | 20241104115604.14522-3-quic_jinlmao@quicinc.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | coresight: Add static trace id support | expand |
On 04/11/2024 11:56, Mao Jinlong wrote: > Dynamic trace id was introduced in coresight subsystem, so trace id is > allocated dynamically. However, some hardware ATB source has static trace > id and it cannot be changed via software programming. For such source, > it can call coresight_get_static_trace_id to get the fixed trace id from > device node and pass id to coresight_trace_id_get_static_system_id to > reserve the id. > > Signed-off-by: Mao Jinlong <quic_jinlmao@quicinc.com> > Reviewed-by: Mike Leach <mike.leach@linaro.org> > --- > .../hwtracing/coresight/coresight-platform.c | 6 +++ > .../hwtracing/coresight/coresight-trace-id.c | 39 +++++++++++++------ > .../hwtracing/coresight/coresight-trace-id.h | 9 +++++ > include/linux/coresight.h | 1 + > 4 files changed, 44 insertions(+), 11 deletions(-) > > diff --git a/drivers/hwtracing/coresight/coresight-platform.c b/drivers/hwtracing/coresight/coresight-platform.c > index 64e171eaad82..633d96b9577a 100644 > --- a/drivers/hwtracing/coresight/coresight-platform.c > +++ b/drivers/hwtracing/coresight/coresight-platform.c > @@ -796,6 +796,12 @@ int coresight_get_cpu(struct device *dev) > } > EXPORT_SYMBOL_GPL(coresight_get_cpu); > > +int coresight_get_static_trace_id(struct device *dev, u32 *id) > +{ > + return fwnode_property_read_u32(dev_fwnode(dev), "arm,static-trace-id", id); > +} > +EXPORT_SYMBOL_GPL(coresight_get_static_trace_id); > + > struct coresight_platform_data * > coresight_get_platform_data(struct device *dev) > { > diff --git a/drivers/hwtracing/coresight/coresight-trace-id.c b/drivers/hwtracing/coresight/coresight-trace-id.c > index d98e12cb30ec..df8fe50b413f 100644 > --- a/drivers/hwtracing/coresight/coresight-trace-id.c > +++ b/drivers/hwtracing/coresight/coresight-trace-id.c > @@ -12,6 +12,12 @@ > > #include "coresight-trace-id.h" > > +enum trace_id_flags { > + TRACE_ID_ANY = 0x0, > + TRACE_ID_PREFER_ODD = 0x1, > + TRACE_ID_REQ_STATIC = 0x2, > +}; > + > /* Default trace ID map. Used in sysfs mode and for system sources */ > static DEFINE_PER_CPU(atomic_t, id_map_default_cpu_ids) = ATOMIC_INIT(0); > static struct coresight_trace_id_map id_map_default = { > @@ -74,16 +80,18 @@ static int coresight_trace_id_find_odd_id(struct coresight_trace_id_map *id_map) > * Otherwise allocate next available ID. > */ > static int coresight_trace_id_alloc_new_id(struct coresight_trace_id_map *id_map, > - int preferred_id, bool prefer_odd_id) > + int preferred_id, unsigned int flags) > { > int id = 0; > > /* for backwards compatibility, cpu IDs may use preferred value */ > - if (IS_VALID_CS_TRACE_ID(preferred_id) && > - !test_bit(preferred_id, id_map->used_ids)) { > - id = preferred_id; > - goto trace_id_allocated; > - } else if (prefer_odd_id) { > + if (IS_VALID_CS_TRACE_ID(preferred_id)) { > + if (!test_bit(preferred_id, id_map->used_ids)) { > + id = preferred_id; > + goto trace_id_allocated; > + } else if (flags & TRACE_ID_REQ_STATIC) > + return -EINVAL; nit: EBUSY sounds like a better choice here ? Requested ID is not available. Additionally, do we need to handle a case where the preferred_id is not valid ? I think we silently allocate a new trace id in such case ? Rest looks good to me. Suzuki > + } else if (flags & TRACE_ID_PREFER_ODD) { > /* may use odd ids to avoid preferred legacy cpu IDs */ > id = coresight_trace_id_find_odd_id(id_map); > if (id) > @@ -153,7 +161,7 @@ static int _coresight_trace_id_get_cpu_id(int cpu, struct coresight_trace_id_map > */ > id = coresight_trace_id_alloc_new_id(id_map, > CORESIGHT_LEGACY_CPU_TRACE_ID(cpu), > - false); > + TRACE_ID_ANY); > if (!IS_VALID_CS_TRACE_ID(id)) > goto get_cpu_id_out_unlock; > > @@ -188,14 +196,14 @@ static void _coresight_trace_id_put_cpu_id(int cpu, struct coresight_trace_id_ma > DUMP_ID_MAP(id_map); > } > > -static int coresight_trace_id_map_get_system_id(struct coresight_trace_id_map *id_map) > +static int coresight_trace_id_map_get_system_id(struct coresight_trace_id_map *id_map, > + int preferred_id, unsigned int traceid_flags) > { > unsigned long flags; > int id; > > spin_lock_irqsave(&id_map->lock, flags); > - /* prefer odd IDs for system components to avoid legacy CPU IDS */ > - id = coresight_trace_id_alloc_new_id(id_map, 0, true); > + id = coresight_trace_id_alloc_new_id(id_map, preferred_id, traceid_flags); > spin_unlock_irqrestore(&id_map->lock, flags); > > DUMP_ID(id); > @@ -255,10 +263,19 @@ EXPORT_SYMBOL_GPL(coresight_trace_id_read_cpu_id_map); > > int coresight_trace_id_get_system_id(void) > { > - return coresight_trace_id_map_get_system_id(&id_map_default); > + /* prefer odd IDs for system components to avoid legacy CPU IDS */ > + return coresight_trace_id_map_get_system_id(&id_map_default, 0, > + TRACE_ID_PREFER_ODD); > } > EXPORT_SYMBOL_GPL(coresight_trace_id_get_system_id); > > +int coresight_trace_id_get_static_system_id(int trace_id) > +{ > + return coresight_trace_id_map_get_system_id(&id_map_default, > + trace_id, TRACE_ID_REQ_STATIC); > +} > +EXPORT_SYMBOL_GPL(coresight_trace_id_get_static_system_id); > + > void coresight_trace_id_put_system_id(int id) > { > coresight_trace_id_map_put_system_id(&id_map_default, id); > diff --git a/drivers/hwtracing/coresight/coresight-trace-id.h b/drivers/hwtracing/coresight/coresight-trace-id.h > index 9aae50a553ca..db68e1ec56b6 100644 > --- a/drivers/hwtracing/coresight/coresight-trace-id.h > +++ b/drivers/hwtracing/coresight/coresight-trace-id.h > @@ -116,6 +116,15 @@ int coresight_trace_id_read_cpu_id_map(int cpu, struct coresight_trace_id_map *i > */ > int coresight_trace_id_get_system_id(void); > > +/** > + * Allocate a CoreSight static trace ID for a system component. > + * > + * Used to allocate static IDs for system trace sources such as dummy source. > + * > + * return: Trace ID or -EINVAL if allocation is impossible. > + */ > +int coresight_trace_id_get_static_system_id(int id); > + > /** > * Release an allocated system trace ID. > * > diff --git a/include/linux/coresight.h b/include/linux/coresight.h > index c13342594278..129795873072 100644 > --- a/include/linux/coresight.h > +++ b/include/linux/coresight.h > @@ -662,6 +662,7 @@ void coresight_relaxed_write64(struct coresight_device *csdev, > void coresight_write64(struct coresight_device *csdev, u64 val, u32 offset); > > extern int coresight_get_cpu(struct device *dev); > +extern int coresight_get_static_trace_id(struct device *dev, u32 *id); > > struct coresight_platform_data *coresight_get_platform_data(struct device *dev); > struct coresight_connection *
On 2024/11/13 21:27, Suzuki K Poulose wrote: > On 04/11/2024 11:56, Mao Jinlong wrote: >> Dynamic trace id was introduced in coresight subsystem, so trace id is >> allocated dynamically. However, some hardware ATB source has static trace >> id and it cannot be changed via software programming. For such source, >> it can call coresight_get_static_trace_id to get the fixed trace id from >> device node and pass id to coresight_trace_id_get_static_system_id to >> reserve the id. >> >> Signed-off-by: Mao Jinlong <quic_jinlmao@quicinc.com> >> Reviewed-by: Mike Leach <mike.leach@linaro.org> >> --- >> .../hwtracing/coresight/coresight-platform.c | 6 +++ >> .../hwtracing/coresight/coresight-trace-id.c | 39 +++++++++++++------ >> .../hwtracing/coresight/coresight-trace-id.h | 9 +++++ >> include/linux/coresight.h | 1 + >> 4 files changed, 44 insertions(+), 11 deletions(-) >> >> diff --git a/drivers/hwtracing/coresight/coresight-platform.c b/ >> drivers/hwtracing/coresight/coresight-platform.c >> index 64e171eaad82..633d96b9577a 100644 >> --- a/drivers/hwtracing/coresight/coresight-platform.c >> +++ b/drivers/hwtracing/coresight/coresight-platform.c >> @@ -796,6 +796,12 @@ int coresight_get_cpu(struct device *dev) >> } >> EXPORT_SYMBOL_GPL(coresight_get_cpu); >> +int coresight_get_static_trace_id(struct device *dev, u32 *id) >> +{ >> + return fwnode_property_read_u32(dev_fwnode(dev), "arm,static- >> trace-id", id); >> +} >> +EXPORT_SYMBOL_GPL(coresight_get_static_trace_id); >> + >> struct coresight_platform_data * >> coresight_get_platform_data(struct device *dev) >> { >> diff --git a/drivers/hwtracing/coresight/coresight-trace-id.c b/ >> drivers/hwtracing/coresight/coresight-trace-id.c >> index d98e12cb30ec..df8fe50b413f 100644 >> --- a/drivers/hwtracing/coresight/coresight-trace-id.c >> +++ b/drivers/hwtracing/coresight/coresight-trace-id.c >> @@ -12,6 +12,12 @@ >> #include "coresight-trace-id.h" >> +enum trace_id_flags { >> + TRACE_ID_ANY = 0x0, >> + TRACE_ID_PREFER_ODD = 0x1, >> + TRACE_ID_REQ_STATIC = 0x2, >> +}; >> + >> /* Default trace ID map. Used in sysfs mode and for system sources */ >> static DEFINE_PER_CPU(atomic_t, id_map_default_cpu_ids) = >> ATOMIC_INIT(0); >> static struct coresight_trace_id_map id_map_default = { >> @@ -74,16 +80,18 @@ static int coresight_trace_id_find_odd_id(struct >> coresight_trace_id_map *id_map) >> * Otherwise allocate next available ID. >> */ >> static int coresight_trace_id_alloc_new_id(struct >> coresight_trace_id_map *id_map, >> - int preferred_id, bool prefer_odd_id) >> + int preferred_id, unsigned int flags) >> { >> int id = 0; >> /* for backwards compatibility, cpu IDs may use preferred value */ >> - if (IS_VALID_CS_TRACE_ID(preferred_id) && >> - !test_bit(preferred_id, id_map->used_ids)) { >> - id = preferred_id; >> - goto trace_id_allocated; >> - } else if (prefer_odd_id) { >> + if (IS_VALID_CS_TRACE_ID(preferred_id)) { >> + if (!test_bit(preferred_id, id_map->used_ids)) { >> + id = preferred_id; >> + goto trace_id_allocated; >> + } else if (flags & TRACE_ID_REQ_STATIC) >> + return -EINVAL; > > nit: EBUSY sounds like a better choice here ? Requested ID is not > available. > > Additionally, do we need to handle a case where the preferred_id is > not valid ? I think we silently allocate a new trace id in such case ? > > Rest looks good to me. > > Suzuki > > If preferred_id is not valid, a random id will be allocated for the source. For the normal source, 0 is provided here as preferred_id. > > >> + } else if (flags & TRACE_ID_PREFER_ODD) { >> /* may use odd ids to avoid preferred legacy cpu IDs */ >> id = coresight_trace_id_find_odd_id(id_map); >> if (id) >> @@ -153,7 +161,7 @@ static int _coresight_trace_id_get_cpu_id(int cpu, >> struct coresight_trace_id_map >> */ >> id = coresight_trace_id_alloc_new_id(id_map, >> CORESIGHT_LEGACY_CPU_TRACE_ID(cpu), >> - false); >> + TRACE_ID_ANY); >> if (!IS_VALID_CS_TRACE_ID(id)) >> goto get_cpu_id_out_unlock; >> @@ -188,14 +196,14 @@ static void _coresight_trace_id_put_cpu_id(int >> cpu, struct coresight_trace_id_ma >> DUMP_ID_MAP(id_map); >> } >> -static int coresight_trace_id_map_get_system_id(struct >> coresight_trace_id_map *id_map) >> +static int coresight_trace_id_map_get_system_id(struct >> coresight_trace_id_map *id_map, >> + int preferred_id, unsigned int traceid_flags) >> { >> unsigned long flags; >> int id; >> spin_lock_irqsave(&id_map->lock, flags); >> - /* prefer odd IDs for system components to avoid legacy CPU IDS */ >> - id = coresight_trace_id_alloc_new_id(id_map, 0, true); >> + id = coresight_trace_id_alloc_new_id(id_map, preferred_id, >> traceid_flags); >> spin_unlock_irqrestore(&id_map->lock, flags); >> DUMP_ID(id); >> @@ -255,10 +263,19 @@ >> EXPORT_SYMBOL_GPL(coresight_trace_id_read_cpu_id_map); >> int coresight_trace_id_get_system_id(void) >> { >> - return coresight_trace_id_map_get_system_id(&id_map_default); >> + /* prefer odd IDs for system components to avoid legacy CPU IDS */ >> + return coresight_trace_id_map_get_system_id(&id_map_default, 0, >> + TRACE_ID_PREFER_ODD); >> } >> EXPORT_SYMBOL_GPL(coresight_trace_id_get_system_id); >> +int coresight_trace_id_get_static_system_id(int trace_id) >> +{ >> + return coresight_trace_id_map_get_system_id(&id_map_default, >> + trace_id, TRACE_ID_REQ_STATIC); >> +} >> +EXPORT_SYMBOL_GPL(coresight_trace_id_get_static_system_id); >> + >> void coresight_trace_id_put_system_id(int id) >> { >> coresight_trace_id_map_put_system_id(&id_map_default, id); >> diff --git a/drivers/hwtracing/coresight/coresight-trace-id.h b/ >> drivers/hwtracing/coresight/coresight-trace-id.h >> index 9aae50a553ca..db68e1ec56b6 100644 >> --- a/drivers/hwtracing/coresight/coresight-trace-id.h >> +++ b/drivers/hwtracing/coresight/coresight-trace-id.h >> @@ -116,6 +116,15 @@ int coresight_trace_id_read_cpu_id_map(int cpu, >> struct coresight_trace_id_map *i >> */ >> int coresight_trace_id_get_system_id(void); >> +/** >> + * Allocate a CoreSight static trace ID for a system component. >> + * >> + * Used to allocate static IDs for system trace sources such as dummy >> source. >> + * >> + * return: Trace ID or -EINVAL if allocation is impossible. >> + */ >> +int coresight_trace_id_get_static_system_id(int id); >> + >> /** >> * Release an allocated system trace ID. >> * >> diff --git a/include/linux/coresight.h b/include/linux/coresight.h >> index c13342594278..129795873072 100644 >> --- a/include/linux/coresight.h >> +++ b/include/linux/coresight.h >> @@ -662,6 +662,7 @@ void coresight_relaxed_write64(struct >> coresight_device *csdev, >> void coresight_write64(struct coresight_device *csdev, u64 val, u32 >> offset); >> extern int coresight_get_cpu(struct device *dev); >> +extern int coresight_get_static_trace_id(struct device *dev, u32 *id); >> struct coresight_platform_data *coresight_get_platform_data(struct >> device *dev); >> struct coresight_connection * >
On 18/11/2024 10:14, Jinlong Mao wrote: > > > On 2024/11/13 21:27, Suzuki K Poulose wrote: >> On 04/11/2024 11:56, Mao Jinlong wrote: >>> Dynamic trace id was introduced in coresight subsystem, so trace id is >>> allocated dynamically. However, some hardware ATB source has static >>> trace >>> id and it cannot be changed via software programming. For such source, >>> it can call coresight_get_static_trace_id to get the fixed trace id from >>> device node and pass id to coresight_trace_id_get_static_system_id to >>> reserve the id. >>> >>> Signed-off-by: Mao Jinlong <quic_jinlmao@quicinc.com> >>> Reviewed-by: Mike Leach <mike.leach@linaro.org> >>> --- >>> .../hwtracing/coresight/coresight-platform.c | 6 +++ >>> .../hwtracing/coresight/coresight-trace-id.c | 39 +++++++++++++------ >>> .../hwtracing/coresight/coresight-trace-id.h | 9 +++++ >>> include/linux/coresight.h | 1 + >>> 4 files changed, 44 insertions(+), 11 deletions(-) >>> >>> diff --git a/drivers/hwtracing/coresight/coresight-platform.c b/ >>> drivers/hwtracing/coresight/coresight-platform.c >>> index 64e171eaad82..633d96b9577a 100644 >>> --- a/drivers/hwtracing/coresight/coresight-platform.c >>> +++ b/drivers/hwtracing/coresight/coresight-platform.c >>> @@ -796,6 +796,12 @@ int coresight_get_cpu(struct device *dev) >>> } >>> EXPORT_SYMBOL_GPL(coresight_get_cpu); >>> +int coresight_get_static_trace_id(struct device *dev, u32 *id) >>> +{ >>> + return fwnode_property_read_u32(dev_fwnode(dev), "arm,static- >>> trace-id", id); >>> +} >>> +EXPORT_SYMBOL_GPL(coresight_get_static_trace_id); >>> + >>> struct coresight_platform_data * >>> coresight_get_platform_data(struct device *dev) >>> { >>> diff --git a/drivers/hwtracing/coresight/coresight-trace-id.c b/ >>> drivers/hwtracing/coresight/coresight-trace-id.c >>> index d98e12cb30ec..df8fe50b413f 100644 >>> --- a/drivers/hwtracing/coresight/coresight-trace-id.c >>> +++ b/drivers/hwtracing/coresight/coresight-trace-id.c >>> @@ -12,6 +12,12 @@ >>> #include "coresight-trace-id.h" >>> +enum trace_id_flags { >>> + TRACE_ID_ANY = 0x0, >>> + TRACE_ID_PREFER_ODD = 0x1, >>> + TRACE_ID_REQ_STATIC = 0x2, >>> +}; >>> + >>> /* Default trace ID map. Used in sysfs mode and for system sources */ >>> static DEFINE_PER_CPU(atomic_t, id_map_default_cpu_ids) = >>> ATOMIC_INIT(0); >>> static struct coresight_trace_id_map id_map_default = { >>> @@ -74,16 +80,18 @@ static int coresight_trace_id_find_odd_id(struct >>> coresight_trace_id_map *id_map) >>> * Otherwise allocate next available ID. >>> */ >>> static int coresight_trace_id_alloc_new_id(struct >>> coresight_trace_id_map *id_map, >>> - int preferred_id, bool prefer_odd_id) >>> + int preferred_id, unsigned int flags) >>> { >>> int id = 0; >>> /* for backwards compatibility, cpu IDs may use preferred value */ >>> - if (IS_VALID_CS_TRACE_ID(preferred_id) && >>> - !test_bit(preferred_id, id_map->used_ids)) { >>> - id = preferred_id; >>> - goto trace_id_allocated; >>> - } else if (prefer_odd_id) { >>> + if (IS_VALID_CS_TRACE_ID(preferred_id)) { >>> + if (!test_bit(preferred_id, id_map->used_ids)) { >>> + id = preferred_id; >>> + goto trace_id_allocated; >>> + } else if (flags & TRACE_ID_REQ_STATIC) >>> + return -EINVAL; >> >> nit: EBUSY sounds like a better choice here ? Requested ID is not >> available. >> >> Additionally, do we need to handle a case where the preferred_id is >> not valid ? I think we silently allocate a new trace id in such case ? >> >> Rest looks good to me. >> >> Suzuki >> >> > > If preferred_id is not valid, a random id will be allocated for the > source. For the normal source, 0 is provided here as preferred_id. My point is : If preferred_id is not valid *and* TRACE_ID_REQ_STATIC flag is set, we go ahead and allocate a random different ID. Which is not preferred. We should return -EINVAL in that case. Suzuki > >> >> >>> + } else if (flags & TRACE_ID_PREFER_ODD) { >>> /* may use odd ids to avoid preferred legacy cpu IDs */ >>> id = coresight_trace_id_find_odd_id(id_map); >>> if (id) >>> @@ -153,7 +161,7 @@ static int _coresight_trace_id_get_cpu_id(int >>> cpu, struct coresight_trace_id_map >>> */ >>> id = coresight_trace_id_alloc_new_id(id_map, >>> CORESIGHT_LEGACY_CPU_TRACE_ID(cpu), >>> - false); >>> + TRACE_ID_ANY); >>> if (!IS_VALID_CS_TRACE_ID(id)) >>> goto get_cpu_id_out_unlock; >>> @@ -188,14 +196,14 @@ static void _coresight_trace_id_put_cpu_id(int >>> cpu, struct coresight_trace_id_ma >>> DUMP_ID_MAP(id_map); >>> } >>> -static int coresight_trace_id_map_get_system_id(struct >>> coresight_trace_id_map *id_map) >>> +static int coresight_trace_id_map_get_system_id(struct >>> coresight_trace_id_map *id_map, >>> + int preferred_id, unsigned int traceid_flags) >>> { >>> unsigned long flags; >>> int id; >>> spin_lock_irqsave(&id_map->lock, flags); >>> - /* prefer odd IDs for system components to avoid legacy CPU IDS */ >>> - id = coresight_trace_id_alloc_new_id(id_map, 0, true); >>> + id = coresight_trace_id_alloc_new_id(id_map, preferred_id, >>> traceid_flags); >>> spin_unlock_irqrestore(&id_map->lock, flags); >>> DUMP_ID(id); >>> @@ -255,10 +263,19 @@ >>> EXPORT_SYMBOL_GPL(coresight_trace_id_read_cpu_id_map); >>> int coresight_trace_id_get_system_id(void) >>> { >>> - return coresight_trace_id_map_get_system_id(&id_map_default); >>> + /* prefer odd IDs for system components to avoid legacy CPU IDS */ >>> + return coresight_trace_id_map_get_system_id(&id_map_default, 0, >>> + TRACE_ID_PREFER_ODD); >>> } >>> EXPORT_SYMBOL_GPL(coresight_trace_id_get_system_id); >>> +int coresight_trace_id_get_static_system_id(int trace_id) >>> +{ >>> + return coresight_trace_id_map_get_system_id(&id_map_default, >>> + trace_id, TRACE_ID_REQ_STATIC); >>> +} >>> +EXPORT_SYMBOL_GPL(coresight_trace_id_get_static_system_id); >>> + >>> void coresight_trace_id_put_system_id(int id) >>> { >>> coresight_trace_id_map_put_system_id(&id_map_default, id); >>> diff --git a/drivers/hwtracing/coresight/coresight-trace-id.h b/ >>> drivers/hwtracing/coresight/coresight-trace-id.h >>> index 9aae50a553ca..db68e1ec56b6 100644 >>> --- a/drivers/hwtracing/coresight/coresight-trace-id.h >>> +++ b/drivers/hwtracing/coresight/coresight-trace-id.h >>> @@ -116,6 +116,15 @@ int coresight_trace_id_read_cpu_id_map(int cpu, >>> struct coresight_trace_id_map *i >>> */ >>> int coresight_trace_id_get_system_id(void); >>> +/** >>> + * Allocate a CoreSight static trace ID for a system component. >>> + * >>> + * Used to allocate static IDs for system trace sources such as >>> dummy source. >>> + * >>> + * return: Trace ID or -EINVAL if allocation is impossible. >>> + */ >>> +int coresight_trace_id_get_static_system_id(int id); >>> + >>> /** >>> * Release an allocated system trace ID. >>> * >>> diff --git a/include/linux/coresight.h b/include/linux/coresight.h >>> index c13342594278..129795873072 100644 >>> --- a/include/linux/coresight.h >>> +++ b/include/linux/coresight.h >>> @@ -662,6 +662,7 @@ void coresight_relaxed_write64(struct >>> coresight_device *csdev, >>> void coresight_write64(struct coresight_device *csdev, u64 val, u32 >>> offset); >>> extern int coresight_get_cpu(struct device *dev); >>> +extern int coresight_get_static_trace_id(struct device *dev, u32 *id); >>> struct coresight_platform_data *coresight_get_platform_data(struct >>> device *dev); >>> struct coresight_connection * >> >
On 2024/11/18 18:18, Suzuki K Poulose wrote: > On 18/11/2024 10:14, Jinlong Mao wrote: >> >> >> On 2024/11/13 21:27, Suzuki K Poulose wrote: >>> On 04/11/2024 11:56, Mao Jinlong wrote: >>>> Dynamic trace id was introduced in coresight subsystem, so trace id is >>>> allocated dynamically. However, some hardware ATB source has static >>>> trace >>>> id and it cannot be changed via software programming. For such source, >>>> it can call coresight_get_static_trace_id to get the fixed trace id >>>> from >>>> device node and pass id to coresight_trace_id_get_static_system_id to >>>> reserve the id. >>>> >>>> Signed-off-by: Mao Jinlong <quic_jinlmao@quicinc.com> >>>> Reviewed-by: Mike Leach <mike.leach@linaro.org> >>>> --- >>>> .../hwtracing/coresight/coresight-platform.c | 6 +++ >>>> .../hwtracing/coresight/coresight-trace-id.c | 39 ++++++++++++ >>>> +------ >>>> .../hwtracing/coresight/coresight-trace-id.h | 9 +++++ >>>> include/linux/coresight.h | 1 + >>>> 4 files changed, 44 insertions(+), 11 deletions(-) >>>> >>>> diff --git a/drivers/hwtracing/coresight/coresight-platform.c b/ >>>> drivers/hwtracing/coresight/coresight-platform.c >>>> index 64e171eaad82..633d96b9577a 100644 >>>> --- a/drivers/hwtracing/coresight/coresight-platform.c >>>> +++ b/drivers/hwtracing/coresight/coresight-platform.c >>>> @@ -796,6 +796,12 @@ int coresight_get_cpu(struct device *dev) >>>> } >>>> EXPORT_SYMBOL_GPL(coresight_get_cpu); >>>> +int coresight_get_static_trace_id(struct device *dev, u32 *id) >>>> +{ >>>> + return fwnode_property_read_u32(dev_fwnode(dev), "arm,static- >>>> trace-id", id); >>>> +} >>>> +EXPORT_SYMBOL_GPL(coresight_get_static_trace_id); >>>> + >>>> struct coresight_platform_data * >>>> coresight_get_platform_data(struct device *dev) >>>> { >>>> diff --git a/drivers/hwtracing/coresight/coresight-trace-id.c b/ >>>> drivers/hwtracing/coresight/coresight-trace-id.c >>>> index d98e12cb30ec..df8fe50b413f 100644 >>>> --- a/drivers/hwtracing/coresight/coresight-trace-id.c >>>> +++ b/drivers/hwtracing/coresight/coresight-trace-id.c >>>> @@ -12,6 +12,12 @@ >>>> #include "coresight-trace-id.h" >>>> +enum trace_id_flags { >>>> + TRACE_ID_ANY = 0x0, >>>> + TRACE_ID_PREFER_ODD = 0x1, >>>> + TRACE_ID_REQ_STATIC = 0x2, >>>> +}; >>>> + >>>> /* Default trace ID map. Used in sysfs mode and for system sources */ >>>> static DEFINE_PER_CPU(atomic_t, id_map_default_cpu_ids) = >>>> ATOMIC_INIT(0); >>>> static struct coresight_trace_id_map id_map_default = { >>>> @@ -74,16 +80,18 @@ static int coresight_trace_id_find_odd_id(struct >>>> coresight_trace_id_map *id_map) >>>> * Otherwise allocate next available ID. >>>> */ >>>> static int coresight_trace_id_alloc_new_id(struct >>>> coresight_trace_id_map *id_map, >>>> - int preferred_id, bool prefer_odd_id) >>>> + int preferred_id, unsigned int flags) >>>> { >>>> int id = 0; >>>> /* for backwards compatibility, cpu IDs may use preferred >>>> value */ >>>> - if (IS_VALID_CS_TRACE_ID(preferred_id) && >>>> - !test_bit(preferred_id, id_map->used_ids)) { >>>> - id = preferred_id; >>>> - goto trace_id_allocated; >>>> - } else if (prefer_odd_id) { >>>> + if (IS_VALID_CS_TRACE_ID(preferred_id)) { >>>> + if (!test_bit(preferred_id, id_map->used_ids)) { >>>> + id = preferred_id; >>>> + goto trace_id_allocated; >>>> + } else if (flags & TRACE_ID_REQ_STATIC) >>>> + return -EINVAL; >>> >>> nit: EBUSY sounds like a better choice here ? Requested ID is not >>> available. >>> >>> Additionally, do we need to handle a case where the preferred_id is >>> not valid ? I think we silently allocate a new trace id in such case ? >>> >>> Rest looks good to me. >>> >>> Suzuki >>> >>> >> >> If preferred_id is not valid, a random id will be allocated for the >> source. For the normal source, 0 is provided here as preferred_id. > > My point is : If preferred_id is not valid *and* TRACE_ID_REQ_STATIC > flag is set, we go ahead and allocate a random different ID. Which is > not preferred. We should return -EINVAL in that case. > > Suzuki > > Got your point. Thanks. >> >>> >>> >>>> + } else if (flags & TRACE_ID_PREFER_ODD) { >>>> /* may use odd ids to avoid preferred legacy cpu IDs */ >>>> id = coresight_trace_id_find_odd_id(id_map); >>>> if (id) >>>> @@ -153,7 +161,7 @@ static int _coresight_trace_id_get_cpu_id(int >>>> cpu, struct coresight_trace_id_map >>>> */ >>>> id = coresight_trace_id_alloc_new_id(id_map, >>>> CORESIGHT_LEGACY_CPU_TRACE_ID(cpu), >>>> - false); >>>> + TRACE_ID_ANY); >>>> if (!IS_VALID_CS_TRACE_ID(id)) >>>> goto get_cpu_id_out_unlock; >>>> @@ -188,14 +196,14 @@ static void _coresight_trace_id_put_cpu_id(int >>>> cpu, struct coresight_trace_id_ma >>>> DUMP_ID_MAP(id_map); >>>> } >>>> -static int coresight_trace_id_map_get_system_id(struct >>>> coresight_trace_id_map *id_map) >>>> +static int coresight_trace_id_map_get_system_id(struct >>>> coresight_trace_id_map *id_map, >>>> + int preferred_id, unsigned int traceid_flags) >>>> { >>>> unsigned long flags; >>>> int id; >>>> spin_lock_irqsave(&id_map->lock, flags); >>>> - /* prefer odd IDs for system components to avoid legacy CPU IDS */ >>>> - id = coresight_trace_id_alloc_new_id(id_map, 0, true); >>>> + id = coresight_trace_id_alloc_new_id(id_map, preferred_id, >>>> traceid_flags); >>>> spin_unlock_irqrestore(&id_map->lock, flags); >>>> DUMP_ID(id); >>>> @@ -255,10 +263,19 @@ >>>> EXPORT_SYMBOL_GPL(coresight_trace_id_read_cpu_id_map); >>>> int coresight_trace_id_get_system_id(void) >>>> { >>>> - return coresight_trace_id_map_get_system_id(&id_map_default); >>>> + /* prefer odd IDs for system components to avoid legacy CPU IDS */ >>>> + return coresight_trace_id_map_get_system_id(&id_map_default, 0, >>>> + TRACE_ID_PREFER_ODD); >>>> } >>>> EXPORT_SYMBOL_GPL(coresight_trace_id_get_system_id); >>>> +int coresight_trace_id_get_static_system_id(int trace_id) >>>> +{ >>>> + return coresight_trace_id_map_get_system_id(&id_map_default, >>>> + trace_id, TRACE_ID_REQ_STATIC); >>>> +} >>>> +EXPORT_SYMBOL_GPL(coresight_trace_id_get_static_system_id); >>>> + >>>> void coresight_trace_id_put_system_id(int id) >>>> { >>>> coresight_trace_id_map_put_system_id(&id_map_default, id); >>>> diff --git a/drivers/hwtracing/coresight/coresight-trace-id.h b/ >>>> drivers/hwtracing/coresight/coresight-trace-id.h >>>> index 9aae50a553ca..db68e1ec56b6 100644 >>>> --- a/drivers/hwtracing/coresight/coresight-trace-id.h >>>> +++ b/drivers/hwtracing/coresight/coresight-trace-id.h >>>> @@ -116,6 +116,15 @@ int coresight_trace_id_read_cpu_id_map(int cpu, >>>> struct coresight_trace_id_map *i >>>> */ >>>> int coresight_trace_id_get_system_id(void); >>>> +/** >>>> + * Allocate a CoreSight static trace ID for a system component. >>>> + * >>>> + * Used to allocate static IDs for system trace sources such as >>>> dummy source. >>>> + * >>>> + * return: Trace ID or -EINVAL if allocation is impossible. >>>> + */ >>>> +int coresight_trace_id_get_static_system_id(int id); >>>> + >>>> /** >>>> * Release an allocated system trace ID. >>>> * >>>> diff --git a/include/linux/coresight.h b/include/linux/coresight.h >>>> index c13342594278..129795873072 100644 >>>> --- a/include/linux/coresight.h >>>> +++ b/include/linux/coresight.h >>>> @@ -662,6 +662,7 @@ void coresight_relaxed_write64(struct >>>> coresight_device *csdev, >>>> void coresight_write64(struct coresight_device *csdev, u64 val, >>>> u32 offset); >>>> extern int coresight_get_cpu(struct device *dev); >>>> +extern int coresight_get_static_trace_id(struct device *dev, u32 *id); >>>> struct coresight_platform_data *coresight_get_platform_data(struct >>>> device *dev); >>>> struct coresight_connection * >>> >> >
diff --git a/drivers/hwtracing/coresight/coresight-platform.c b/drivers/hwtracing/coresight/coresight-platform.c index 64e171eaad82..633d96b9577a 100644 --- a/drivers/hwtracing/coresight/coresight-platform.c +++ b/drivers/hwtracing/coresight/coresight-platform.c @@ -796,6 +796,12 @@ int coresight_get_cpu(struct device *dev) } EXPORT_SYMBOL_GPL(coresight_get_cpu); +int coresight_get_static_trace_id(struct device *dev, u32 *id) +{ + return fwnode_property_read_u32(dev_fwnode(dev), "arm,static-trace-id", id); +} +EXPORT_SYMBOL_GPL(coresight_get_static_trace_id); + struct coresight_platform_data * coresight_get_platform_data(struct device *dev) { diff --git a/drivers/hwtracing/coresight/coresight-trace-id.c b/drivers/hwtracing/coresight/coresight-trace-id.c index d98e12cb30ec..df8fe50b413f 100644 --- a/drivers/hwtracing/coresight/coresight-trace-id.c +++ b/drivers/hwtracing/coresight/coresight-trace-id.c @@ -12,6 +12,12 @@ #include "coresight-trace-id.h" +enum trace_id_flags { + TRACE_ID_ANY = 0x0, + TRACE_ID_PREFER_ODD = 0x1, + TRACE_ID_REQ_STATIC = 0x2, +}; + /* Default trace ID map. Used in sysfs mode and for system sources */ static DEFINE_PER_CPU(atomic_t, id_map_default_cpu_ids) = ATOMIC_INIT(0); static struct coresight_trace_id_map id_map_default = { @@ -74,16 +80,18 @@ static int coresight_trace_id_find_odd_id(struct coresight_trace_id_map *id_map) * Otherwise allocate next available ID. */ static int coresight_trace_id_alloc_new_id(struct coresight_trace_id_map *id_map, - int preferred_id, bool prefer_odd_id) + int preferred_id, unsigned int flags) { int id = 0; /* for backwards compatibility, cpu IDs may use preferred value */ - if (IS_VALID_CS_TRACE_ID(preferred_id) && - !test_bit(preferred_id, id_map->used_ids)) { - id = preferred_id; - goto trace_id_allocated; - } else if (prefer_odd_id) { + if (IS_VALID_CS_TRACE_ID(preferred_id)) { + if (!test_bit(preferred_id, id_map->used_ids)) { + id = preferred_id; + goto trace_id_allocated; + } else if (flags & TRACE_ID_REQ_STATIC) + return -EINVAL; + } else if (flags & TRACE_ID_PREFER_ODD) { /* may use odd ids to avoid preferred legacy cpu IDs */ id = coresight_trace_id_find_odd_id(id_map); if (id) @@ -153,7 +161,7 @@ static int _coresight_trace_id_get_cpu_id(int cpu, struct coresight_trace_id_map */ id = coresight_trace_id_alloc_new_id(id_map, CORESIGHT_LEGACY_CPU_TRACE_ID(cpu), - false); + TRACE_ID_ANY); if (!IS_VALID_CS_TRACE_ID(id)) goto get_cpu_id_out_unlock; @@ -188,14 +196,14 @@ static void _coresight_trace_id_put_cpu_id(int cpu, struct coresight_trace_id_ma DUMP_ID_MAP(id_map); } -static int coresight_trace_id_map_get_system_id(struct coresight_trace_id_map *id_map) +static int coresight_trace_id_map_get_system_id(struct coresight_trace_id_map *id_map, + int preferred_id, unsigned int traceid_flags) { unsigned long flags; int id; spin_lock_irqsave(&id_map->lock, flags); - /* prefer odd IDs for system components to avoid legacy CPU IDS */ - id = coresight_trace_id_alloc_new_id(id_map, 0, true); + id = coresight_trace_id_alloc_new_id(id_map, preferred_id, traceid_flags); spin_unlock_irqrestore(&id_map->lock, flags); DUMP_ID(id); @@ -255,10 +263,19 @@ EXPORT_SYMBOL_GPL(coresight_trace_id_read_cpu_id_map); int coresight_trace_id_get_system_id(void) { - return coresight_trace_id_map_get_system_id(&id_map_default); + /* prefer odd IDs for system components to avoid legacy CPU IDS */ + return coresight_trace_id_map_get_system_id(&id_map_default, 0, + TRACE_ID_PREFER_ODD); } EXPORT_SYMBOL_GPL(coresight_trace_id_get_system_id); +int coresight_trace_id_get_static_system_id(int trace_id) +{ + return coresight_trace_id_map_get_system_id(&id_map_default, + trace_id, TRACE_ID_REQ_STATIC); +} +EXPORT_SYMBOL_GPL(coresight_trace_id_get_static_system_id); + void coresight_trace_id_put_system_id(int id) { coresight_trace_id_map_put_system_id(&id_map_default, id); diff --git a/drivers/hwtracing/coresight/coresight-trace-id.h b/drivers/hwtracing/coresight/coresight-trace-id.h index 9aae50a553ca..db68e1ec56b6 100644 --- a/drivers/hwtracing/coresight/coresight-trace-id.h +++ b/drivers/hwtracing/coresight/coresight-trace-id.h @@ -116,6 +116,15 @@ int coresight_trace_id_read_cpu_id_map(int cpu, struct coresight_trace_id_map *i */ int coresight_trace_id_get_system_id(void); +/** + * Allocate a CoreSight static trace ID for a system component. + * + * Used to allocate static IDs for system trace sources such as dummy source. + * + * return: Trace ID or -EINVAL if allocation is impossible. + */ +int coresight_trace_id_get_static_system_id(int id); + /** * Release an allocated system trace ID. * diff --git a/include/linux/coresight.h b/include/linux/coresight.h index c13342594278..129795873072 100644 --- a/include/linux/coresight.h +++ b/include/linux/coresight.h @@ -662,6 +662,7 @@ void coresight_relaxed_write64(struct coresight_device *csdev, void coresight_write64(struct coresight_device *csdev, u64 val, u32 offset); extern int coresight_get_cpu(struct device *dev); +extern int coresight_get_static_trace_id(struct device *dev, u32 *id); struct coresight_platform_data *coresight_get_platform_data(struct device *dev); struct coresight_connection *