Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

coresight-funnel: change funnel_drvdata spinlock's type to raw_spinlock_t

In coresight-funnel drivers, cti_drvdata->spinlock can be held
during __schedule() by perf_event_task_sched_out()/in().

Since funnel_drvdata->spinlock type is spinlock_t and
perf_event_task_sched_out()/in() is called after acquiring rq_lock,
which is raw_spinlock_t (an unsleepable lock),
this poses an issue in PREEMPT_RT kernel where spinlock_t is sleepable.

To address this, change type funnel_drvdata->spinlock in
coresight-funnel drivers, which can be called by
perf_event_task_sched_out()/in(), from spinlock_t to raw_spinlock_t.

Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
Reviewed-by: James Clark <james.clark@linaro.org>
Reviewed-by: Mike Leach <mike.leach@linaro.org>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Link: https://lore.kernel.org/r/20250306121110.1647948-7-yeoreum.yun@arm.com

authored by

Yeoreum Yun and committed by
Suzuki K Poulose
56eb02f0 6b80c0ab

+6 -6
+6 -6
drivers/hwtracing/coresight/coresight-funnel.c
··· 47 47 struct clk *pclk; 48 48 struct coresight_device *csdev; 49 49 unsigned long priority; 50 - spinlock_t spinlock; 50 + raw_spinlock_t spinlock; 51 51 }; 52 52 53 53 static int dynamic_funnel_enable_hw(struct funnel_drvdata *drvdata, int port) ··· 85 85 unsigned long flags; 86 86 bool first_enable = false; 87 87 88 - spin_lock_irqsave(&drvdata->spinlock, flags); 88 + raw_spin_lock_irqsave(&drvdata->spinlock, flags); 89 89 if (in->dest_refcnt == 0) { 90 90 if (drvdata->base) 91 91 rc = dynamic_funnel_enable_hw(drvdata, in->dest_port); ··· 94 94 } 95 95 if (!rc) 96 96 in->dest_refcnt++; 97 - spin_unlock_irqrestore(&drvdata->spinlock, flags); 97 + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); 98 98 99 99 if (first_enable) 100 100 dev_dbg(&csdev->dev, "FUNNEL inport %d enabled\n", ··· 129 129 unsigned long flags; 130 130 bool last_disable = false; 131 131 132 - spin_lock_irqsave(&drvdata->spinlock, flags); 132 + raw_spin_lock_irqsave(&drvdata->spinlock, flags); 133 133 if (--in->dest_refcnt == 0) { 134 134 if (drvdata->base) 135 135 dynamic_funnel_disable_hw(drvdata, in->dest_port); 136 136 last_disable = true; 137 137 } 138 - spin_unlock_irqrestore(&drvdata->spinlock, flags); 138 + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); 139 139 140 140 if (last_disable) 141 141 dev_dbg(&csdev->dev, "FUNNEL inport %d disabled\n", ··· 266 266 } 267 267 dev->platform_data = pdata; 268 268 269 - spin_lock_init(&drvdata->spinlock); 269 + raw_spin_lock_init(&drvdata->spinlock); 270 270 desc.type = CORESIGHT_DEV_TYPE_LINK; 271 271 desc.subtype.link_subtype = CORESIGHT_DEV_SUBTYPE_LINK_MERG; 272 272 desc.ops = &funnel_cs_ops;