Message ID | 20230616031713.16769-1-pkshih@realtek.com (mailing list archive) |
---|---|
State | Accepted |
Commit | 67d7f24b194e6e8e82540aa4fe97580f6cfa0902 |
Delegated to: | Kalle Valo |
Headers | show |
Series | wifi: rtw88: process VO packets without workqueue to avoid PTK rekey failed | expand |
Ping-Ke Shih <pkshih@realtek.com> wrote: > From: Chih-Kang Chang <gary.chang@realtek.com> > > In the wpa_supplicant rekey flow, it sends an EAPOL packet 4/4 through > nl80211_tx_control_port() and triggers wake_tx_queue() in the driver. > Then, it sends nl80211_new_key() to configure a new key in mac80211. > However, in wake_tx_queue(), a workqueue is used to process the tx packet, > which might cause the driver to process the EAPOL packet later than > nl80211_new_key(). As a result, the EAPOL 4/4 packet is dropped by mac80211 > due to the rekey configuration being finished. The EAPOL packets belongs to > VO packets that need high priority. Therefore, we process VO packets > directly without workqueue to ensure that packets can process immediately. > > VO is normally used by voice application that is low traffic load and low > latency, that doesn't affect user experience. > We test iperf with VO packets(iperf3 -P4 -u -b 10000M -S 0xdf) > before after > TX throughput 162M 162M > ping RTT 3.8ms 3.7ms > > Signed-off-by: Chih-Kang Chang <gary.chang@realtek.com> > Signed-off-by: Ping-Ke Shih <pkshih@realtek.com> Patch applied to wireless-next.git, thanks. 67d7f24b194e wifi: rtw88: process VO packets without workqueue to avoid PTK rekey failed
diff --git a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireless/realtek/rtw88/mac80211.c index 09bcc2345bb05..4241027902832 100644 --- a/drivers/net/wireless/realtek/rtw88/mac80211.c +++ b/drivers/net/wireless/realtek/rtw88/mac80211.c @@ -43,7 +43,11 @@ static void rtw_ops_wake_tx_queue(struct ieee80211_hw *hw, list_add_tail(&rtwtxq->list, &rtwdev->txqs); spin_unlock_bh(&rtwdev->txq_lock); - queue_work(rtwdev->tx_wq, &rtwdev->tx_work); + /* ensure to dequeue EAPOL (4/4) at the right time */ + if (txq->ac == IEEE80211_AC_VO) + __rtw_tx_work(rtwdev); + else + queue_work(rtwdev->tx_wq, &rtwdev->tx_work); } static int rtw_ops_start(struct ieee80211_hw *hw) diff --git a/drivers/net/wireless/realtek/rtw88/tx.c b/drivers/net/wireless/realtek/rtw88/tx.c index bb5c7492c98b0..b6c97a986a1ac 100644 --- a/drivers/net/wireless/realtek/rtw88/tx.c +++ b/drivers/net/wireless/realtek/rtw88/tx.c @@ -635,9 +635,8 @@ static void rtw_txq_push(struct rtw_dev *rtwdev, rcu_read_unlock(); } -void rtw_tx_work(struct work_struct *w) +void __rtw_tx_work(struct rtw_dev *rtwdev) { - struct rtw_dev *rtwdev = container_of(w, struct rtw_dev, tx_work); struct rtw_txq *rtwtxq, *tmp; spin_lock_bh(&rtwdev->txq_lock); @@ -658,6 +657,13 @@ void rtw_tx_work(struct work_struct *w) spin_unlock_bh(&rtwdev->txq_lock); } +void rtw_tx_work(struct work_struct *w) +{ + struct rtw_dev *rtwdev = container_of(w, struct rtw_dev, tx_work); + + __rtw_tx_work(rtwdev); +} + void rtw_txq_init(struct rtw_dev *rtwdev, struct ieee80211_txq *txq) { struct rtw_txq *rtwtxq; diff --git a/drivers/net/wireless/realtek/rtw88/tx.h b/drivers/net/wireless/realtek/rtw88/tx.h index 197d5868c8ad9..544133643a1bb 100644 --- a/drivers/net/wireless/realtek/rtw88/tx.h +++ b/drivers/net/wireless/realtek/rtw88/tx.h @@ -111,6 +111,7 @@ void rtw_tx(struct rtw_dev *rtwdev, void rtw_txq_init(struct rtw_dev *rtwdev, struct ieee80211_txq *txq); void rtw_txq_cleanup(struct rtw_dev *rtwdev, struct ieee80211_txq *txq); void rtw_tx_work(struct work_struct *w); +void __rtw_tx_work(struct rtw_dev *rtwdev); void rtw_tx_pkt_info_update(struct rtw_dev *rtwdev, struct rtw_tx_pkt_info *pkt_info, struct ieee80211_sta *sta,