Commit d11eb31d authored by Yeoreum Yun's avatar Yeoreum Yun Committed by Suzuki K Poulose
Browse files

coresight/ultrasoc: change smb_drv_data spinlock's type to raw_spinlock_t



In ultrasoc-smb drivers, smb_drv_data->spinlock can be held
during __schedule() by perf_event_task_sched_out()/in().

Since smb__drv_data->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 smb_drv_data->spinlock in ultrasoc-smb drivers,
which can be called by perf_event_task_sched_out()/in(),
from spinlock_t to raw_spinlock_t.

Reviewed-by: default avatarJames Clark <james.clark@linaro.org>
Signed-off-by: default avatarYeoreum Yun <yeoreum.yun@arm.com>
Signed-off-by: default avatarSuzuki K Poulose <suzuki.poulose@arm.com>
Link: https://lore.kernel.org/r/20250306121110.1647948-10-yeoreum.yun@arm.com
parent db11f75b
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -98,7 +98,7 @@ static int smb_open(struct inode *inode, struct file *file)
	struct smb_drv_data *drvdata = container_of(file->private_data,
					struct smb_drv_data, miscdev);

	guard(spinlock)(&drvdata->spinlock);
	guard(raw_spinlock)(&drvdata->spinlock);

	if (drvdata->reading)
		return -EBUSY;
@@ -152,7 +152,7 @@ static int smb_release(struct inode *inode, struct file *file)
	struct smb_drv_data *drvdata = container_of(file->private_data,
					struct smb_drv_data, miscdev);

	guard(spinlock)(&drvdata->spinlock);
	guard(raw_spinlock)(&drvdata->spinlock);
	drvdata->reading = false;

	return 0;
@@ -245,7 +245,7 @@ static int smb_enable(struct coresight_device *csdev, enum cs_mode mode,
	struct smb_drv_data *drvdata = dev_get_drvdata(csdev->dev.parent);
	int ret = 0;

	guard(spinlock)(&drvdata->spinlock);
	guard(raw_spinlock)(&drvdata->spinlock);

	/* Do nothing, the trace data is reading by other interface now */
	if (drvdata->reading)
@@ -280,7 +280,7 @@ static int smb_disable(struct coresight_device *csdev)
{
	struct smb_drv_data *drvdata = dev_get_drvdata(csdev->dev.parent);

	guard(spinlock)(&drvdata->spinlock);
	guard(raw_spinlock)(&drvdata->spinlock);

	if (drvdata->reading)
		return -EBUSY;
@@ -378,7 +378,7 @@ static unsigned long smb_update_buffer(struct coresight_device *csdev,
	if (!buf)
		return 0;

	guard(spinlock)(&drvdata->spinlock);
	guard(raw_spinlock)(&drvdata->spinlock);

	/* Don't do anything if another tracer is using this sink. */
	if (csdev->refcnt != 1)
@@ -563,7 +563,7 @@ static int smb_probe(struct platform_device *pdev)

	smb_reset_buffer(drvdata);
	platform_set_drvdata(pdev, drvdata);
	spin_lock_init(&drvdata->spinlock);
	raw_spin_lock_init(&drvdata->spinlock);
	drvdata->pid = -1;

	ret = smb_register_sink(pdev, drvdata);
+1 −1
Original line number Diff line number Diff line
@@ -115,7 +115,7 @@ struct smb_drv_data {
	struct coresight_device	*csdev;
	struct smb_data_buffer sdb;
	struct miscdevice miscdev;
	spinlock_t spinlock;
	raw_spinlock_t spinlock;
	bool reading;
	pid_t pid;
};