Skip to content

Commit db11f75

Browse files
LeviYeoReumSuzuki K Poulose
authored andcommitted
coresight-tmc: change tmc_drvdata spinlock's type to raw_spinlock_t
In coresight-tmc drivers, tmc_drvdata->spinlock can be held during __schedule() by perf_event_task_sched_out()/in(). Since tmc_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 tmc_drvdata->spinlock in coresight-tmc drivers, which can be called by perf_event_task_sched_out()/in(), from spinlock_t to raw_spinlock_t. Reviewed-by: James Clark <[email protected]> Reviewed-by: Mike Leach <[email protected]> Signed-off-by: Yeoreum Yun <[email protected]> Signed-off-by: Suzuki K Poulose <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 982d0a0 commit db11f75

File tree

4 files changed

+54
-54
lines changed

4 files changed

+54
-54
lines changed

drivers/hwtracing/coresight/coresight-tmc-core.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -358,12 +358,12 @@ static int tmc_crashdata_open(struct inode *inode, struct file *file)
358358
mdata = drvdata->crash_mdata.vaddr;
359359
rbuf = &drvdata->resrv_buf;
360360

361-
spin_lock_irqsave(&drvdata->spinlock, flags);
361+
raw_spin_lock_irqsave(&drvdata->spinlock, flags);
362362
if (mdata->valid)
363363
rbuf->reading = true;
364364
else
365365
err = -ENOENT;
366-
spin_unlock_irqrestore(&drvdata->spinlock, flags);
366+
raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
367367
if (err)
368368
goto exit;
369369

@@ -408,9 +408,9 @@ static int tmc_crashdata_release(struct inode *inode, struct file *file)
408408
crashdev);
409409

410410
rbuf = &drvdata->resrv_buf;
411-
spin_lock_irqsave(&drvdata->spinlock, flags);
411+
raw_spin_lock_irqsave(&drvdata->spinlock, flags);
412412
rbuf->reading = false;
413-
spin_unlock_irqrestore(&drvdata->spinlock, flags);
413+
raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
414414

415415
dev_dbg(&drvdata->csdev->dev, "%s: released\n", __func__);
416416
return ret;
@@ -801,7 +801,7 @@ static int __tmc_probe(struct device *dev, struct resource *res)
801801
drvdata->base = base;
802802
desc.access = CSDEV_ACCESS_IOMEM(base);
803803

804-
spin_lock_init(&drvdata->spinlock);
804+
raw_spin_lock_init(&drvdata->spinlock);
805805

806806
devid = readl_relaxed(drvdata->base + CORESIGHT_DEVID);
807807
drvdata->config_type = BMVAL(devid, 6, 7);
@@ -913,7 +913,7 @@ static void tmc_shutdown(struct amba_device *adev)
913913
unsigned long flags;
914914
struct tmc_drvdata *drvdata = amba_get_drvdata(adev);
915915

916-
spin_lock_irqsave(&drvdata->spinlock, flags);
916+
raw_spin_lock_irqsave(&drvdata->spinlock, flags);
917917

918918
if (coresight_get_mode(drvdata->csdev) == CS_MODE_DISABLED)
919919
goto out;
@@ -927,7 +927,7 @@ static void tmc_shutdown(struct amba_device *adev)
927927
* the system is going down after this.
928928
*/
929929
out:
930-
spin_unlock_irqrestore(&drvdata->spinlock, flags);
930+
raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
931931
}
932932

933933
static void __tmc_remove(struct device *dev)

drivers/hwtracing/coresight/coresight-tmc-etf.c

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -185,17 +185,17 @@ static int tmc_enable_etf_sink_sysfs(struct coresight_device *csdev)
185185
* If we don't have a buffer release the lock and allocate memory.
186186
* Otherwise keep the lock and move along.
187187
*/
188-
spin_lock_irqsave(&drvdata->spinlock, flags);
188+
raw_spin_lock_irqsave(&drvdata->spinlock, flags);
189189
if (!drvdata->buf) {
190-
spin_unlock_irqrestore(&drvdata->spinlock, flags);
190+
raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
191191

192192
/* Allocating the memory here while outside of the spinlock */
193193
buf = kzalloc(drvdata->size, GFP_KERNEL);
194194
if (!buf)
195195
return -ENOMEM;
196196

197197
/* Let's try again */
198-
spin_lock_irqsave(&drvdata->spinlock, flags);
198+
raw_spin_lock_irqsave(&drvdata->spinlock, flags);
199199
}
200200

201201
if (drvdata->reading) {
@@ -237,7 +237,7 @@ static int tmc_enable_etf_sink_sysfs(struct coresight_device *csdev)
237237
used = false;
238238
}
239239
out:
240-
spin_unlock_irqrestore(&drvdata->spinlock, flags);
240+
raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
241241

242242
/* Free memory outside the spinlock if need be */
243243
if (!used)
@@ -255,7 +255,7 @@ static int tmc_enable_etf_sink_perf(struct coresight_device *csdev, void *data)
255255
struct perf_output_handle *handle = data;
256256
struct cs_buffers *buf = etm_perf_sink_config(handle);
257257

258-
spin_lock_irqsave(&drvdata->spinlock, flags);
258+
raw_spin_lock_irqsave(&drvdata->spinlock, flags);
259259
do {
260260
ret = -EINVAL;
261261
if (drvdata->reading)
@@ -298,7 +298,7 @@ static int tmc_enable_etf_sink_perf(struct coresight_device *csdev, void *data)
298298
csdev->refcnt++;
299299
}
300300
} while (0);
301-
spin_unlock_irqrestore(&drvdata->spinlock, flags);
301+
raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
302302

303303
return ret;
304304
}
@@ -333,16 +333,16 @@ static int tmc_disable_etf_sink(struct coresight_device *csdev)
333333
unsigned long flags;
334334
struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
335335

336-
spin_lock_irqsave(&drvdata->spinlock, flags);
336+
raw_spin_lock_irqsave(&drvdata->spinlock, flags);
337337

338338
if (drvdata->reading) {
339-
spin_unlock_irqrestore(&drvdata->spinlock, flags);
339+
raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
340340
return -EBUSY;
341341
}
342342

343343
csdev->refcnt--;
344344
if (csdev->refcnt) {
345-
spin_unlock_irqrestore(&drvdata->spinlock, flags);
345+
raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
346346
return -EBUSY;
347347
}
348348

@@ -353,7 +353,7 @@ static int tmc_disable_etf_sink(struct coresight_device *csdev)
353353
drvdata->pid = -1;
354354
coresight_set_mode(csdev, CS_MODE_DISABLED);
355355

356-
spin_unlock_irqrestore(&drvdata->spinlock, flags);
356+
raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
357357

358358
dev_dbg(&csdev->dev, "TMC-ETB/ETF disabled\n");
359359
return 0;
@@ -368,9 +368,9 @@ static int tmc_enable_etf_link(struct coresight_device *csdev,
368368
struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
369369
bool first_enable = false;
370370

371-
spin_lock_irqsave(&drvdata->spinlock, flags);
371+
raw_spin_lock_irqsave(&drvdata->spinlock, flags);
372372
if (drvdata->reading) {
373-
spin_unlock_irqrestore(&drvdata->spinlock, flags);
373+
raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
374374
return -EBUSY;
375375
}
376376

@@ -383,7 +383,7 @@ static int tmc_enable_etf_link(struct coresight_device *csdev,
383383
}
384384
if (!ret)
385385
csdev->refcnt++;
386-
spin_unlock_irqrestore(&drvdata->spinlock, flags);
386+
raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
387387

388388
if (first_enable)
389389
dev_dbg(&csdev->dev, "TMC-ETF enabled\n");
@@ -398,9 +398,9 @@ static void tmc_disable_etf_link(struct coresight_device *csdev,
398398
struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
399399
bool last_disable = false;
400400

401-
spin_lock_irqsave(&drvdata->spinlock, flags);
401+
raw_spin_lock_irqsave(&drvdata->spinlock, flags);
402402
if (drvdata->reading) {
403-
spin_unlock_irqrestore(&drvdata->spinlock, flags);
403+
raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
404404
return;
405405
}
406406

@@ -410,7 +410,7 @@ static void tmc_disable_etf_link(struct coresight_device *csdev,
410410
coresight_set_mode(csdev, CS_MODE_DISABLED);
411411
last_disable = true;
412412
}
413-
spin_unlock_irqrestore(&drvdata->spinlock, flags);
413+
raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
414414

415415
if (last_disable)
416416
dev_dbg(&csdev->dev, "TMC-ETF disabled\n");
@@ -490,7 +490,7 @@ static unsigned long tmc_update_etf_buffer(struct coresight_device *csdev,
490490
if (WARN_ON_ONCE(coresight_get_mode(csdev) != CS_MODE_PERF))
491491
return 0;
492492

493-
spin_lock_irqsave(&drvdata->spinlock, flags);
493+
raw_spin_lock_irqsave(&drvdata->spinlock, flags);
494494

495495
/* Don't do anything if another tracer is using this sink */
496496
if (csdev->refcnt != 1)
@@ -587,7 +587,7 @@ static unsigned long tmc_update_etf_buffer(struct coresight_device *csdev,
587587
*/
588588
CS_LOCK(drvdata->base);
589589
out:
590-
spin_unlock_irqrestore(&drvdata->spinlock, flags);
590+
raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
591591

592592
return to_read;
593593
}
@@ -705,7 +705,7 @@ int tmc_read_prepare_etb(struct tmc_drvdata *drvdata)
705705
drvdata->config_type != TMC_CONFIG_TYPE_ETF))
706706
return -EINVAL;
707707

708-
spin_lock_irqsave(&drvdata->spinlock, flags);
708+
raw_spin_lock_irqsave(&drvdata->spinlock, flags);
709709

710710
if (drvdata->reading) {
711711
ret = -EBUSY;
@@ -737,7 +737,7 @@ int tmc_read_prepare_etb(struct tmc_drvdata *drvdata)
737737

738738
drvdata->reading = true;
739739
out:
740-
spin_unlock_irqrestore(&drvdata->spinlock, flags);
740+
raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
741741

742742
return ret;
743743
}
@@ -754,14 +754,14 @@ int tmc_read_unprepare_etb(struct tmc_drvdata *drvdata)
754754
drvdata->config_type != TMC_CONFIG_TYPE_ETF))
755755
return -EINVAL;
756756

757-
spin_lock_irqsave(&drvdata->spinlock, flags);
757+
raw_spin_lock_irqsave(&drvdata->spinlock, flags);
758758

759759
/* Re-enable the TMC if need be */
760760
if (coresight_get_mode(drvdata->csdev) == CS_MODE_SYSFS) {
761761
/* There is no point in reading a TMC in HW FIFO mode */
762762
mode = readl_relaxed(drvdata->base + TMC_MODE);
763763
if (mode != TMC_MODE_CIRCULAR_BUFFER) {
764-
spin_unlock_irqrestore(&drvdata->spinlock, flags);
764+
raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
765765
return -EINVAL;
766766
}
767767
/*
@@ -775,7 +775,7 @@ int tmc_read_unprepare_etb(struct tmc_drvdata *drvdata)
775775
memset(drvdata->buf, 0, drvdata->size);
776776
rc = __tmc_etb_enable_hw(drvdata);
777777
if (rc) {
778-
spin_unlock_irqrestore(&drvdata->spinlock, flags);
778+
raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
779779
return rc;
780780
}
781781
} else {
@@ -788,7 +788,7 @@ int tmc_read_unprepare_etb(struct tmc_drvdata *drvdata)
788788
}
789789

790790
drvdata->reading = false;
791-
spin_unlock_irqrestore(&drvdata->spinlock, flags);
791+
raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
792792

793793
/*
794794
* Free allocated memory outside of the spinlock. There is no need

0 commit comments

Comments
 (0)