Skip to content

Commit a9aecef

Browse files
pawellcdnsPeter Chen
authored andcommitted
usb: cdnsp: Fix deadlock issue in cdnsp_thread_irq_handler
Patch fixes the following critical issue caused by deadlock which has been detected during testing NCM class: smp: csd: Detected non-responsive CSD lock (#1) on CPU#0 smp: csd: CSD lock (#1) unresponsive. .... RIP: 0010:native_queued_spin_lock_slowpath+0x61/0x1d0 RSP: 0018:ffffbc494011cde0 EFLAGS: 00000002 RAX: 0000000000000101 RBX: ffff9ee8116b4a68 RCX: 0000000000000000 RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffff9ee8116b4658 RBP: ffffbc494011cde0 R08: 0000000000000001 R09: 0000000000000000 R10: ffff9ee8116b4670 R11: 0000000000000000 R12: ffff9ee8116b4658 R13: ffff9ee8116b4670 R14: 0000000000000246 R15: ffff9ee8116b4658 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f7bcc41a830 CR3: 000000007a612003 CR4: 00000000001706e0 Call Trace: <IRQ> do_raw_spin_lock+0xc0/0xd0 _raw_spin_lock_irqsave+0x95/0xa0 cdnsp_gadget_ep_queue.cold+0x88/0x107 [cdnsp_udc_pci] usb_ep_queue+0x35/0x110 eth_start_xmit+0x220/0x3d0 [u_ether] ncm_tx_timeout+0x34/0x40 [usb_f_ncm] ? ncm_free_inst+0x50/0x50 [usb_f_ncm] __hrtimer_run_queues+0xac/0x440 hrtimer_run_softirq+0x8c/0xb0 __do_softirq+0xcf/0x428 asm_call_irq_on_stack+0x12/0x20 </IRQ> do_softirq_own_stack+0x61/0x70 irq_exit_rcu+0xc1/0xd0 sysvec_apic_timer_interrupt+0x52/0xb0 asm_sysvec_apic_timer_interrupt+0x12/0x20 RIP: 0010:do_raw_spin_trylock+0x18/0x40 RSP: 0018:ffffbc494138bda8 EFLAGS: 00000246 RAX: 0000000000000000 RBX: ffff9ee8116b4658 RCX: 0000000000000000 RDX: 0000000000000001 RSI: 0000000000000000 RDI: ffff9ee8116b4658 RBP: ffffbc494138bda8 R08: 0000000000000001 R09: 0000000000000000 R10: ffff9ee8116b4670 R11: 0000000000000000 R12: ffff9ee8116b4658 R13: ffff9ee8116b4670 R14: ffff9ee7b5c73d80 R15: ffff9ee8116b4000 _raw_spin_lock+0x3d/0x70 ? cdnsp_thread_irq_handler.cold+0x32/0x112c [cdnsp_udc_pci] cdnsp_thread_irq_handler.cold+0x32/0x112c [cdnsp_udc_pci] ? cdnsp_remove_request+0x1f0/0x1f0 [cdnsp_udc_pci] ? cdnsp_thread_irq_handler+0x5/0xa0 [cdnsp_udc_pci] ? irq_thread+0xa0/0x1c0 irq_thread_fn+0x28/0x60 irq_thread+0x105/0x1c0 ? __kthread_parkme+0x42/0x90 ? irq_forced_thread_fn+0x90/0x90 ? wake_threads_waitq+0x30/0x30 ? irq_thread_check_affinity+0xe0/0xe0 kthread+0x12a/0x160 ? kthread_park+0x90/0x90 ret_from_fork+0x22/0x30 The root cause of issue is spin_lock/spin_unlock instruction instead spin_lock_irqsave/spin_lock_irqrestore in cdnsp_thread_irq_handler function. Cc: stable@vger.kernel.org Fixes: 3d82904 ("usb: cdnsp: cdns3 Add main part of Cadence USBSSP DRD Driver") Signed-off-by: Pawel Laszczak <pawell@cadence.com> Link: https://lore.kernel.org/r/20210526060527.7197-1-pawell@gli-login.cadence.com Signed-off-by: Peter Chen <peter.chen@kernel.org>
1 parent d6eef88 commit a9aecef

File tree

1 file changed

+4
-3
lines changed

1 file changed

+4
-3
lines changed

drivers/usb/cdns3/cdnsp-ring.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1517,13 +1517,14 @@ irqreturn_t cdnsp_thread_irq_handler(int irq, void *data)
15171517
{
15181518
struct cdnsp_device *pdev = (struct cdnsp_device *)data;
15191519
union cdnsp_trb *event_ring_deq;
1520+
unsigned long flags;
15201521
int counter = 0;
15211522

1522-
spin_lock(&pdev->lock);
1523+
spin_lock_irqsave(&pdev->lock, flags);
15231524

15241525
if (pdev->cdnsp_state & (CDNSP_STATE_HALTED | CDNSP_STATE_DYING)) {
15251526
cdnsp_died(pdev);
1526-
spin_unlock(&pdev->lock);
1527+
spin_unlock_irqrestore(&pdev->lock, flags);
15271528
return IRQ_HANDLED;
15281529
}
15291530

@@ -1539,7 +1540,7 @@ irqreturn_t cdnsp_thread_irq_handler(int irq, void *data)
15391540

15401541
cdnsp_update_erst_dequeue(pdev, event_ring_deq, 1);
15411542

1542-
spin_unlock(&pdev->lock);
1543+
spin_unlock_irqrestore(&pdev->lock, flags);
15431544

15441545
return IRQ_HANDLED;
15451546
}

0 commit comments

Comments
 (0)