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

Configure Feed

Select the types of activity you want to include in your feed.

coresight-cti: change cti_drvdata spinlock's type to raw_spinlock_t

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

Since cti_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 cti_drvdata->spinlock in coresight-cti drivers,
which can be called by perf_event_task_sched_out()/in(),
from spinlock_t to raw_spinlock_t.

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

authored by

Yeoreum Yun and committed by
Suzuki K Poulose
e3044065 4cf364ca

+61 -61
+22 -22
drivers/hwtracing/coresight/coresight-cti-core.c
··· 93 93 unsigned long flags; 94 94 int rc = 0; 95 95 96 - spin_lock_irqsave(&drvdata->spinlock, flags); 96 + raw_spin_lock_irqsave(&drvdata->spinlock, flags); 97 97 98 98 /* no need to do anything if enabled or unpowered*/ 99 99 if (config->hw_enabled || !config->hw_powered) ··· 108 108 109 109 config->hw_enabled = true; 110 110 drvdata->config.enable_req_count++; 111 - spin_unlock_irqrestore(&drvdata->spinlock, flags); 111 + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); 112 112 return rc; 113 113 114 114 cti_state_unchanged: ··· 116 116 117 117 /* cannot enable due to error */ 118 118 cti_err_not_enabled: 119 - spin_unlock_irqrestore(&drvdata->spinlock, flags); 119 + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); 120 120 return rc; 121 121 } 122 122 ··· 125 125 { 126 126 struct cti_config *config = &drvdata->config; 127 127 128 - spin_lock(&drvdata->spinlock); 128 + raw_spin_lock(&drvdata->spinlock); 129 129 config->hw_powered = true; 130 130 131 131 /* no need to do anything if no enable request */ ··· 138 138 139 139 cti_write_all_hw_regs(drvdata); 140 140 config->hw_enabled = true; 141 - spin_unlock(&drvdata->spinlock); 141 + raw_spin_unlock(&drvdata->spinlock); 142 142 return; 143 143 144 144 /* did not re-enable due to no claim / no request */ 145 145 cti_hp_not_enabled: 146 - spin_unlock(&drvdata->spinlock); 146 + raw_spin_unlock(&drvdata->spinlock); 147 147 } 148 148 149 149 /* disable hardware */ ··· 153 153 struct coresight_device *csdev = drvdata->csdev; 154 154 int ret = 0; 155 155 156 - spin_lock(&drvdata->spinlock); 156 + raw_spin_lock(&drvdata->spinlock); 157 157 158 158 /* don't allow negative refcounts, return an error */ 159 159 if (!drvdata->config.enable_req_count) { ··· 177 177 178 178 coresight_disclaim_device_unlocked(csdev); 179 179 CS_LOCK(drvdata->base); 180 - spin_unlock(&drvdata->spinlock); 180 + raw_spin_unlock(&drvdata->spinlock); 181 181 return ret; 182 182 183 183 /* not disabled this call */ 184 184 cti_not_disabled: 185 - spin_unlock(&drvdata->spinlock); 185 + raw_spin_unlock(&drvdata->spinlock); 186 186 return ret; 187 187 } 188 188 ··· 198 198 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); 199 199 struct cti_config *config = &drvdata->config; 200 200 201 - spin_lock(&drvdata->spinlock); 201 + raw_spin_lock(&drvdata->spinlock); 202 202 /* write if enabled */ 203 203 if (cti_active(config)) 204 204 cti_write_single_reg(drvdata, CTIINTACK, ackval); 205 - spin_unlock(&drvdata->spinlock); 205 + raw_spin_unlock(&drvdata->spinlock); 206 206 } 207 207 208 208 /* ··· 369 369 reg_offset = (direction == CTI_TRIG_IN ? CTIINEN(trigger_idx) : 370 370 CTIOUTEN(trigger_idx)); 371 371 372 - spin_lock(&drvdata->spinlock); 372 + raw_spin_lock(&drvdata->spinlock); 373 373 374 374 /* read - modify write - the trigger / channel enable value */ 375 375 reg_value = direction == CTI_TRIG_IN ? config->ctiinen[trigger_idx] : ··· 388 388 /* write through if enabled */ 389 389 if (cti_active(config)) 390 390 cti_write_single_reg(drvdata, reg_offset, reg_value); 391 - spin_unlock(&drvdata->spinlock); 391 + raw_spin_unlock(&drvdata->spinlock); 392 392 return 0; 393 393 } 394 394 ··· 406 406 407 407 chan_bitmask = BIT(channel_idx); 408 408 409 - spin_lock(&drvdata->spinlock); 409 + raw_spin_lock(&drvdata->spinlock); 410 410 reg_value = config->ctigate; 411 411 switch (op) { 412 412 case CTI_GATE_CHAN_ENABLE: ··· 426 426 if (cti_active(config)) 427 427 cti_write_single_reg(drvdata, CTIGATE, reg_value); 428 428 } 429 - spin_unlock(&drvdata->spinlock); 429 + raw_spin_unlock(&drvdata->spinlock); 430 430 return err; 431 431 } 432 432 ··· 445 445 446 446 chan_bitmask = BIT(channel_idx); 447 447 448 - spin_lock(&drvdata->spinlock); 448 + raw_spin_lock(&drvdata->spinlock); 449 449 reg_value = config->ctiappset; 450 450 switch (op) { 451 451 case CTI_CHAN_SET: ··· 473 473 474 474 if ((err == 0) && cti_active(config)) 475 475 cti_write_single_reg(drvdata, reg_offset, reg_value); 476 - spin_unlock(&drvdata->spinlock); 476 + raw_spin_unlock(&drvdata->spinlock); 477 477 478 478 return err; 479 479 } ··· 676 676 if (WARN_ON_ONCE(drvdata->ctidev.cpu != cpu)) 677 677 return NOTIFY_BAD; 678 678 679 - spin_lock(&drvdata->spinlock); 679 + raw_spin_lock(&drvdata->spinlock); 680 680 681 681 switch (cmd) { 682 682 case CPU_PM_ENTER: ··· 716 716 } 717 717 718 718 cti_notify_exit: 719 - spin_unlock(&drvdata->spinlock); 719 + raw_spin_unlock(&drvdata->spinlock); 720 720 return notify_res; 721 721 } 722 722 ··· 743 743 if (!drvdata) 744 744 return 0; 745 745 746 - spin_lock(&drvdata->spinlock); 746 + raw_spin_lock(&drvdata->spinlock); 747 747 drvdata->config.hw_powered = false; 748 748 if (drvdata->config.hw_enabled) 749 749 coresight_disclaim_device(drvdata->csdev); 750 - spin_unlock(&drvdata->spinlock); 750 + raw_spin_unlock(&drvdata->spinlock); 751 751 return 0; 752 752 } 753 753 ··· 888 888 drvdata->ctidev.ctm_id = 0; 889 889 INIT_LIST_HEAD(&drvdata->ctidev.trig_cons); 890 890 891 - spin_lock_init(&drvdata->spinlock); 891 + raw_spin_lock_init(&drvdata->spinlock); 892 892 893 893 /* initialise CTI driver config values */ 894 894 cti_set_default_config(dev, drvdata);
+38 -38
drivers/hwtracing/coresight/coresight-cti-sysfs.c
··· 84 84 bool enabled, powered; 85 85 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); 86 86 87 - spin_lock(&drvdata->spinlock); 87 + raw_spin_lock(&drvdata->spinlock); 88 88 enable_req = drvdata->config.enable_req_count; 89 89 powered = drvdata->config.hw_powered; 90 90 enabled = drvdata->config.hw_enabled; 91 - spin_unlock(&drvdata->spinlock); 91 + raw_spin_unlock(&drvdata->spinlock); 92 92 93 93 if (powered) 94 94 return sprintf(buf, "%d\n", enabled); ··· 134 134 bool powered; 135 135 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); 136 136 137 - spin_lock(&drvdata->spinlock); 137 + raw_spin_lock(&drvdata->spinlock); 138 138 powered = drvdata->config.hw_powered; 139 - spin_unlock(&drvdata->spinlock); 139 + raw_spin_unlock(&drvdata->spinlock); 140 140 141 141 return sprintf(buf, "%d\n", powered); 142 142 } ··· 181 181 u32 val = 0; 182 182 183 183 pm_runtime_get_sync(dev->parent); 184 - spin_lock(&drvdata->spinlock); 184 + raw_spin_lock(&drvdata->spinlock); 185 185 if (drvdata->config.hw_powered) 186 186 val = readl_relaxed(drvdata->base + cti_attr->off); 187 - spin_unlock(&drvdata->spinlock); 187 + raw_spin_unlock(&drvdata->spinlock); 188 188 pm_runtime_put_sync(dev->parent); 189 189 return sysfs_emit(buf, "0x%x\n", val); 190 190 } ··· 202 202 return -EINVAL; 203 203 204 204 pm_runtime_get_sync(dev->parent); 205 - spin_lock(&drvdata->spinlock); 205 + raw_spin_lock(&drvdata->spinlock); 206 206 if (drvdata->config.hw_powered) 207 207 cti_write_single_reg(drvdata, cti_attr->off, val); 208 - spin_unlock(&drvdata->spinlock); 208 + raw_spin_unlock(&drvdata->spinlock); 209 209 pm_runtime_put_sync(dev->parent); 210 210 return size; 211 211 } ··· 264 264 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); 265 265 struct cti_config *config = &drvdata->config; 266 266 267 - spin_lock(&drvdata->spinlock); 267 + raw_spin_lock(&drvdata->spinlock); 268 268 if ((reg_offset >= 0) && cti_active(config)) { 269 269 CS_UNLOCK(drvdata->base); 270 270 val = readl_relaxed(drvdata->base + reg_offset); ··· 274 274 } else if (pcached_val) { 275 275 val = *pcached_val; 276 276 } 277 - spin_unlock(&drvdata->spinlock); 277 + raw_spin_unlock(&drvdata->spinlock); 278 278 return sprintf(buf, "%#x\n", val); 279 279 } 280 280 ··· 293 293 if (kstrtoul(buf, 0, &val)) 294 294 return -EINVAL; 295 295 296 - spin_lock(&drvdata->spinlock); 296 + raw_spin_lock(&drvdata->spinlock); 297 297 /* local store */ 298 298 if (pcached_val) 299 299 *pcached_val = (u32)val; ··· 301 301 /* write through if offset and enabled */ 302 302 if ((reg_offset >= 0) && cti_active(config)) 303 303 cti_write_single_reg(drvdata, reg_offset, val); 304 - spin_unlock(&drvdata->spinlock); 304 + raw_spin_unlock(&drvdata->spinlock); 305 305 return size; 306 306 } 307 307 ··· 349 349 if (val > (CTIINOUTEN_MAX - 1)) 350 350 return -EINVAL; 351 351 352 - spin_lock(&drvdata->spinlock); 352 + raw_spin_lock(&drvdata->spinlock); 353 353 drvdata->config.ctiinout_sel = val; 354 - spin_unlock(&drvdata->spinlock); 354 + raw_spin_unlock(&drvdata->spinlock); 355 355 return size; 356 356 } 357 357 static DEVICE_ATTR_RW(inout_sel); ··· 364 364 int index; 365 365 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); 366 366 367 - spin_lock(&drvdata->spinlock); 367 + raw_spin_lock(&drvdata->spinlock); 368 368 index = drvdata->config.ctiinout_sel; 369 369 val = drvdata->config.ctiinen[index]; 370 - spin_unlock(&drvdata->spinlock); 370 + raw_spin_unlock(&drvdata->spinlock); 371 371 return sprintf(buf, "%#lx\n", val); 372 372 } 373 373 ··· 383 383 if (kstrtoul(buf, 0, &val)) 384 384 return -EINVAL; 385 385 386 - spin_lock(&drvdata->spinlock); 386 + raw_spin_lock(&drvdata->spinlock); 387 387 index = config->ctiinout_sel; 388 388 config->ctiinen[index] = val; 389 389 390 390 /* write through if enabled */ 391 391 if (cti_active(config)) 392 392 cti_write_single_reg(drvdata, CTIINEN(index), val); 393 - spin_unlock(&drvdata->spinlock); 393 + raw_spin_unlock(&drvdata->spinlock); 394 394 return size; 395 395 } 396 396 static DEVICE_ATTR_RW(inen); ··· 403 403 int index; 404 404 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); 405 405 406 - spin_lock(&drvdata->spinlock); 406 + raw_spin_lock(&drvdata->spinlock); 407 407 index = drvdata->config.ctiinout_sel; 408 408 val = drvdata->config.ctiouten[index]; 409 - spin_unlock(&drvdata->spinlock); 409 + raw_spin_unlock(&drvdata->spinlock); 410 410 return sprintf(buf, "%#lx\n", val); 411 411 } 412 412 ··· 422 422 if (kstrtoul(buf, 0, &val)) 423 423 return -EINVAL; 424 424 425 - spin_lock(&drvdata->spinlock); 425 + raw_spin_lock(&drvdata->spinlock); 426 426 index = config->ctiinout_sel; 427 427 config->ctiouten[index] = val; 428 428 429 429 /* write through if enabled */ 430 430 if (cti_active(config)) 431 431 cti_write_single_reg(drvdata, CTIOUTEN(index), val); 432 - spin_unlock(&drvdata->spinlock); 432 + raw_spin_unlock(&drvdata->spinlock); 433 433 return size; 434 434 } 435 435 static DEVICE_ATTR_RW(outen); ··· 463 463 if (kstrtoul(buf, 0, &val)) 464 464 return -EINVAL; 465 465 466 - spin_lock(&drvdata->spinlock); 466 + raw_spin_lock(&drvdata->spinlock); 467 467 468 468 /* a 1'b1 in appclr clears down the same bit in appset*/ 469 469 config->ctiappset &= ~val; ··· 471 471 /* write through if enabled */ 472 472 if (cti_active(config)) 473 473 cti_write_single_reg(drvdata, CTIAPPCLEAR, val); 474 - spin_unlock(&drvdata->spinlock); 474 + raw_spin_unlock(&drvdata->spinlock); 475 475 return size; 476 476 } 477 477 static DEVICE_ATTR_WO(appclear); ··· 487 487 if (kstrtoul(buf, 0, &val)) 488 488 return -EINVAL; 489 489 490 - spin_lock(&drvdata->spinlock); 490 + raw_spin_lock(&drvdata->spinlock); 491 491 492 492 /* write through if enabled */ 493 493 if (cti_active(config)) 494 494 cti_write_single_reg(drvdata, CTIAPPPULSE, val); 495 - spin_unlock(&drvdata->spinlock); 495 + raw_spin_unlock(&drvdata->spinlock); 496 496 return size; 497 497 } 498 498 static DEVICE_ATTR_WO(apppulse); ··· 681 681 u32 val; 682 682 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); 683 683 684 - spin_lock(&drvdata->spinlock); 684 + raw_spin_lock(&drvdata->spinlock); 685 685 val = drvdata->config.trig_filter_enable; 686 - spin_unlock(&drvdata->spinlock); 686 + raw_spin_unlock(&drvdata->spinlock); 687 687 return sprintf(buf, "%d\n", val); 688 688 } 689 689 ··· 697 697 if (kstrtoul(buf, 0, &val)) 698 698 return -EINVAL; 699 699 700 - spin_lock(&drvdata->spinlock); 700 + raw_spin_lock(&drvdata->spinlock); 701 701 drvdata->config.trig_filter_enable = !!val; 702 - spin_unlock(&drvdata->spinlock); 702 + raw_spin_unlock(&drvdata->spinlock); 703 703 return size; 704 704 } 705 705 static DEVICE_ATTR_RW(trig_filter_enable); ··· 728 728 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); 729 729 struct cti_config *config = &drvdata->config; 730 730 731 - spin_lock(&drvdata->spinlock); 731 + raw_spin_lock(&drvdata->spinlock); 732 732 733 733 /* clear the CTI trigger / channel programming registers */ 734 734 for (i = 0; i < config->nr_trig_max; i++) { ··· 747 747 if (cti_active(config)) 748 748 cti_write_all_hw_regs(drvdata); 749 749 750 - spin_unlock(&drvdata->spinlock); 750 + raw_spin_unlock(&drvdata->spinlock); 751 751 return size; 752 752 } 753 753 static DEVICE_ATTR_WO(chan_xtrigs_reset); ··· 768 768 if (val > (drvdata->config.nr_ctm_channels - 1)) 769 769 return -EINVAL; 770 770 771 - spin_lock(&drvdata->spinlock); 771 + raw_spin_lock(&drvdata->spinlock); 772 772 drvdata->config.xtrig_rchan_sel = val; 773 - spin_unlock(&drvdata->spinlock); 773 + raw_spin_unlock(&drvdata->spinlock); 774 774 return size; 775 775 } 776 776 ··· 781 781 unsigned long val; 782 782 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); 783 783 784 - spin_lock(&drvdata->spinlock); 784 + raw_spin_lock(&drvdata->spinlock); 785 785 val = drvdata->config.xtrig_rchan_sel; 786 - spin_unlock(&drvdata->spinlock); 786 + raw_spin_unlock(&drvdata->spinlock); 787 787 788 788 return sprintf(buf, "%ld\n", val); 789 789 } ··· 838 838 unsigned long inuse_bits = 0, chan_mask; 839 839 840 840 /* scan regs to get bitmap of channels in use. */ 841 - spin_lock(&drvdata->spinlock); 841 + raw_spin_lock(&drvdata->spinlock); 842 842 for (i = 0; i < config->nr_trig_max; i++) { 843 843 inuse_bits |= config->ctiinen[i]; 844 844 inuse_bits |= config->ctiouten[i]; 845 845 } 846 - spin_unlock(&drvdata->spinlock); 846 + raw_spin_unlock(&drvdata->spinlock); 847 847 848 848 /* inverse bits if printing free channels */ 849 849 if (!inuse)
+1 -1
drivers/hwtracing/coresight/coresight-cti.h
··· 175 175 void __iomem *base; 176 176 struct coresight_device *csdev; 177 177 struct cti_device ctidev; 178 - spinlock_t spinlock; 178 + raw_spinlock_t spinlock; 179 179 struct cti_config config; 180 180 struct list_head node; 181 181 void (*csdev_release)(struct device *dev);