• Emmanuel Grumbach's avatar
    mac80211: fix AP powersave TX vs. wakeup race · 1d147bfa
    Emmanuel Grumbach authored
    There is a race between the TX path and the STA wakeup: while
    a station is sleeping, mac80211 buffers frames until it wakes
    up, then the frames are transmitted. However, the RX and TX
    path are concurrent, so the packet indicating wakeup can be
    processed while a packet is being transmitted.
    
    This can lead to a situation where the buffered frames list
    is emptied on the one side, while a frame is being added on
    the other side, as the station is still seen as sleeping in
    the TX path.
    
    As a result, the newly added frame will not be send anytime
    soon. It might be sent much later (and out of order) when the
    station goes to sleep and wakes up the next time.
    
    Additionally, it can lead to the crash below.
    
    Fix all this by synchronising both paths with a new lock.
    Both path are not fastpath since they handle PS situations.
    
    In a later patch we'll remove the extra skb queue locks to
    reduce locking overhead.
    
    BUG: unable to handle kernel
    NULL pointer dereference at 000000b0
    IP: [<ff6f1791>] ieee80211_report_used_skb+0x11/0x3e0 [mac80211]
    *pde = 00000000
    Oops: 0000 [#1] SMP DEBUG_PAGEALLOC
    EIP: 0060:[<ff6f1791>] EFLAGS: 00210282 CPU: 1
    EIP is at ieee80211_report_used_skb+0x11/0x3e0 [mac80211]
    EAX: e5900da0 EBX: 00000000 ECX: 00000001 EDX: 00000000
    ESI: e41d00c0 EDI: e5900da0 EBP: ebe458e4 ESP: ebe458b0
     DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068
    CR0: 8005003b CR2: 000000b0 CR3: 25a78000 CR4: 000407d0
    DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000
    DR6: ffff0ff0 DR7: 00000400
    Process iperf (pid: 3934, ti=ebe44000 task=e757c0b0 task.ti=ebe44000)
    iwlwifi 0000:02:00.0: I iwl_pcie_enqueue_hcmd Sending command LQ_CMD (#4e), seq: 0x0903, 92 bytes at 3[3]:9
    Stack:
     e403b32c ebe458c4 00200002 00200286 e403b338 ebe458cc c10960bb e5900da0
     ff76a6ec ebe458d8 00000000 e41d00c0 e5900da0 ebe458f0 ff6f1b75 e403b210
     ebe4598c ff723dc1 00000000 ff76a6ec e597c978 e403b758 00000002 00000002
    Call Trace:
     [<ff6f1b75>] ieee80211_free_txskb+0x15/0x20 [mac80211]
     [<ff723dc1>] invoke_tx_handlers+0x1661/0x1780 [mac80211]
     [<ff7248a5>] ieee80211_tx+0x75/0x100 [mac80211]
     [<ff7249bf>] ieee80211_xmit+0x8f/0xc0 [mac80211]
     [<ff72550e>] ieee80211_subif_start_xmit+0x4fe/0xe20 [mac80211]
     [<c149ef70>] dev_hard_start_xmit+0x450/0x950
     [<c14b9aa9>] sch_direct_xmit+0xa9/0x250
     [<c14b9c9b>] __qdisc_run+0x4b/0x150
     [<c149f732>] dev_queue_xmit+0x2c2/0xca0
    
    Cc: stable@vger.kernel.org
    Reported-by: default avatarYaara Rozenblum <yaara.rozenblum@intel.com>
    Signed-off-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
    Reviewed-by: default avatarStanislaw Gruszka <sgruszka@redhat.com>
    [reword commit log, use a separate lock]
    Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
    1d147bfa
tx.c 81.3 KB