[PATCH 12/25] coresight: trbe: Track per-CPU sink interrupt handling

James Clark james.clark at linaro.org
Mon Oct 19 04:54:11 PDT 2026



On 15/09/2026 16:48, Leo Yan wrote:
> A sampling NMI can interrupt TRBE while it is using the active AUX
> handle or buffer. Circular buffer mode avoids wrap interrupts but can
> still generate fault interrupts.
> 
> Add an in_interrupt flag to per-CPU sinks and set it around the TRBE IRQ
> handler. Compiler barriers keep AUX buffer accesses between the flag
> updates. This lets NMI callbacks detect when they have interrupted sink
> handling before modifying its state.
> 
> Assisted-by: Codex:gpt-6
> Signed-off-by: Leo Yan <leo.yan at arm.com>
> ---
>   drivers/hwtracing/coresight/coresight-trbe.c | 17 ++++++++++++++++-
>   include/linux/coresight.h                    |  2 ++
>   2 files changed, 18 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c
> index ab3c5c7d27f3d272b07eade1e6452559808b196c..8eb625d3fc99db57a18e35ef59ef814dacf20a09 100644
> --- a/drivers/hwtracing/coresight/coresight-trbe.c
> +++ b/drivers/hwtracing/coresight/coresight-trbe.c
> @@ -1185,7 +1185,7 @@ static u64 cpu_prohibit_trace(void)
>   	return trfcr;
>   }
>   
> -static irqreturn_t arm_trbe_irq_handler(int irq, void *dev)
> +static irqreturn_t __arm_trbe_irq_handler(int irq, void *dev)
>   {
>   	struct perf_output_handle **handle_ptr = dev;
>   	struct perf_output_handle *handle = *handle_ptr;
> @@ -1249,6 +1249,21 @@ static irqreturn_t arm_trbe_irq_handler(int irq, void *dev)
>   	return IRQ_HANDLED;
>   }
>   
> +static irqreturn_t arm_trbe_irq_handler(int irq, void *dev)
> +{
> +	struct coresight_device *csdev = coresight_get_percpu_sink(smp_processor_id());
> +	irqreturn_t ret;
> +
> +	/* Circular Buffer mode can still interrupt on a fault. */
> +	WRITE_ONCE(csdev->in_interrupt, true);
> +	barrier();
> +	ret = __arm_trbe_irq_handler(irq, dev);
> +	barrier();
> +	WRITE_ONCE(csdev->in_interrupt, false);
> +
> +	return ret;
> +}
> +
>   static int arm_trbe_save(struct coresight_device *csdev)
>   {
>   	struct trbe_cpudata *cpudata = dev_get_drvdata(&csdev->dev);
> diff --git a/include/linux/coresight.h b/include/linux/coresight.h
> index ddf18c970e343041787424c2019f2b5dd49154c2..8830c30be0df53a22525ef4fc3c7e41a0ec6fd90 100644
> --- a/include/linux/coresight.h
> +++ b/include/linux/coresight.h
> @@ -275,6 +275,7 @@ struct coresight_trace_id_map {
>    *		when a source has been selected and a path is enabled from
>    *		source to that sink. A sink can also become enabled but not
>    *		activated if it's used via Perf.
> + * @in_interrupt: Per-CPU sink interrupt handler is running.
>    * @ea:		Device attribute for sink representation under PMU directory.
>    * @def_sink:	cached reference to default sink found for this device.
>    * @nr_links:   number of sysfs links created to other components from this
> @@ -299,6 +300,7 @@ struct coresight_device {
>   	bool orphan;
>   	/* sink specific fields */
>   	bool sysfs_sink_activated;
> +	bool in_interrupt;
>   	struct dev_ext_attribute *ea;
>   	struct coresight_device *def_sink;
>   	struct coresight_trace_id_map perf_sink_id_map;
> 
Reviewed-by: James Clark <james.clark at linaro.org>




More information about the linux-arm-kernel mailing list