• V
    wil6210: fix for oops while stopping interface · 73d839ae
    Vladimir Kondratiev 提交于
    When interface stopped while running intensive Rx traffic, the following oops
    observed:
    
    [89846.734683] Call trace:
    [89846.737117] [<ffffffc00083aa64>] dev_gro_receive+0xac/0x358
    [89846.742674] [<ffffffc00083ae94>] napi_gro_receive+0x24/0xa4
    [89846.748251] [<ffffffbffc1c2f88>] $x+0xec/0x1f8 [wil6210]         wil_netif_rx_any
    [89846.753547] [<ffffffbffc1c4830>] $x+0x34/0x54 [wil6210]          wil_release_reorder_frame
    [89846.758755] [<ffffffbffc1c48ac>] wil_release_reorder_frames+0x5c/0x78 [wil6210]
    [89846.766044] [<ffffffbffc1c4bf8>] wil_tid_ampdu_rx_free+0x20/0x48 [wil6210]
    [89846.772901] [<ffffffbffc1bedc8>] $x+0x190/0x1e8 [wil6210]
    [89846.778285] [<ffffffbffc1c0ed4>] wmi_event_worker+0x230/0x2f8 [wil6210]
    [89846.784865] [<ffffffc0000b0bc8>] process_one_work+0x278/0x3fc
    [89846.790591] [<ffffffc0000b1218>] worker_thread+0x200/0x330
    [89846.796060] [<ffffffc0000b6664>] kthread+0xac/0xb8
    [89846.800836] Code: b940c661 f9406a62 8b010041 f9400026 (f8636882)
    [89846.807008] ---[ end trace d6fdc17cd27d18f6 ]---
    
    Reason is the following: when removing Rx vring
    (wil_netdev_ops.ndo_stop -> wil_stop -> wil_down -> __wil_down -> wil_rx_fini),
    Rx interrupt occurs. It trigger Rx NAPI, calling wil_rx_handle() that reaps
    (already cleaned) buffer, causing skb referring to garbage memory being set into reorder buffer.
    Then, network stack trying to access this buffer and fails.
    
    Prevent Rx NAPI from being scheduled if device going to stop. Bit wil_status_napi_en reflects
    NAPI enablement state, check it when triggering Rx NAPI.
    
    Testing shows that check for wil_status_napi_en sometimes gets negative, and new error message
    get printed - in this case kernel oops would be observed. Original oops is no more reproducible.
    
    This change requires also changes in the AP flows.
    Properly enable/disable NAPI for the AP. Make sure Rx VRING is disabled
    when resetting target.
    
    For this, promote __wil_up() and __wil_down() to the module scope, and use it
    in the relevant flows.
    Signed-off-by: NVladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>
    Signed-off-by: NJohn W. Linville <linville@tuxdriver.com>
    73d839ae
main.c 17.9 KB