diff options
| author | Karl Mehltretter <kmehltretter@gmail.com> | 2026-08-11 10:27:02 +0200 |
|---|---|---|
| committer | Johannes Berg <johannes.berg@intel.com> | 2026-09-15 11:52:24 +0200 |
| commit | 621d90169cef6c8da5b6134db5c0c4e23cdd09ce (patch) | |
| tree | 0f9e2c83ed4b1e4910d3f35abf4e9a9f0ccb9abc | |
| parent | 769ec67d0abc64c7f716d16e9826c8ae2c5264c2 (diff) | |
| download | linux-next-621d90169cef6c8da5b6134db5c0c4e23cdd09ce.tar.gz linux-next-621d90169cef6c8da5b6134db5c0c4e23cdd09ce.zip | |
wifi: brcmfmac: fix lost 802.1x TX completion wakeup
brcmf_txfinalize() decrements pend_8021x_cnt before a lockless
waitqueue_active() check. atomic_dec() does not order the decrement
against the check.
The waiter can therefore observe a nonzero count while the waker observes
an empty queue, losing the final wakeup and delaying key installation
until the 950 ms timeout.
Add smp_mb__after_atomic() to order the decrement before the queue
check. wait_event_timeout() provides the matching barrier. LKMM confirms
that this forbids the lost-wakeup outcome.
Fixes: 21fff75d2fb6 ("brcmfmac: use wait_event_timeout for 8021x pending count")
Assisted-by: Claude:claude-fable-5
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
Link: https://patch.msgid.link/20260811082702.44521-1-kmehltretter@gmail.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
| -rw-r--r-- | drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c index dad6f4563d14..d2ae67985606 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c @@ -555,6 +555,8 @@ void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success) if (type == ETH_P_PAE) { atomic_dec(&ifp->pend_8021x_cnt); + /* Order the decrement before waitqueue_active() */ + smp_mb__after_atomic(); if (waitqueue_active(&ifp->pend_8021x_wait)) wake_up(&ifp->pend_8021x_wait); } |
