Skip to content

Commit cc89f45

Browse files
Jinjian-Songgregkh
authored andcommitted
net: wwan: t7xx: Fix napi rx poll issue
[ Upstream commit 905fe08 ] When driver handles the napi rx polling requests, the netdev might have been released by the dellink logic triggered by the disconnect operation on user plane. However, in the logic of processing skb in polling, an invalid netdev is still being used, which causes a panic. BUG: kernel NULL pointer dereference, address: 00000000000000f1 Oops: 0000 [#1] PREEMPT SMP NOPTI RIP: 0010:dev_gro_receive+0x3a/0x620 [...] Call Trace: <IRQ> ? __die_body+0x68/0xb0 ? page_fault_oops+0x379/0x3e0 ? exc_page_fault+0x4f/0xa0 ? asm_exc_page_fault+0x22/0x30 ? __pfx_t7xx_ccmni_recv_skb+0x10/0x10 [mtk_t7xx (HASH:1400 7)] ? dev_gro_receive+0x3a/0x620 napi_gro_receive+0xad/0x170 t7xx_ccmni_recv_skb+0x48/0x70 [mtk_t7xx (HASH:1400 7)] t7xx_dpmaif_napi_rx_poll+0x590/0x800 [mtk_t7xx (HASH:1400 7)] net_rx_action+0x103/0x470 irq_exit_rcu+0x13a/0x310 sysvec_apic_timer_interrupt+0x56/0x90 </IRQ> Fixes: 5545b7b ("net: wwan: t7xx: Add NAPI support") Signed-off-by: Jinjian Song <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Paolo Abeni <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent 85eef17 commit cc89f45

File tree

1 file changed

+6
-5
lines changed

1 file changed

+6
-5
lines changed

drivers/net/wwan/t7xx/t7xx_netdev.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ static int t7xx_ccmni_wwan_newlink(void *ctxt, struct net_device *dev, u32 if_id
296296
ccmni->ctlb = ctlb;
297297
ccmni->dev = dev;
298298
atomic_set(&ccmni->usage, 0);
299-
ctlb->ccmni_inst[if_id] = ccmni;
299+
WRITE_ONCE(ctlb->ccmni_inst[if_id], ccmni);
300300

301301
ret = register_netdevice(dev);
302302
if (ret)
@@ -318,6 +318,7 @@ static void t7xx_ccmni_wwan_dellink(void *ctxt, struct net_device *dev, struct l
318318
if (WARN_ON(ctlb->ccmni_inst[if_id] != ccmni))
319319
return;
320320

321+
WRITE_ONCE(ctlb->ccmni_inst[if_id], NULL);
321322
unregister_netdevice(dev);
322323
}
323324

@@ -413,7 +414,7 @@ static void t7xx_ccmni_recv_skb(struct t7xx_ccmni_ctrl *ccmni_ctlb, struct sk_bu
413414

414415
skb_cb = T7XX_SKB_CB(skb);
415416
netif_id = skb_cb->netif_idx;
416-
ccmni = ccmni_ctlb->ccmni_inst[netif_id];
417+
ccmni = READ_ONCE(ccmni_ctlb->ccmni_inst[netif_id]);
417418
if (!ccmni) {
418419
dev_kfree_skb(skb);
419420
return;
@@ -435,7 +436,7 @@ static void t7xx_ccmni_recv_skb(struct t7xx_ccmni_ctrl *ccmni_ctlb, struct sk_bu
435436

436437
static void t7xx_ccmni_queue_tx_irq_notify(struct t7xx_ccmni_ctrl *ctlb, int qno)
437438
{
438-
struct t7xx_ccmni *ccmni = ctlb->ccmni_inst[0];
439+
struct t7xx_ccmni *ccmni = READ_ONCE(ctlb->ccmni_inst[0]);
439440
struct netdev_queue *net_queue;
440441

441442
if (netif_running(ccmni->dev) && atomic_read(&ccmni->usage) > 0) {
@@ -447,7 +448,7 @@ static void t7xx_ccmni_queue_tx_irq_notify(struct t7xx_ccmni_ctrl *ctlb, int qno
447448

448449
static void t7xx_ccmni_queue_tx_full_notify(struct t7xx_ccmni_ctrl *ctlb, int qno)
449450
{
450-
struct t7xx_ccmni *ccmni = ctlb->ccmni_inst[0];
451+
struct t7xx_ccmni *ccmni = READ_ONCE(ctlb->ccmni_inst[0]);
451452
struct netdev_queue *net_queue;
452453

453454
if (atomic_read(&ccmni->usage) > 0) {
@@ -465,7 +466,7 @@ static void t7xx_ccmni_queue_state_notify(struct t7xx_pci_dev *t7xx_dev,
465466
if (ctlb->md_sta != MD_STATE_READY)
466467
return;
467468

468-
if (!ctlb->ccmni_inst[0]) {
469+
if (!READ_ONCE(ctlb->ccmni_inst[0])) {
469470
dev_warn(&t7xx_dev->pdev->dev, "No netdev registered yet\n");
470471
return;
471472
}

0 commit comments

Comments
 (0)