Skip to content

Commit ce48f65

Browse files
LorenzoBianconigregkh
authored andcommitted
mt7601u: do not schedule rx_tasklet when the device has been disconnected
[ Upstream commit 4079e8c ] Do not schedule rx_tasklet when the usb dongle is disconnected. Moreover do not grub rx_lock in mt7601u_kill_rx since usb_poison_urb can run concurrently with urb completion and we can unlink urbs from rx ring in any order. This patch fixes the common kernel warning reported when the device is removed. [ 24.921354] usb 3-14: USB disconnect, device number 7 [ 24.921593] ------------[ cut here ]------------ [ 24.921594] RX urb mismatch [ 24.921675] WARNING: CPU: 4 PID: 163 at drivers/net/wireless/mediatek/mt7601u/dma.c:200 mt7601u_complete_rx+0xcb/0xd0 [mt7601u] [ 24.921769] CPU: 4 PID: 163 Comm: kworker/4:2 Tainted: G OE 4.19.31-041931-generic #201903231635 [ 24.921770] Hardware name: To Be Filled By O.E.M. To Be Filled By O.E.M./Z97 Extreme4, BIOS P1.30 05/23/2014 [ 24.921782] Workqueue: usb_hub_wq hub_event [ 24.921797] RIP: 0010:mt7601u_complete_rx+0xcb/0xd0 [mt7601u] [ 24.921800] RSP: 0018:ffff9bd9cfd03d08 EFLAGS: 00010086 [ 24.921802] RAX: 0000000000000000 RBX: ffff9bd9bf043540 RCX: 0000000000000006 [ 24.921803] RDX: 0000000000000007 RSI: 0000000000000096 RDI: ffff9bd9cfd16420 [ 24.921804] RBP: ffff9bd9cfd03d28 R08: 0000000000000002 R09: 00000000000003a8 [ 24.921805] R10: 0000002f485fca34 R11: 0000000000000000 R12: ffff9bd9bf043c1c [ 24.921806] R13: ffff9bd9c62fa3c0 R14: 0000000000000082 R15: 0000000000000000 [ 24.921807] FS: 0000000000000000(0000) GS:ffff9bd9cfd00000(0000) knlGS:0000000000000000 [ 24.921808] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 24.921808] CR2: 00007fb2648b0000 CR3: 0000000142c0a004 CR4: 00000000001606e0 [ 24.921809] Call Trace: [ 24.921812] <IRQ> [ 24.921819] __usb_hcd_giveback_urb+0x8b/0x140 [ 24.921821] usb_hcd_giveback_urb+0xca/0xe0 [ 24.921828] xhci_giveback_urb_in_irq.isra.42+0x82/0xf0 [ 24.921834] handle_cmd_completion+0xe02/0x10d0 [ 24.921837] xhci_irq+0x274/0x4a0 [ 24.921838] xhci_msi_irq+0x11/0x20 [ 24.921851] __handle_irq_event_percpu+0x44/0x190 [ 24.921856] handle_irq_event_percpu+0x32/0x80 [ 24.921861] handle_irq_event+0x3b/0x5a [ 24.921867] handle_edge_irq+0x80/0x190 [ 24.921874] handle_irq+0x20/0x30 [ 24.921889] do_IRQ+0x4e/0xe0 [ 24.921891] common_interrupt+0xf/0xf [ 24.921892] </IRQ> [ 24.921900] RIP: 0010:usb_hcd_flush_endpoint+0x78/0x180 [ 24.921354] usb 3-14: USB disconnect, device number 7 Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> Signed-off-by: Kalle Valo <kvalo@codeaurora.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent e650657 commit ce48f65

File tree

1 file changed

+18
-15
lines changed
  • drivers/net/wireless/mediatek/mt7601u

1 file changed

+18
-15
lines changed

drivers/net/wireless/mediatek/mt7601u/dma.c

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -193,10 +193,23 @@ static void mt7601u_complete_rx(struct urb *urb)
193193
struct mt7601u_rx_queue *q = &dev->rx_q;
194194
unsigned long flags;
195195

196-
spin_lock_irqsave(&dev->rx_lock, flags);
196+
/* do no schedule rx tasklet if urb has been unlinked
197+
* or the device has been removed
198+
*/
199+
switch (urb->status) {
200+
case -ECONNRESET:
201+
case -ESHUTDOWN:
202+
case -ENOENT:
203+
return;
204+
default:
205+
dev_err_ratelimited(dev->dev, "rx urb failed: %d\n",
206+
urb->status);
207+
/* fall through */
208+
case 0:
209+
break;
210+
}
197211

198-
if (mt7601u_urb_has_error(urb))
199-
dev_err(dev->dev, "Error: RX urb failed:%d\n", urb->status);
212+
spin_lock_irqsave(&dev->rx_lock, flags);
200213
if (WARN_ONCE(q->e[q->end].urb != urb, "RX urb mismatch"))
201214
goto out;
202215

@@ -363,19 +376,9 @@ int mt7601u_dma_enqueue_tx(struct mt7601u_dev *dev, struct sk_buff *skb,
363376
static void mt7601u_kill_rx(struct mt7601u_dev *dev)
364377
{
365378
int i;
366-
unsigned long flags;
367379

368-
spin_lock_irqsave(&dev->rx_lock, flags);
369-
370-
for (i = 0; i < dev->rx_q.entries; i++) {
371-
int next = dev->rx_q.end;
372-
373-
spin_unlock_irqrestore(&dev->rx_lock, flags);
374-
usb_poison_urb(dev->rx_q.e[next].urb);
375-
spin_lock_irqsave(&dev->rx_lock, flags);
376-
}
377-
378-
spin_unlock_irqrestore(&dev->rx_lock, flags);
380+
for (i = 0; i < dev->rx_q.entries; i++)
381+
usb_poison_urb(dev->rx_q.e[i].urb);
379382
}
380383

381384
static int mt7601u_submit_rx_buf(struct mt7601u_dev *dev,

0 commit comments

Comments
 (0)