Skip to content

Commit 6c50384

Browse files
Yicong YangSuzuki K Poulose
authored andcommitted
hwtracing: hisi_ptt: Fix potential sleep in atomic context
We're using pci_irq_vector() to obtain the interrupt number and then bind it to the CPU start perf under the protection of spinlock in pmu::start(). pci_irq_vector() might sleep since [1] because it will call msi_domain_get_virq() to get the MSI interrupt number and it needs to acquire dev->msi.data->mutex. Getting a mutex will sleep on contention. So use pci_irq_vector() in an atomic context is problematic. This patch cached the interrupt number in the probe() and uses the cached data instead to avoid potential sleep. [1] commit 82ff8e6 ("PCI/MSI: Use msi_get_virq() in pci_get_vector()") Fixes: ff0de06 ("hwtracing: hisi_ptt: Add trace function support for HiSilicon PCIe Tune and Trace device") Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Signed-off-by: Yicong Yang <yangyicong@hisilicon.com> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> Link: https://lore.kernel.org/r/20230621092804.15120-6-yangyicong@huawei.com
1 parent 45c9029 commit 6c50384

2 files changed

Lines changed: 7 additions & 7 deletions

File tree

drivers/hwtracing/ptt/hisi_ptt.c

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -341,13 +341,13 @@ static int hisi_ptt_register_irq(struct hisi_ptt *hisi_ptt)
341341
if (ret < 0)
342342
return ret;
343343

344-
ret = devm_request_threaded_irq(&pdev->dev,
345-
pci_irq_vector(pdev, HISI_PTT_TRACE_DMA_IRQ),
344+
hisi_ptt->trace_irq = pci_irq_vector(pdev, HISI_PTT_TRACE_DMA_IRQ);
345+
ret = devm_request_threaded_irq(&pdev->dev, hisi_ptt->trace_irq,
346346
NULL, hisi_ptt_isr, 0,
347347
DRV_NAME, hisi_ptt);
348348
if (ret) {
349349
pci_err(pdev, "failed to request irq %d, ret = %d\n",
350-
pci_irq_vector(pdev, HISI_PTT_TRACE_DMA_IRQ), ret);
350+
hisi_ptt->trace_irq, ret);
351351
return ret;
352352
}
353353

@@ -1098,8 +1098,7 @@ static void hisi_ptt_pmu_start(struct perf_event *event, int flags)
10981098
* core in event_function_local(). If CPU passed is offline we'll fail
10991099
* here, just log it since we can do nothing here.
11001100
*/
1101-
ret = irq_set_affinity(pci_irq_vector(hisi_ptt->pdev, HISI_PTT_TRACE_DMA_IRQ),
1102-
cpumask_of(cpu));
1101+
ret = irq_set_affinity(hisi_ptt->trace_irq, cpumask_of(cpu));
11031102
if (ret)
11041103
dev_warn(dev, "failed to set the affinity of trace interrupt\n");
11051104

@@ -1394,8 +1393,7 @@ static int hisi_ptt_cpu_teardown(unsigned int cpu, struct hlist_node *node)
13941393
* Also make sure the interrupt bind to the migrated CPU as well. Warn
13951394
* the user on failure here.
13961395
*/
1397-
if (irq_set_affinity(pci_irq_vector(hisi_ptt->pdev, HISI_PTT_TRACE_DMA_IRQ),
1398-
cpumask_of(target)))
1396+
if (irq_set_affinity(hisi_ptt->trace_irq, cpumask_of(target)))
13991397
dev_warn(dev, "failed to set the affinity of trace interrupt\n");
14001398

14011399
hisi_ptt->trace_ctrl.on_cpu = target;

drivers/hwtracing/ptt/hisi_ptt.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ struct hisi_ptt_pmu_buf {
201201
* @pdev: pci_dev of this PTT device
202202
* @tune_lock: lock to serialize the tune process
203203
* @pmu_lock: lock to serialize the perf process
204+
* @trace_irq: interrupt number used by trace
204205
* @upper_bdf: the upper BDF range of the PCI devices managed by this PTT device
205206
* @lower_bdf: the lower BDF range of the PCI devices managed by this PTT device
206207
* @port_filters: the filter list of root ports
@@ -221,6 +222,7 @@ struct hisi_ptt {
221222
struct pci_dev *pdev;
222223
struct mutex tune_lock;
223224
spinlock_t pmu_lock;
225+
int trace_irq;
224226
u32 upper_bdf;
225227
u32 lower_bdf;
226228

0 commit comments

Comments
 (0)