diff mbox series

[v6,2/3] coresight: Add support to get static id for system trace sources

Message ID 20241104115604.14522-3-quic_jinlmao@quicinc.com (mailing list archive)
State Superseded
Headers show
Series coresight: Add static trace id support | expand

Commit Message

Mao Jinlong Nov. 4, 2024, 11:56 a.m. UTC
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(-)

Comments

Suzuki K Poulose Nov. 13, 2024, 1:27 p.m. UTC | #1
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 *
Mao Jinlong Nov. 18, 2024, 10:14 a.m. UTC | #2
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 *
>
Suzuki K Poulose Nov. 18, 2024, 10:18 a.m. UTC | #3
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 *
>>
>
Mao Jinlong Nov. 19, 2024, 10:38 a.m. UTC | #4
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 mbox series

Patch

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 *