From patchwork Mon Jan 27 16:26:14 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Wetzel X-Patchwork-Id: 860613 Received: from ns2.wdyn.eu (ns2.wdyn.eu [5.252.227.236]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 1D56315D5C4 for ; Mon, 27 Jan 2025 16:37:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=5.252.227.236 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737995872; cv=none; b=YrlVorUjOMJsrjg/7bhX9iymU0w+BK9Lz6IdpTzR9Q1bk5mkM3rBUu5SbV/+Rcf8BRPTlG97K638UyOILX2e8dEQsn44lOfd7MR1hMH2HSYww2VBHtQpST51/yRgNtHyOS7BM/EH/VK+V4WnQ6SG9Fiz1BNhrBuviLp0cOruy/Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737995872; c=relaxed/simple; bh=0P39nBFonvA472ZjtFhVRectDaTp6bwcemm9aXtbqFg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=E0J8D9pw0FbX9wKEaSkY9r2AlvMYNVQR8deonCG6pSw1kO9ug9khdu9mHvg53l4nSOZ40fB9YLmtNuVILBYKAEBD0M5f6E6bj5v6h0KluIvpSPqrY8X6Gis94Y6xT2ldYZebhY3TWStOk0hja7LaAzcOkMGzccK8OoJRltZ6jss= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=wetzel-home.de; spf=pass smtp.mailfrom=wetzel-home.de; dkim=pass (1024-bit key) header.d=wetzel-home.de header.i=@wetzel-home.de header.b=UOXeY37b; arc=none smtp.client-ip=5.252.227.236 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=wetzel-home.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=wetzel-home.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=wetzel-home.de header.i=@wetzel-home.de header.b="UOXeY37b" From: Alexander Wetzel DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=wetzel-home.de; s=wetzel-home; t=1737995297; bh=0P39nBFonvA472ZjtFhVRectDaTp6bwcemm9aXtbqFg=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=UOXeY37bViPkNBlktNAtKJ4XzHqisjvnO7R772Xgy2bdm4HIQn6qpNikrECIXs06e ODGtWsMy42mLWmKDTzRHoS5ESGgTAERRv7NlNLNHzS0M30jAo4wB2cGsQLPDRzc7/n M+idnOjAcISzBlUnevC2V5yy0KhnpguJkKgBU6eY= To: linux-wireless@vger.kernel.org Cc: johannes@sipsolutions.net, Alexander Wetzel Subject: [RFC PATCH 02/13] wifi: mac80211: Fix debugfs handling for virtual monitor Date: Mon, 27 Jan 2025 17:26:14 +0100 Message-ID: <20250127162625.20747-3-Alexander@wetzel-home.de> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250127162625.20747-1-Alexander@wetzel-home.de> References: <20250127162625.20747-1-Alexander@wetzel-home.de> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Create debugfs entry for the virtual monitor interface when it's created and delete them again when it's deleted again. Instead of creating them on deletion, when calling drv_remove_interface(). This fixes debugfs name collisions when deleting and re-creating a monitor interface with the same name. Signed-off-by: Alexander Wetzel --- A user can still create collisions in the debugfs when using names like e.g. phy0-monitor for another monitor interface. And then trigger the creation of the virtual monitor interface... But I guess that's ok and not worth the hassle to fix it. --- net/mac80211/iface.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index b0c02942dac3..1a2b682c452c 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -1162,6 +1162,7 @@ int ieee80211_add_virtual_monitor(struct ieee80211_local *local) } } + ieee80211_debugfs_recreate_netdev(sdata, false); set_bit(SDATA_STATE_RUNNING, &sdata->state); ret = ieee80211_check_queues(sdata, NL80211_IFTYPE_MONITOR); @@ -1212,6 +1213,7 @@ void ieee80211_del_virtual_monitor(struct ieee80211_local *local) return; } + clear_bit(SDATA_STATE_RUNNING, &sdata->state); RCU_INIT_POINTER(local->monitor_sdata, NULL); mutex_unlock(&local->iflist_mtx); @@ -1222,6 +1224,7 @@ void ieee80211_del_virtual_monitor(struct ieee80211_local *local) if (ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF)) drv_remove_interface(local, sdata); + ieee80211_debugfs_remove_netdev(sdata); kfree(sdata); } From patchwork Mon Jan 27 16:26:15 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Wetzel X-Patchwork-Id: 860615 Received: from ns2.wdyn.eu (ns2.wdyn.eu [5.252.227.236]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 1ADC915CD74 for ; Mon, 27 Jan 2025 16:37:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=5.252.227.236 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737995872; cv=none; b=kFSHdzUMdHnGZvsRg2mrT8+VJwTLCOEjf4Ew62l2qcfSusmmuWQ75pZmd3ApJpZTLpRv/keSRy0NRg/aJcud5mpcLWX28qHR1XhmS/LbQtVW+jO3z+qp+U8AoDM5YGPYP+RPP4Edo0cfPlClTwc6FuFVLLrcyRYqv5CWIh2TK1k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737995872; c=relaxed/simple; bh=Sq+njo8vH8dl0o1OvSJ7npHjqJoVsATGAu6h6Fh8u/A=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=mA2rx7ysJi+hGarwmJzaXw3V4jl6TjhItPLPR4y1kAuoiyCeNZMR4Of/ZZsd7awPiAozD1zbTvnasery5rR3L2f0DhIkmW1bPGtAnEs04vyUNFVMtyNTkBiLjkDVbfEU12WLDM96gF9OtUpLx6kur2Sq4jBq4jlubwOZGYst0MI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=wetzel-home.de; spf=pass smtp.mailfrom=wetzel-home.de; dkim=pass (1024-bit key) header.d=wetzel-home.de header.i=@wetzel-home.de header.b=TqrsVJRe; arc=none smtp.client-ip=5.252.227.236 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=wetzel-home.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=wetzel-home.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=wetzel-home.de header.i=@wetzel-home.de header.b="TqrsVJRe" From: Alexander Wetzel DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=wetzel-home.de; s=wetzel-home; t=1737995297; bh=Sq+njo8vH8dl0o1OvSJ7npHjqJoVsATGAu6h6Fh8u/A=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=TqrsVJReE4favL+P2/lZP6WTD6F9KtkwXwwqAWucgrtFP3dY+h6hqxjmFjYsZ4hAn lFnPmudMS0DvAC4ueOnVfBCU4c37U4Xd5JACE7grkhXyoTTB+QJkWCyQ0bIExUW/j8 WN1zcH169S1Ihtwl4AGyRb0p0UD2TYkXsEYbonyQ= To: linux-wireless@vger.kernel.org Cc: johannes@sipsolutions.net, Alexander Wetzel Subject: [RFC PATCH 03/13] wifi: mac80211: Cleanup sta TXQs on flush Date: Mon, 27 Jan 2025 17:26:15 +0100 Message-ID: <20250127162625.20747-4-Alexander@wetzel-home.de> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250127162625.20747-1-Alexander@wetzel-home.de> References: <20250127162625.20747-1-Alexander@wetzel-home.de> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Drop the sta TXQs on flush when the drivers is not supporting flush. ieee80211_set_disassoc() tries to clean up everything for the sta. But it ignored queued frames in the sta TX queues when the driver isn't supporting the flush driver ops. Signed-off-by: Alexander Wetzel --- I tripped over while working on something else.. It looks like this could cause issues with this patch series for drivers not supporting flush. (But all drivers I tested this series with support flush.) --- net/mac80211/util.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 86320ecf306c..4fdac50cda67 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -685,7 +685,7 @@ void __ieee80211_flush_queues(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata, unsigned int queues, bool drop) { - if (!local->ops->flush) + if (!local->ops->flush && !drop) return; /* @@ -712,7 +712,8 @@ void __ieee80211_flush_queues(struct ieee80211_local *local, } } - drv_flush(local, sdata, queues, drop); + if (local->ops->flush) + drv_flush(local, sdata, queues, drop); ieee80211_wake_queues_by_reason(&local->hw, queues, IEEE80211_QUEUE_STOP_REASON_FLUSH, From patchwork Mon Jan 27 16:26:16 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Wetzel X-Patchwork-Id: 860348 Received: from ns2.wdyn.eu (ns2.wdyn.eu [5.252.227.236]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 2054415FA7B for ; Mon, 27 Jan 2025 16:37:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=5.252.227.236 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737995872; cv=none; b=NxdRHgV8IjVQTR+VGB2lxKlSYD0xOBxRs17jkyYqarDImW+z/++V2HS8b5OITvI7QZfRCl+KJrRBkVifAVM1HB+kzfHJXVMadLHSHreAQo3Y3uO1Kt+wLcZ8GNoEiHX+1csd4ZwlpcuX2H4JJ+P8QBU/FCKorGmPtq7ljCuygVc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737995872; c=relaxed/simple; bh=T1hzmvPCM5kU+Z7q52lL9TudExGd+NMTCbjTYl/puxY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=IzOqSL56PhRXLutkIlvjciQfYlI9wMNwoqW1aP2BNCCiSVkOtHXSF2xWl3a+7GhJjYpf5lhTzph6yfzIvt0Mm/joZpeO7STkIsuS6Hshbmwb+mJyElFVo6sLMRl4h4ZbckInGaz2Syrv3BNNfgHMxiuR6KnvBbLHVJ122JD75uY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=wetzel-home.de; spf=pass smtp.mailfrom=wetzel-home.de; dkim=pass (1024-bit key) header.d=wetzel-home.de header.i=@wetzel-home.de header.b=xEIE/D6t; arc=none smtp.client-ip=5.252.227.236 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=wetzel-home.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=wetzel-home.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=wetzel-home.de header.i=@wetzel-home.de header.b="xEIE/D6t" From: Alexander Wetzel DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=wetzel-home.de; s=wetzel-home; t=1737995297; bh=T1hzmvPCM5kU+Z7q52lL9TudExGd+NMTCbjTYl/puxY=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=xEIE/D6tc1q9GSZukjnvl4bzx3JBZYk5gwz1CmajcUZjNSvBRhjF0nc08l767GDXu tsswWXLyS6upbMNNAKiOVDdZRUB3FJT/C6KceP6txUHkrO0c+hCYqWOZnKCPkPE9GJ r/B1Qo/rahiGV+ve6yx1jpt5mbWT9RjRFv7KBLZA= To: linux-wireless@vger.kernel.org Cc: johannes@sipsolutions.net, Alexander Wetzel Subject: [RFC PATCH 04/13] wifi: mac80211: Always provide the MMPDU TXQ Date: Mon, 27 Jan 2025 17:26:16 +0100 Message-ID: <20250127162625.20747-5-Alexander@wetzel-home.de> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250127162625.20747-1-Alexander@wetzel-home.de> References: <20250127162625.20747-1-Alexander@wetzel-home.de> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Alexander Wetzel Always providing and use the MMPDU TX queue to prepare to move all TX into TXQs. For drivers not supporting the MMPDU TXQ, mac80211 will handle it internally. Signed-off-by: Alexander Wetzel --- net/mac80211/driver-ops.h | 12 ++++++++++++ net/mac80211/sta_info.c | 1 - net/mac80211/tx.c | 19 ++----------------- 3 files changed, 14 insertions(+), 18 deletions(-) diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index c64531e0a60e..bf3393340fb9 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h @@ -1360,6 +1360,18 @@ static inline void drv_wake_tx_queue(struct ieee80211_local *local, return; trace_drv_wake_tx_queue(local, sdata, txq); + + /* Driver support for MPDU txqi support is optional */ + if (unlikely(txq->txq.tid == IEEE80211_NUM_TIDS && + ((sdata->vif.type == NL80211_IFTYPE_STATION && + !ieee80211_hw_check(&sdata->local->hw, STA_MMPDU_TXQ)) || + (sdata->vif.type != NL80211_IFTYPE_STATION && + !ieee80211_hw_check(&sdata->local->hw, + BUFF_MMPDU_TXQ))))) { + ieee80211_handle_wake_tx_queue(&local->hw, &txq->txq); + return; + } + local->ops->wake_tx_queue(&local->hw, &txq->txq); } diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index aa22f09e6d14..ef5e466c5a3d 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -620,7 +620,6 @@ __sta_info_alloc(struct ieee80211_sub_if_data *sdata, for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) { struct txq_info *txq = txq_data + i * size; - /* might not do anything for the (bufferable) MMPDU TXQ */ ieee80211_txq_init(sdata, sta, txq, i); } diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index a24636bda679..7b6ae03e421f 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -1310,10 +1310,6 @@ static struct txq_info *ieee80211_get_txq(struct ieee80211_local *local, ieee80211_is_bufferable_mmpdu(skb) || vif->type == NL80211_IFTYPE_STATION) && sta && sta->uploaded) { - /* - * This will be NULL if the driver didn't set the - * opt-in hardware flag. - */ txq = sta->sta.txq[IEEE80211_NUM_TIDS]; } } else if (sta) { @@ -1520,21 +1516,10 @@ void ieee80211_txq_init(struct ieee80211_sub_if_data *sdata, return; } - if (tid == IEEE80211_NUM_TIDS) { - if (sdata->vif.type == NL80211_IFTYPE_STATION) { - /* Drivers need to opt in to the management MPDU TXQ */ - if (!ieee80211_hw_check(&sdata->local->hw, - STA_MMPDU_TXQ)) - return; - } else if (!ieee80211_hw_check(&sdata->local->hw, - BUFF_MMPDU_TXQ)) { - /* Drivers need to opt in to the bufferable MMPDU TXQ */ - return; - } + if (tid == IEEE80211_NUM_TIDS) txqi->txq.ac = IEEE80211_AC_VO; - } else { + else txqi->txq.ac = ieee80211_ac_from_tid(tid); - } txqi->txq.sta = &sta->sta; txqi->txq.tid = tid; From patchwork Mon Jan 27 16:26:17 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Wetzel X-Patchwork-Id: 860349 Received: from ns2.wdyn.eu (ns2.wdyn.eu [5.252.227.236]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 96ABC15573F for ; Mon, 27 Jan 2025 16:28:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=5.252.227.236 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737995310; cv=none; b=j5ARmltu+p32TJfan3uCayG5Qs2KaABiGhG7OFbotK+H3M4DL8MkkBlm+Sqtq5g/43bt8F8J4q907fLzYIFn3erryMJyYa67OBVqrXugEojk1P3Qi+ZvgzdBxIU7l/baOiENaq9ntPQhoax8MlKVXEhvUna6rmzHl47I5Wu1h9k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737995310; c=relaxed/simple; bh=pHg7R0Q2vYxUT3A88xPphKzbXOpfuQqunIDbAGgV8Q4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Ga6f9D4ltUDVHXvHZTglkQ9XmUZRAHRZk1NTnZa/WLpWaoZhldbRJY6LqBWOc6qN++/iUeUuckLVoWztc8asSpFbvWCOn4ynbKt/qHC1/9M6JOJIZZoarYzhuQx0wKImYPqCFqNEYDjAoS6/afORxT3WQrJgM1LzkphnSAjKHJk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=wetzel-home.de; spf=pass smtp.mailfrom=wetzel-home.de; dkim=pass (1024-bit key) header.d=wetzel-home.de header.i=@wetzel-home.de header.b=CBwFiMck; arc=none smtp.client-ip=5.252.227.236 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=wetzel-home.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=wetzel-home.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=wetzel-home.de header.i=@wetzel-home.de header.b="CBwFiMck" From: Alexander Wetzel DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=wetzel-home.de; s=wetzel-home; t=1737995297; bh=pHg7R0Q2vYxUT3A88xPphKzbXOpfuQqunIDbAGgV8Q4=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=CBwFiMckSje05T4Yq86GOJ5uAaQSix0K4p7R8ATaoZyOdB9yUgqlj3bSr4J68ZUID 63t9VtfqDe+2cz4pFvBKKzmOkRRKGtx9INpElY6Ywbr9PV0uvgV6XBX9Oy/05xR+nW 1Za/3r8qqCPup9lwA5t9+aWMW0G6vY1cXToop8sg= To: linux-wireless@vger.kernel.org Cc: johannes@sipsolutions.net, Alexander Wetzel Subject: [RFC PATCH 05/13] wifi: mac80211: Convert vif->txq to an array Date: Mon, 27 Jan 2025 17:26:17 +0100 Message-ID: <20250127162625.20747-6-Alexander@wetzel-home.de> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250127162625.20747-1-Alexander@wetzel-home.de> References: <20250127162625.20747-1-Alexander@wetzel-home.de> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Alexander Wetzel Mac80211 needs additional TX queues to handle all TX within TXQs. Convert vif->txq to an array, allowing other patches to extend vif TXQs. Signed-off-by: Alexander Wetzel --- drivers/net/wireless/ath/ath10k/mac.c | 8 ++++---- drivers/net/wireless/ath/ath9k/ath9k.h | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 6 +++--- drivers/net/wireless/mediatek/mt76/mt7603/main.c | 3 ++- drivers/net/wireless/mediatek/mt76/mt7615/main.c | 5 +++-- drivers/net/wireless/mediatek/mt76/mt76x02_util.c | 3 ++- drivers/net/wireless/mediatek/mt76/mt7915/main.c | 6 +++--- drivers/net/wireless/mediatek/mt76/mt7921/main.c | 5 +++-- drivers/net/wireless/mediatek/mt76/mt7925/main.c | 5 +++-- drivers/net/wireless/mediatek/mt76/mt7996/main.c | 5 +++-- drivers/net/wireless/realtek/rtw88/mac80211.c | 4 ++-- drivers/net/wireless/realtek/rtw88/main.c | 2 +- drivers/net/wireless/realtek/rtw89/mac80211.c | 2 +- include/net/mac80211.h | 14 ++++++++++++-- net/mac80211/cfg.c | 8 ++++++-- net/mac80211/debugfs_netdev.c | 4 ++-- net/mac80211/iface.c | 6 ++++-- net/mac80211/tx.c | 8 ++++---- net/mac80211/util.c | 7 ++++--- 19 files changed, 63 insertions(+), 40 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index c61b95a928da..53df2a9102a7 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -4297,7 +4297,7 @@ struct ieee80211_txq *ath10k_mac_txq_lookup(struct ath10k *ar, if (peer->sta) return peer->sta->txq[tid]; else if (peer->vif) - return peer->vif->txq; + return peer->vif->txq[IEEE80211_VIF_TXQ_MULTICAST]; else return NULL; } @@ -5539,7 +5539,7 @@ static int ath10k_add_interface(struct ieee80211_hw *hw, mutex_lock(&ar->conf_mutex); memset(arvif, 0, sizeof(*arvif)); - ath10k_mac_txq_init(vif->txq); + ath10k_mac_txq_init(vif->txq[IEEE80211_VIF_TXQ_MULTICAST]); arvif->ar = ar; arvif->vif = vif; @@ -5985,7 +5985,7 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw, spin_unlock_bh(&ar->data_lock); ath10k_peer_cleanup(ar, arvif->vdev_id); - ath10k_mac_txq_unref(ar, vif->txq); + ath10k_mac_txq_unref(ar, vif->txq[IEEE80211_VIF_TXQ_MULTICAST]); if (vif->type == NL80211_IFTYPE_MONITOR) { ar->monitor_arvif = NULL; @@ -6002,7 +6002,7 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw, ath10k_mac_vif_tx_unlock_all(arvif); spin_unlock_bh(&ar->htt.tx_lock); - ath10k_mac_txq_unref(ar, vif->txq); + ath10k_mac_txq_unref(ar, vif->txq[IEEE80211_VIF_TXQ_MULTICAST]); out: mutex_unlock(&ar->conf_mutex); diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index bcfc8df0efe5..9b58308ba08a 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -437,7 +437,7 @@ ath_node_to_tid(struct ath_node *an, u8 tidno) if (sta) txq = sta->txq[tidno % ARRAY_SIZE(sta->txq)]; else - txq = vif->txq; + txq = vif->txq[IEEE80211_VIF_TXQ_MULTICAST]; return (struct ath_atx_tid *) txq->drv_priv; } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 07778d55878b..0906d714e680 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -1590,12 +1590,12 @@ int iwl_mvm_post_channel_switch(struct ieee80211_hw *hw, } } else if (vif->type == NL80211_IFTYPE_AP && mvmvif->csa_blocks_tx) { struct iwl_mvm_txq *mvmtxq = - iwl_mvm_txq_from_mac80211(vif->txq); + iwl_mvm_txq_from_mac80211(vif->txq[IEEE80211_VIF_TXQ_MULTICAST]); clear_bit(IWL_MVM_TXQ_STATE_STOP_AP_CSA, &mvmtxq->state); local_bh_disable(); - iwl_mvm_mac_itxq_xmit(hw, vif->txq); + iwl_mvm_mac_itxq_xmit(hw, vif->txq[IEEE80211_VIF_TXQ_MULTICAST]); ieee80211_iterate_stations_atomic(hw, iwl_mvm_post_csa_tx, hw); local_bh_enable(); @@ -5722,7 +5722,7 @@ int iwl_mvm_pre_channel_switch(struct iwl_mvm *mvm, break; mvmvif->csa_blocks_tx = true; - mvmtxq = iwl_mvm_txq_from_mac80211(vif->txq); + mvmtxq = iwl_mvm_txq_from_mac80211(vif->txq[IEEE80211_VIF_TXQ_MULTICAST]); set_bit(IWL_MVM_TXQ_STATE_STOP_AP_CSA, &mvmtxq->state); ieee80211_iterate_stations_atomic(mvm->hw, iwl_mvm_csa_block_txqs, diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/main.c b/drivers/net/wireless/mediatek/mt76/mt7603/main.c index 574f74ad325d..760a55f17f0e 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7603/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7603/main.c @@ -35,6 +35,7 @@ mt7603_stop(struct ieee80211_hw *hw, bool suspend) static int mt7603_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { + struct ieee80211_txq *txq = vif->txq[IEEE80211_VIF_TXQ_MULTICAST]; struct mt7603_vif *mvif = (struct mt7603_vif *)vif->drv_priv; struct mt7603_dev *dev = hw->priv; struct mt76_txq *mtxq; @@ -75,7 +76,7 @@ mt7603_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) eth_broadcast_addr(bc_addr); mt7603_wtbl_init(dev, idx, mvif->idx, bc_addr); - mtxq = (struct mt76_txq *)vif->txq->drv_priv; + mtxq = (struct mt76_txq *)txq->drv_priv; mtxq->wcid = idx; rcu_assign_pointer(dev->mt76.wcid[idx], &mvif->sta.wcid); diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/main.c b/drivers/net/wireless/mediatek/mt76/mt7615/main.c index 376975388007..1f6207b124fb 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/main.c @@ -179,6 +179,7 @@ static int get_omac_idx(enum nl80211_iftype type, u64 mask) static int mt7615_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { + struct ieee80211_txq *txq = vif->txq[IEEE80211_VIF_TXQ_MULTICAST]; struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv; struct mt7615_dev *dev = mt7615_hw_dev(hw); struct mt7615_phy *phy = mt7615_hw_phy(hw); @@ -232,8 +233,8 @@ static int mt7615_add_interface(struct ieee80211_hw *hw, MT_WTBL_UPDATE_ADM_COUNT_CLEAR); rcu_assign_pointer(dev->mt76.wcid[idx], &mvif->sta.wcid); - if (vif->txq) { - mtxq = (struct mt76_txq *)vif->txq->drv_priv; + if (txq) { + mtxq = (struct mt76_txq *)txq->drv_priv; mtxq->wcid = idx; } diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c index 8020446be37b..26d20fabf979 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c @@ -280,6 +280,7 @@ static void mt76x02_vif_init(struct mt76x02_dev *dev, struct ieee80211_vif *vif, unsigned int idx) { + struct ieee80211_txq *txq = vif->txq[IEEE80211_VIF_TXQ_MULTICAST]; struct mt76x02_vif *mvif = (struct mt76x02_vif *)vif->drv_priv; struct mt76_txq *mtxq; @@ -290,7 +291,7 @@ mt76x02_vif_init(struct mt76x02_dev *dev, struct ieee80211_vif *vif, mvif->group_wcid.hw_key_idx = -1; mt76_wcid_init(&mvif->group_wcid); - mtxq = (struct mt76_txq *)vif->txq->drv_priv; + mtxq = (struct mt76_txq *)txq->drv_priv; rcu_assign_pointer(dev->mt76.wcid[MT_VIF_WCID(idx)], &mvif->group_wcid); mtxq->wcid = MT_VIF_WCID(idx); } diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c index c6f498fc81ff..24577eed41ba 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c @@ -204,6 +204,7 @@ static void mt7915_init_bitrate_mask(struct ieee80211_vif *vif) static int mt7915_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { + struct ieee80211_txq *txq = vif->txq[IEEE80211_VIF_TXQ_MULTICAST]; struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv; struct mt7915_dev *dev = mt7915_hw_dev(hw); struct mt7915_phy *phy = mt7915_hw_phy(hw); @@ -259,9 +260,8 @@ static int mt7915_add_interface(struct ieee80211_hw *hw, mt7915_mac_wtbl_update(dev, idx, MT_WTBL_UPDATE_ADM_COUNT_CLEAR); - - if (vif->txq) { - mtxq = (struct mt76_txq *)vif->txq->drv_priv; + if (txq) { + mtxq = (struct mt76_txq *)txq->drv_priv; mtxq->wcid = idx; } diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/main.c b/drivers/net/wireless/mediatek/mt76/mt7921/main.c index a7f5bfbc02ed..3f6cff769561 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c @@ -287,6 +287,7 @@ static void mt7921_stop(struct ieee80211_hw *hw, bool suspend) static int mt7921_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { + struct ieee80211_txq *txq = vif->txq[IEEE80211_VIF_TXQ_MULTICAST]; struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv; struct mt792x_dev *dev = mt792x_hw_dev(hw); struct mt792x_phy *phy = mt792x_hw_phy(hw); @@ -330,8 +331,8 @@ mt7921_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) ewma_rssi_init(&mvif->bss_conf.rssi); rcu_assign_pointer(dev->mt76.wcid[idx], &mvif->sta.deflink.wcid); - if (vif->txq) { - mtxq = (struct mt76_txq *)vif->txq->drv_priv; + if (txq) { + mtxq = (struct mt76_txq *)txq->drv_priv; mtxq->wcid = idx; } diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/main.c b/drivers/net/wireless/mediatek/mt76/mt7925/main.c index 791c8b00e112..6636961754ea 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/main.c @@ -352,6 +352,7 @@ static int mt7925_mac_link_bss_add(struct mt792x_dev *dev, { struct mt792x_bss_conf *mconf = mt792x_link_conf_to_mconf(link_conf); struct ieee80211_vif *vif = link_conf->vif; + struct ieee80211_txq *txq = vif->txq[IEEE80211_VIF_TXQ_MULTICAST]; struct mt792x_vif *mvif = mconf->vif; struct mt76_txq *mtxq; int idx, ret = 0; @@ -395,8 +396,8 @@ static int mt7925_mac_link_bss_add(struct mt792x_dev *dev, ewma_rssi_init(&mconf->rssi); rcu_assign_pointer(dev->mt76.wcid[idx], &mlink->wcid); - if (vif->txq) { - mtxq = (struct mt76_txq *)vif->txq->drv_priv; + if (txq) { + mtxq = (struct mt76_txq *)txq->drv_priv; mtxq->wcid = idx; } diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c index 2b34ae5e0cb5..def6185710eb 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c @@ -179,6 +179,7 @@ static void mt7996_init_bitrate_mask(struct ieee80211_vif *vif) static int mt7996_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { + struct ieee80211_txq *txq = vif->txq[IEEE80211_VIF_TXQ_MULTICAST]; struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; struct mt7996_dev *dev = mt7996_hw_dev(hw); struct mt7996_phy *phy = mt7996_hw_phy(hw); @@ -228,8 +229,8 @@ static int mt7996_add_interface(struct ieee80211_hw *hw, mt7996_mac_wtbl_update(dev, idx, MT_WTBL_UPDATE_ADM_COUNT_CLEAR); - if (vif->txq) { - mtxq = (struct mt76_txq *)vif->txq->drv_priv; + if (txq) { + mtxq = (struct mt76_txq *)txq->drv_priv; mtxq->wcid = idx; } diff --git a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireless/realtek/rtw88/mac80211.c index 026fbf4ad9cc..f689e37c4f7d 100644 --- a/drivers/net/wireless/realtek/rtw88/mac80211.c +++ b/drivers/net/wireless/realtek/rtw88/mac80211.c @@ -162,7 +162,7 @@ static int rtw_ops_add_interface(struct ieee80211_hw *hw, rtwvif->stats.rx_cnt = 0; rtwvif->scan_req = NULL; memset(&rtwvif->bfee, 0, sizeof(struct rtw_bfee)); - rtw_txq_init(rtwdev, vif->txq); + rtw_txq_init(rtwdev, vif->txq[IEEE80211_VIF_TXQ_MULTICAST]); INIT_LIST_HEAD(&rtwvif->rsvd_page_list); mutex_lock(&rtwdev->mutex); @@ -239,7 +239,7 @@ static void rtw_ops_remove_interface(struct ieee80211_hw *hw, rtw_leave_lps_deep(rtwdev); - rtw_txq_cleanup(rtwdev, vif->txq); + rtw_txq_cleanup(rtwdev, vif->txq[IEEE80211_VIF_TXQ_MULTICAST]); rtw_remove_rsvd_page(rtwdev, rtwvif); eth_zero_addr(rtwvif->mac_addr); diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c index e91530ed05a0..c58c29c7e917 100644 --- a/drivers/net/wireless/realtek/rtw88/main.c +++ b/drivers/net/wireless/realtek/rtw88/main.c @@ -625,7 +625,7 @@ static void rtw_reset_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) rtw_bf_disassoc(rtwdev, vif, NULL); rtw_vif_assoc_changed(rtwvif, NULL); - rtw_txq_cleanup(rtwdev, vif->txq); + rtw_txq_cleanup(rtwdev, vif->txq[IEEE80211_VIF_TXQ_MULTICAST]); rtw_release_macid(rtwdev, rtwvif->mac_id); } diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c index 5eac0b524060..f1f485d58179 100644 --- a/drivers/net/wireless/realtek/rtw89/mac80211.c +++ b/drivers/net/wireless/realtek/rtw89/mac80211.c @@ -187,7 +187,7 @@ static int rtw89_ops_add_interface(struct ieee80211_hw *hw, rtw89_init_vif(rtwdev, rtwvif, mac_id, port); - rtw89_core_txq_init(rtwdev, vif->txq); + rtw89_core_txq_init(rtwdev, vif->txq[IEEE80211_VIF_TXQ_MULTICAST]); if (!rtw89_rtwvif_in_list(rtwdev, rtwvif)) list_add_tail(&rtwvif->list, &rtwdev->rtwvifs_list); diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 9320d4bc22ee..c3cd62dc63e0 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -1961,6 +1961,16 @@ enum ieee80211_neg_ttlm_res { NEG_TTLM_RES_SUGGEST_PREFERRED }; +/** + * enum ieee80211_vif_txq - per-vif intermediate queues (txqi) + * + * @IEEE80211_VIF_TXQ_MULTICAST: queue for broadcast/multicast data frames. + */ +enum ieee80211_vif_txq { + IEEE80211_VIF_TXQ_MULTICAST, + IEEE80211_VIF_TXQ_NUM, +}; + /** * struct ieee80211_vif - per-interface data * @@ -2015,7 +2025,7 @@ enum ieee80211_neg_ttlm_res { * for this interface. * @drv_priv: data area for driver use, will always be aligned to * sizeof(void \*). - * @txq: the multicast data TX queue + * @txq: per-vif iTXQs (see enum ieee80211_vif_txq for available queues) * @offload_flags: 802.3 -> 802.11 enapsulation offload flags, see * &enum ieee80211_offload_flags. * @mbssid_tx_vif: Pointer to the transmitting interface if MBSSID is enabled. @@ -2034,7 +2044,7 @@ struct ieee80211_vif { u8 cab_queue; u8 hw_queue[IEEE80211_NUM_ACS]; - struct ieee80211_txq *txq; + struct ieee80211_txq *txq[IEEE80211_VIF_TXQ_NUM]; netdev_features_t netdev_features; u32 driver_flags; diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index fbdd6b46b154..f4d1159e7da7 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -4631,12 +4631,16 @@ static int ieee80211_get_txq_stats(struct wiphy *wiphy, rcu_read_lock(); if (wdev) { + struct ieee80211_txq *txq; + sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); - if (!sdata->vif.txq) { + txq = sdata->vif.txq[IEEE80211_VIF_TXQ_MULTICAST]; + + if (!txq) { ret = 1; goto out; } - ieee80211_fill_txq_stats(txqstats, to_txq_info(sdata->vif.txq)); + ieee80211_fill_txq_stats(txqstats, to_txq_info(txq)); } else { /* phy stats */ txqstats->filled |= BIT(NL80211_TXQ_STATS_BACKLOG_PACKETS) | diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index a9bc2fd59f55..e3541e29b879 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c @@ -619,10 +619,10 @@ static ssize_t ieee80211_if_fmt_aqm( struct txq_info *txqi; int len; - if (!sdata->vif.txq) + if (!sdata->vif.txq[IEEE80211_VIF_TXQ_MULTICAST]) return 0; - txqi = to_txq_info(sdata->vif.txq); + txqi = to_txq_info(sdata->vif.txq[IEEE80211_VIF_TXQ_MULTICAST]); spin_lock_bh(&local->fq.lock); rcu_read_lock(); diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 1a2b682c452c..6b29bcc40a88 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -2239,6 +2239,8 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata) { + struct ieee80211_txq *txq = sdata->vif.txq[IEEE80211_VIF_TXQ_MULTICAST]; + ASSERT_RTNL(); lockdep_assert_wiphy(sdata->local->hw.wiphy); @@ -2246,8 +2248,8 @@ void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata) list_del_rcu(&sdata->list); mutex_unlock(&sdata->local->iflist_mtx); - if (sdata->vif.txq) - ieee80211_txq_purge(sdata->local, to_txq_info(sdata->vif.txq)); + if (txq) + ieee80211_txq_purge(sdata->local, to_txq_info(txq)); synchronize_rcu(); diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 7b6ae03e421f..581b3d97e278 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -1320,7 +1320,7 @@ static struct txq_info *ieee80211_get_txq(struct ieee80211_local *local, txq = sta->sta.txq[tid]; } else { - txq = vif->txq; + txq = vif->txq[IEEE80211_VIF_TXQ_MULTICAST]; } if (!txq) @@ -1484,10 +1484,10 @@ void ieee80211_txq_remove_vlan(struct ieee80211_local *local, ap = container_of(sdata->bss, struct ieee80211_sub_if_data, u.ap); - if (!ap->vif.txq) + if (!ap->vif.txq[IEEE80211_VIF_TXQ_MULTICAST]) return; - txqi = to_txq_info(ap->vif.txq); + txqi = to_txq_info(ap->vif.txq[IEEE80211_VIF_TXQ_MULTICAST]); tin = &txqi->tin; spin_lock_bh(&fq->lock); @@ -1509,7 +1509,7 @@ void ieee80211_txq_init(struct ieee80211_sub_if_data *sdata, txqi->txq.vif = &sdata->vif; if (!sta) { - sdata->vif.txq = &txqi->txq; + sdata->vif.txq[IEEE80211_VIF_TXQ_MULTICAST] = &txqi->txq; txqi->txq.tid = 0; txqi->txq.ac = IEEE80211_AC_BE; diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 4fdac50cda67..b65e08de0a00 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -364,13 +364,14 @@ static void __ieee80211_wake_txqs(struct ieee80211_sub_if_data *sdata, int ac) } } - if (!vif->txq) + if (!vif->txq[IEEE80211_VIF_TXQ_MULTICAST]) goto out; - txqi = to_txq_info(vif->txq); + txqi = to_txq_info(vif->txq[IEEE80211_VIF_TXQ_MULTICAST]); if (!test_and_clear_bit(IEEE80211_TXQ_DIRTY, &txqi->flags) || - (ps && atomic_read(&ps->num_sta_ps)) || ac != vif->txq->ac) + (ps && atomic_read(&ps->num_sta_ps)) || + ac != vif->txq[IEEE80211_VIF_TXQ_MULTICAST]->ac) goto out; spin_unlock(&fq->lock); From patchwork Mon Jan 27 16:26:18 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Wetzel X-Patchwork-Id: 860619 Received: from ns2.wdyn.eu (ns2.wdyn.eu [5.252.227.236]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 96C891581E0 for ; Mon, 27 Jan 2025 16:28:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=5.252.227.236 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737995310; cv=none; b=rW/7HNuoACWZDVLUqLdbiapL1eqYBuEYEZW+YQ2dwoycdcJDpP1UbyIpicMgOZvCyP8bpGyP610jaEG+bMN0qDc2lXWs6W23lcCsltn4VNjsHv8SaglcQL/lBHJoQfElInLEWHWaqb+uHtWY/xs6IdAisPWBHe1sUu1pQZGpcqM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737995310; c=relaxed/simple; bh=jyWRkI7gZpVh6dEPjf/9l49zMY2tOn8tJIhC8fjqiMQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=WTkiZcvWohKe3mKuxyAdUenyDzG/4gTIduI20ViNF1ckYTFwH4sNYtlsJU0FEEi9T0JvQO58f1F0WzpJO3FUf18SsAG9IaKyiyf1amvjh6iz0hNK0qt0BXUfJNlQaF1vkuTyeS2OEeHAFucss7QeQa+JBqsXQjRXsPeEAiRs0m0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=wetzel-home.de; spf=pass smtp.mailfrom=wetzel-home.de; dkim=pass (1024-bit key) header.d=wetzel-home.de header.i=@wetzel-home.de header.b=NkmSar4E; arc=none smtp.client-ip=5.252.227.236 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=wetzel-home.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=wetzel-home.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=wetzel-home.de header.i=@wetzel-home.de header.b="NkmSar4E" From: Alexander Wetzel DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=wetzel-home.de; s=wetzel-home; t=1737995297; bh=jyWRkI7gZpVh6dEPjf/9l49zMY2tOn8tJIhC8fjqiMQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=NkmSar4EerbznuKd6+pNvanfF5zSQQK3ksmo7e4uLZPw80YsJlUe9YbKONA4aKNoj 7Dba6KkVKtclIYtFHnSVAeFtQ/SyESWKxphc9zmgqLIg15CTjvRQpuujnXsxtUp+dD gZs1z1VkFM04IMN1NvNikPzwelGLkrg4Ax4GYPSM= To: linux-wireless@vger.kernel.org Cc: johannes@sipsolutions.net, Alexander Wetzel Subject: [RFC PATCH 06/13] wifi: mac80211: Add new TX queues to replace legacy TX Date: Mon, 27 Jan 2025 17:26:18 +0100 Message-ID: <20250127162625.20747-7-Alexander@wetzel-home.de> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250127162625.20747-1-Alexander@wetzel-home.de> References: <20250127162625.20747-1-Alexander@wetzel-home.de> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Alexander Wetzel Add new mac80211 internal TX queues (TXQs) for cases which can't be handled with the existing queues: 1) per-vif fallback queue for all non-bufferable frames 2) per-vif "noqueue" helper queue 3) per-sta "noqueue" helper queue for sta The "noqueue" queues are intended for frames which can't be queued but still use the queue/dequeue functions to prepare the frames. This is intended to be used for offchannel, disassoc and null-func PS frames in another patch. For now these frames continue to use the legacy TX path. All other frames previously using the legacy TX path are switched over to the new per-vif fallback queue, including TX on monitor interfaces. Signed-off-by: Alexander Wetzel --- include/net/mac80211.h | 34 ++++++-- net/mac80211/debugfs_netdev.c | 46 ++++++----- net/mac80211/driver-ops.h | 29 +++++-- net/mac80211/ieee80211_i.h | 19 +++++ net/mac80211/iface.c | 146 ++++++++++++++++++++++------------ net/mac80211/tx.c | 115 +++++++++++++------------- net/mac80211/util.c | 64 ++++++++------- 7 files changed, 282 insertions(+), 171 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index c3cd62dc63e0..41d91d69d61f 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -97,9 +97,14 @@ * linking it to ieee80211_handle_wake_tx_queue() or implementing a custom * handler. * - * Intermediate queues (struct ieee80211_txq) are kept per-sta per-tid, with - * another per-sta for non-data/non-mgmt and bufferable management frames, and - * a single per-vif queue for multicast data frames. + * Intermediate queues (struct ieee80211_txq) are kept for: + * - per-sta per-tid + * - per-sta for non-data/non-mgmt and bufferable management frames + * - per-sta "noqueue" helper queue for sta (mac80211 internal only) + * - per-vif queue for broadcast/multicast data frames + * - per-vif fallback queue (mac80211 internal only) + * - per-vif "noqueue" helper queue (mac80211 internal only) + * The "mac80211 internal only" queues must be ignored by drivers. * * The driver is expected to initialize its private per-queue data for stations * and interfaces in the .add_interface and .sta_add ops. @@ -1965,9 +1970,18 @@ enum ieee80211_neg_ttlm_res { * enum ieee80211_vif_txq - per-vif intermediate queues (txqi) * * @IEEE80211_VIF_TXQ_MULTICAST: queue for broadcast/multicast data frames. + * @IEEE80211_VIF_TXQ_FALLBACK: last resort queue for frames unable to use any + * other queue. + * @IEEE80211_VIF_TXQ_NOQUEUE: "queue" for non-sta frames which must be + * send out immediately, like offchannel, null-func and disassoc frames. + * (Queued frames will be transmitted by the queueing process and not wait + * for a queue run like normal iTXQs.) + * */ enum ieee80211_vif_txq { IEEE80211_VIF_TXQ_MULTICAST, + IEEE80211_VIF_TXQ_FALLBACK, + IEEE80211_VIF_TXQ_NOQUEUE, IEEE80211_VIF_TXQ_NUM, }; @@ -2457,6 +2471,12 @@ struct ieee80211_link_sta { struct ieee80211_sta_txpwr txpwr; }; +/* To identify the NOQUEUE iTXQs vif->txq[IEEE80211_VIF_TXQ_NOQUEUE] and + * sta->txq[IEEE80211_TXQ_NOQUEUE] we set the tid for these queues to + * IEEE80211_TXQ_NOQUEUE (IEEE80211_NUM_TIDS + 1) + */ +#define IEEE80211_TXQ_NOQUEUE (IEEE80211_NUM_TIDS + 1) + /** * struct ieee80211_sta - station table entry * @@ -2495,8 +2515,10 @@ struct ieee80211_link_sta { * For non MLO STA it will point to the deflink data. For MLO STA * ieee80211_sta_recalc_aggregates() must be called to update it. * @support_p2p_ps: indicates whether the STA supports P2P PS mechanism or not. - * @txq: per-TID data TX queues; note that the last entry (%IEEE80211_NUM_TIDS) - * is used for non-data frames + * @txq: per-TID data TX queues; note that the last two queues are not for TIDs: + * %IEEE80211_NUM_TIDS is used for non-data frames and + * %IEEE80211_TXQ_NOQUEUE is for frames which can't wait in any of the + * other queues and must be send out immediately. * @deflink: This holds the default link STA information, for non MLO STA all link * specific STA information is accessed through @deflink or through * link[0] which points to address of @deflink. For MLO Link STA @@ -2530,7 +2552,7 @@ struct ieee80211_sta { bool support_p2p_ps; - struct ieee80211_txq *txq[IEEE80211_NUM_TIDS + 1]; + struct ieee80211_txq *txq[IEEE80211_TXQ_NOQUEUE + 1]; u16 valid_links; struct ieee80211_link_sta deflink; diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index e3541e29b879..c86fcb179582 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c @@ -619,28 +619,38 @@ static ssize_t ieee80211_if_fmt_aqm( struct txq_info *txqi; int len; - if (!sdata->vif.txq[IEEE80211_VIF_TXQ_MULTICAST]) - return 0; - - txqi = to_txq_info(sdata->vif.txq[IEEE80211_VIF_TXQ_MULTICAST]); + len = scnprintf(buf, + buflen, + "id ac backlog-bytes backlog-packets new-flows drops marks overlimit collisions tx-bytes tx-packets flags\n"); spin_lock_bh(&local->fq.lock); rcu_read_lock(); - len = scnprintf(buf, - buflen, - "ac backlog-bytes backlog-packets new-flows drops marks overlimit collisions tx-bytes tx-packets\n" - "%u %u %u %u %u %u %u %u %u %u\n", - txqi->txq.ac, - txqi->tin.backlog_bytes, - txqi->tin.backlog_packets, - txqi->tin.flows, - txqi->cstats.drop_count, - txqi->cstats.ecn_mark, - txqi->tin.overlimit, - txqi->tin.collisions, - txqi->tin.tx_bytes, - txqi->tin.tx_packets); + for (int i = 0; i < IEEE80211_VIF_TXQ_NUM; i++) { + if (!sdata->vif.txq[i]) + break; + + txqi = to_txq_info(sdata->vif.txq[i]); + len += scnprintf(buf + len, + buflen - len, + "%u %u %u %u %u %u %u %u %u %u %u 0x%lx(%s%s%s%s)\n", + txqi->txq.tid, + txqi->txq.ac, + txqi->tin.backlog_bytes, + txqi->tin.backlog_packets, + txqi->tin.flows, + txqi->cstats.drop_count, + txqi->cstats.ecn_mark, + txqi->tin.overlimit, + txqi->tin.collisions, + txqi->tin.tx_bytes, + txqi->tin.tx_packets, + txqi->flags, + test_bit(IEEE80211_TXQ_STOP, &txqi->flags) ? "STOP" : "RUN", + test_bit(IEEE80211_TXQ_AMPDU, &txqi->flags) ? " AMPDU" : "", + test_bit(IEEE80211_TXQ_NO_AMSDU, &txqi->flags) ? " NO-AMSDU" : "", + test_bit(IEEE80211_TXQ_DIRTY, &txqi->flags) ? " DIRTY" : ""); + } rcu_read_unlock(); spin_unlock_bh(&local->fq.lock); diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index bf3393340fb9..3a7980b5a00a 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h @@ -1356,18 +1356,31 @@ static inline void drv_wake_tx_queue(struct ieee80211_local *local, return; } - if (!check_sdata_in_driver(sdata)) + if (unlikely(sdata->vif.type == NL80211_IFTYPE_MONITOR)) { + if (local->monitor_sdata) { + sdata = local->monitor_sdata; + if (!check_sdata_in_driver(sdata)) + return; + } + } else if (!check_sdata_in_driver(sdata)) { return; + } trace_drv_wake_tx_queue(local, sdata, txq); - /* Driver support for MPDU txqi support is optional */ - if (unlikely(txq->txq.tid == IEEE80211_NUM_TIDS && - ((sdata->vif.type == NL80211_IFTYPE_STATION && - !ieee80211_hw_check(&sdata->local->hw, STA_MMPDU_TXQ)) || - (sdata->vif.type != NL80211_IFTYPE_STATION && - !ieee80211_hw_check(&sdata->local->hw, - BUFF_MMPDU_TXQ))))) { + /* + * Driver support for MPDU txqi support is optional. + * IEEE80211_TXQ_NOQUEUE's txqi's are mac80211 internal and not + * intended to be handled by the drivers. + */ + if (unlikely(WARN_ON(txq->txq.tid == IEEE80211_TXQ_NOQUEUE) || + (txq->txq.tid == IEEE80211_NUM_TIDS && + (!txq->txq.sta || + (sdata->vif.type == NL80211_IFTYPE_STATION && + !ieee80211_hw_check(&sdata->local->hw, STA_MMPDU_TXQ)) || + (sdata->vif.type != NL80211_IFTYPE_STATION && + !ieee80211_hw_check(&sdata->local->hw, + BUFF_MMPDU_TXQ)))))) { ieee80211_handle_wake_tx_queue(&local->hw, &txq->txq); return; } diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 8aceec18ffaf..25fdc8ce8644 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1623,6 +1623,25 @@ IEEE80211_WDEV_TO_SUB_IF(struct wireless_dev *wdev) return container_of(wdev, struct ieee80211_sub_if_data, wdev); } +static inline struct ieee80211_sub_if_data * +ieee80211_get_tx_sdata(struct ieee80211_sub_if_data *sdata) +{ + if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) + sdata = container_of(sdata->bss, + struct ieee80211_sub_if_data, u.ap); + /* + * local->monitor_sdata can only be set without + * %IEEE80211_HW_NO_VIRTUAL_MONITOR, no need to check it here. + */ + else if (unlikely(sdata->vif.type == NL80211_IFTYPE_MONITOR) && + sdata->local->monitor_sdata && + !(sdata->u.mntr.flags & (MONITOR_FLAG_ACTIVE | + MONITOR_FLAG_COOK_FRAMES))) + sdata = rcu_dereference(sdata->local->monitor_sdata); + + return sdata; +} + static inline struct ieee80211_supported_band * ieee80211_get_sband(struct ieee80211_sub_if_data *sdata) { diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 6b29bcc40a88..9b2d0b3ae132 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -1124,11 +1124,63 @@ static void ieee80211_sdata_init(struct ieee80211_local *local, * MLD connection, we get a separate allocation for it. */ ieee80211_link_init(sdata, -1, &sdata->deflink, &sdata->vif.bss_conf); + + for (int i = 0; i < NUM_NL80211_BANDS; i++) { + struct ieee80211_supported_band *sband; + + sband = local->hw.wiphy->bands[i]; + sdata->rc_rateidx_mask[i] = + sband ? (1 << sband->n_bitrates) - 1 : 0; + if (sband) { + __le16 cap; + u16 *vht_rate_mask; + + memcpy(sdata->rc_rateidx_mcs_mask[i], + sband->ht_cap.mcs.rx_mask, + sizeof(sdata->rc_rateidx_mcs_mask[i])); + + cap = sband->vht_cap.vht_mcs.rx_mcs_map; + vht_rate_mask = sdata->rc_rateidx_vht_mcs_mask[i]; + ieee80211_get_vht_mask_from_cap(cap, vht_rate_mask); + } else { + memset(sdata->rc_rateidx_mcs_mask[i], 0, + sizeof(sdata->rc_rateidx_mcs_mask[i])); + memset(sdata->rc_rateidx_vht_mcs_mask[i], 0, + sizeof(sdata->rc_rateidx_vht_mcs_mask[i])); + } + } +} + +static void ieee80211_vif_txq_init(struct ieee80211_sub_if_data *sdata, + int txq_offset, int txq_size, int num_queues) +{ + void *buffer = (char *)sdata + txq_offset; + + /* Fallback queue */ + ieee80211_txq_init(sdata, NULL, buffer, IEEE80211_NUM_TIDS); + + if (num_queues == 1) + return; + + /* Immediate TX helper queue */ + buffer += txq_size; + ieee80211_txq_init(sdata, NULL, buffer, IEEE80211_TXQ_NOQUEUE); + + if (num_queues == 2) + return; + + /* Multicast queue */ + buffer += txq_size; + ieee80211_txq_init(sdata, NULL, buffer, 0); } int ieee80211_add_virtual_monitor(struct ieee80211_local *local) { struct ieee80211_sub_if_data *sdata; + int size = ALIGN(sizeof(*sdata) + local->hw.vif_data_size, + sizeof(void *)); + int txq_size = ALIGN(sizeof(struct txq_info) + local->hw.txq_data_size, + sizeof(void *)); int ret; ASSERT_RTNL(); @@ -1138,7 +1190,7 @@ int ieee80211_add_virtual_monitor(struct ieee80211_local *local) WARN_ON(ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR))) return 0; - sdata = kzalloc(sizeof(*sdata) + local->hw.vif_data_size, GFP_KERNEL); + sdata = kzalloc(size + txq_size, GFP_KERNEL); if (!sdata) return -ENOMEM; @@ -1150,7 +1202,7 @@ int ieee80211_add_virtual_monitor(struct ieee80211_local *local) sdata->wdev.wiphy = local->hw.wiphy; ieee80211_sdata_init(local, sdata); - + ieee80211_vif_txq_init(sdata, size, txq_size, 1); ieee80211_set_default_queues(sdata); if (ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF)) { @@ -2077,8 +2129,12 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, { struct net_device *ndev = NULL; struct ieee80211_sub_if_data *sdata = NULL; - struct txq_info *txqi; - int ret, i; + int size = ALIGN(sizeof(*sdata) + local->hw.vif_data_size, + sizeof(void *)); + int txq_size = ALIGN(sizeof(struct txq_info) + local->hw.txq_data_size, + sizeof(void *)); + int num_txqs = 2; + int ret; ASSERT_RTNL(); lockdep_assert_wiphy(local->hw.wiphy); @@ -2086,8 +2142,7 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, if (type == NL80211_IFTYPE_P2P_DEVICE || type == NL80211_IFTYPE_NAN) { struct wireless_dev *wdev; - sdata = kzalloc(sizeof(*sdata) + local->hw.vif_data_size, - GFP_KERNEL); + sdata = kzalloc(size + 2 * txq_size, GFP_KERNEL); if (!sdata) return -ENOMEM; wdev = &sdata->wdev; @@ -2098,17 +2153,14 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, memcpy(sdata->vif.addr, wdev->address, ETH_ALEN); ether_addr_copy(sdata->vif.bss_conf.addr, sdata->vif.addr); } else { - int size = ALIGN(sizeof(*sdata) + local->hw.vif_data_size, - sizeof(void *)); - int txq_size = 0; - - if (type != NL80211_IFTYPE_AP_VLAN && - (type != NL80211_IFTYPE_MONITOR || - (params->flags & MONITOR_FLAG_ACTIVE))) - txq_size += sizeof(struct txq_info) + - local->hw.txq_data_size; + if (type == NL80211_IFTYPE_AP_VLAN) + num_txqs = 0; + else if (type == NL80211_IFTYPE_MONITOR) + num_txqs = 1; + else + num_txqs = 3; - ndev = alloc_netdev_mqs(size + txq_size, + ndev = alloc_netdev_mqs(size + num_txqs * txq_size, name, name_assign_type, ieee80211_if_setup, 1, 1); if (!ndev) @@ -2147,14 +2199,12 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, ether_addr_copy(sdata->vif.bss_conf.addr, sdata->vif.addr); memcpy(sdata->name, ndev->name, IFNAMSIZ); - if (txq_size) { - txqi = netdev_priv(ndev) + size; - ieee80211_txq_init(sdata, NULL, txqi, 0); - } - sdata->dev = ndev; } + if (num_txqs) + ieee80211_vif_txq_init(sdata, size, txq_size, num_txqs); + /* initialise type-independent data */ sdata->wdev.wiphy = local->hw.wiphy; @@ -2167,30 +2217,6 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, wiphy_delayed_work_init(&sdata->dec_tailroom_needed_wk, ieee80211_delayed_tailroom_dec); - for (i = 0; i < NUM_NL80211_BANDS; i++) { - struct ieee80211_supported_band *sband; - sband = local->hw.wiphy->bands[i]; - sdata->rc_rateidx_mask[i] = - sband ? (1 << sband->n_bitrates) - 1 : 0; - if (sband) { - __le16 cap; - u16 *vht_rate_mask; - - memcpy(sdata->rc_rateidx_mcs_mask[i], - sband->ht_cap.mcs.rx_mask, - sizeof(sdata->rc_rateidx_mcs_mask[i])); - - cap = sband->vht_cap.vht_mcs.rx_mcs_map; - vht_rate_mask = sdata->rc_rateidx_vht_mcs_mask[i]; - ieee80211_get_vht_mask_from_cap(cap, vht_rate_mask); - } else { - memset(sdata->rc_rateidx_mcs_mask[i], 0, - sizeof(sdata->rc_rateidx_mcs_mask[i])); - memset(sdata->rc_rateidx_vht_mcs_mask[i], 0, - sizeof(sdata->rc_rateidx_vht_mcs_mask[i])); - } - } - ieee80211_set_default_queues(sdata); /* setup type-dependent data */ @@ -2237,10 +2263,29 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, return 0; } -void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata) +static void ieee80211_purge_txqs(struct ieee80211_sub_if_data *sdata) { - struct ieee80211_txq *txq = sdata->vif.txq[IEEE80211_VIF_TXQ_MULTICAST]; + struct sta_info *sta; + list_for_each_entry(sta, &sdata->local->sta_list, list) { + if (sdata != sta->sdata) + continue; + ieee80211_purge_sta_txqs(sta); + } + + for (int i = IEEE80211_VIF_TXQ_MULTICAST; + i <= IEEE80211_VIF_TXQ_FALLBACK; + i++) { + if (sdata->vif.txq[i]) + ieee80211_txq_purge(sdata->local, + to_txq_info(sdata->vif.txq[i])); + } + + synchronize_rcu(); +} + +void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata) +{ ASSERT_RTNL(); lockdep_assert_wiphy(sdata->local->hw.wiphy); @@ -2248,10 +2293,7 @@ void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata) list_del_rcu(&sdata->list); mutex_unlock(&sdata->local->iflist_mtx); - if (txq) - ieee80211_txq_purge(sdata->local, to_txq_info(txq)); - - synchronize_rcu(); + ieee80211_purge_txqs(sdata); cfg80211_unregister_wdev(&sdata->wdev); @@ -2300,6 +2342,8 @@ void ieee80211_remove_interfaces(struct ieee80211_local *local) list_for_each_entry_safe(sdata, tmp, &unreg_list, list) { bool netdev = sdata->dev; + ieee80211_purge_txqs(sdata); + /* * Remove IP addresses explicitly, since the notifier will * skip the callbacks if wdev->registered is false, since diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 581b3d97e278..c59cebc66ac6 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -1300,31 +1300,37 @@ static struct txq_info *ieee80211_get_txq(struct ieee80211_local *local, struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ieee80211_txq *txq = NULL; - if ((info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) || - (info->control.flags & IEEE80211_TX_CTRL_PS_RESPONSE)) + if (unlikely(info->flags & IEEE80211_TX_INTFL_OFFCHAN_TX_OK)) + /* Offchannel queue can't be used, yet */ return NULL; - if (!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) && - unlikely(!ieee80211_is_data_present(hdr->frame_control))) { + if (unlikely(vif->type == NL80211_IFTYPE_MONITOR || + info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM || + info->control.flags & IEEE80211_TX_CTRL_PS_RESPONSE)) + goto out; + + if (unlikely(!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) && + !ieee80211_is_data_present(hdr->frame_control))) { if ((!ieee80211_is_mgmt(hdr->frame_control) || ieee80211_is_bufferable_mmpdu(skb) || vif->type == NL80211_IFTYPE_STATION) && sta && sta->uploaded) { txq = sta->sta.txq[IEEE80211_NUM_TIDS]; } - } else if (sta) { + } else if (likely(sta)) { u8 tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK; - if (!sta->uploaded) - return NULL; + if (unlikely(!sta->uploaded)) + goto out; txq = sta->sta.txq[tid]; } else { txq = vif->txq[IEEE80211_VIF_TXQ_MULTICAST]; } +out: if (!txq) - return NULL; + txq = vif->txq[IEEE80211_VIF_TXQ_FALLBACK]; return to_txq_info(txq); } @@ -1446,12 +1452,13 @@ static void ieee80211_txq_enqueue(struct ieee80211_local *local, spin_lock_bh(&fq->lock); /* - * For management frames, don't really apply codel etc., + * For management frames (tid set to IEEE80211_NUM_TIDS + * or IEEE80211_TXQ_NOQUEUE), don't really apply codel etc., * we don't want to apply any shaping or anything we just - * want to simplify the driver API by having them on the - * txqi. + * want to simplify the driver API and mac80211 internal + * handling by having them on the txqi. */ - if (unlikely(txqi->txq.tid == IEEE80211_NUM_TIDS)) { + if (unlikely(txqi->txq.tid >= IEEE80211_NUM_TIDS)) { IEEE80211_SKB_CB(skb)->control.flags |= IEEE80211_TX_INTCFL_NEED_TXPROCESSING; __skb_queue_tail(&txqi->frags, skb); @@ -1509,14 +1516,26 @@ void ieee80211_txq_init(struct ieee80211_sub_if_data *sdata, txqi->txq.vif = &sdata->vif; if (!sta) { - sdata->vif.txq[IEEE80211_VIF_TXQ_MULTICAST] = &txqi->txq; - txqi->txq.tid = 0; - txqi->txq.ac = IEEE80211_AC_BE; + if (tid == IEEE80211_TXQ_NOQUEUE) { + sdata->vif.txq[IEEE80211_VIF_TXQ_NOQUEUE] = + &txqi->txq; + txqi->txq.ac = IEEE80211_AC_VO; + } else if (tid == IEEE80211_NUM_TIDS) { + sdata->vif.txq[IEEE80211_VIF_TXQ_FALLBACK] = + &txqi->txq; + txqi->txq.ac = IEEE80211_AC_VO; + } else { + sdata->vif.txq[IEEE80211_VIF_TXQ_MULTICAST] = + &txqi->txq; + txqi->txq.ac = IEEE80211_AC_BE; + } + txqi->txq.tid = tid; return; } - if (tid == IEEE80211_NUM_TIDS) + /* for %IEEE80211_NUM_TIDS and %IEEE80211_TXQ_NOQUEUE*/ + if (tid >= IEEE80211_NUM_TIDS) txqi->txq.ac = IEEE80211_AC_VO; else txqi->txq.ac = ieee80211_ac_from_tid(tid); @@ -1628,16 +1647,13 @@ static bool ieee80211_queue_skb(struct ieee80211_local *local, struct sta_info *sta, struct sk_buff *skb) { - struct ieee80211_vif *vif; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_vif *vif = &sdata->vif; struct txq_info *txqi; - if (sdata->vif.type == NL80211_IFTYPE_MONITOR) - return false; - - if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) - sdata = container_of(sdata->bss, - struct ieee80211_sub_if_data, u.ap); + info->control.vif = vif; + sdata = ieee80211_get_tx_sdata(sdata); vif = &sdata->vif; txqi = ieee80211_get_txq(local, vif, sta, skb); @@ -1645,7 +1661,6 @@ static bool ieee80211_queue_skb(struct ieee80211_local *local, return false; ieee80211_txq_enqueue(local, txqi, skb); - schedule_and_wake_txq(local, txqi); return true; @@ -3794,7 +3809,7 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw, struct ieee80211_local *local = hw_to_local(hw); struct txq_info *txqi = container_of(txq, struct txq_info, txq); struct ieee80211_hdr *hdr; - struct sk_buff *skb = NULL; + struct sk_buff *skb; struct fq *fq = &local->fq; struct fq_tin *tin = &txqi->tin; struct ieee80211_tx_info *info; @@ -3803,7 +3818,7 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw, struct ieee80211_vif *vif = txq->vif; int q = vif->hw_queue[txq->ac]; unsigned long flags; - bool q_stopped; + int qsr; WARN_ON_ONCE(softirq_count() == 0); @@ -3812,10 +3827,21 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw, begin: spin_lock_irqsave(&local->queue_stop_reason_lock, flags); - q_stopped = local->queue_stop_reasons[q]; + qsr = local->queue_stop_reasons[q]; spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); - if (unlikely(q_stopped)) { + if (unlikely(qsr && + (txq->tid != IEEE80211_TXQ_NOQUEUE || + (qsr & ~BIT(IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL))))) { + /* Drop off-channel frames if queues are stopped for any reason + * other than off-channel operation. Never queue them. + */ + if (unlikely(txq->tid == IEEE80211_TXQ_NOQUEUE)) { + WARN(1, "mac80211: Drop noqueue TX. qsr=%i\n", qsr); + ieee80211_txq_purge(local, txqi); + return NULL; + } + /* mark for waking later */ set_bit(IEEE80211_TXQ_DIRTY, &txqi->flags); return NULL; @@ -3936,36 +3962,6 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw, } } - switch (tx.sdata->vif.type) { - case NL80211_IFTYPE_MONITOR: - if ((tx.sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) || - ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR)) { - vif = &tx.sdata->vif; - break; - } - tx.sdata = rcu_dereference(local->monitor_sdata); - if (tx.sdata && - ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF)) { - vif = &tx.sdata->vif; - info->hw_queue = - vif->hw_queue[skb_get_queue_mapping(skb)]; - } else if (ieee80211_hw_check(&local->hw, QUEUE_CONTROL)) { - ieee80211_free_txskb(&local->hw, skb); - goto begin; - } else { - info->control.vif = NULL; - return skb; - } - break; - case NL80211_IFTYPE_AP_VLAN: - tx.sdata = container_of(tx.sdata->bss, - struct ieee80211_sub_if_data, u.ap); - fallthrough; - default: - vif = &tx.sdata->vif; - break; - } - encap_out: info->control.vif = vif; @@ -4143,7 +4139,7 @@ bool ieee80211_txq_airtime_check(struct ieee80211_hw *hw, if (!txq->sta) return true; - if (unlikely(txq->tid == IEEE80211_NUM_TIDS)) + if (unlikely(txq->tid >= IEEE80211_NUM_TIDS)) return true; sta = container_of(txq->sta, struct sta_info, sta); @@ -4636,7 +4632,6 @@ static void ieee80211_8023_xmit(struct ieee80211_sub_if_data *sdata, struct ieee80211_sub_if_data, u.ap); info->flags |= IEEE80211_TX_CTL_HW_80211_ENCAP; - info->control.vif = &sdata->vif; if (key) info->control.hw_key = &key->conf; diff --git a/net/mac80211/util.c b/net/mac80211/util.c index b65e08de0a00..c5b4dfab09e5 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -320,65 +320,73 @@ void ieee80211_handle_wake_tx_queue(struct ieee80211_hw *hw, } EXPORT_SYMBOL(ieee80211_handle_wake_tx_queue); +static void __ieee80211_wake_txq(struct ieee80211_local *local, + struct ieee80211_txq *txq) +{ + struct txq_info *txqi = to_txq_info(txq); + struct fq *fq = &local->fq; + + if (WARN_ON(!txq)) + return; + if (test_and_clear_bit(IEEE80211_TXQ_DIRTY, &txqi->flags)) { + spin_unlock(&fq->lock); + drv_wake_tx_queue(local, txqi); + spin_lock(&fq->lock); + } +} + static void __ieee80211_wake_txqs(struct ieee80211_sub_if_data *sdata, int ac) { struct ieee80211_local *local = sdata->local; - struct ieee80211_vif *vif = &sdata->vif; struct fq *fq = &local->fq; + struct ieee80211_vif *vif; struct ps_data *ps = NULL; - struct txq_info *txqi; struct sta_info *sta; int i; local_bh_disable(); spin_lock(&fq->lock); + if (WARN_ON(!sdata)) + goto out; if (!test_bit(SDATA_STATE_RUNNING, &sdata->state)) goto out; + sdata = ieee80211_get_tx_sdata(sdata); + vif = &sdata->vif; + if (sdata->vif.type == NL80211_IFTYPE_AP) ps = &sdata->bss->ps; + /* %IEEE80211_VIF_TXQ_NOQUEUE must be ignored here */ + + if (ac == IEEE80211_AC_VO) { + __ieee80211_wake_txq(local, + vif->txq[IEEE80211_VIF_TXQ_FALLBACK]); + } + + if (ac == IEEE80211_AC_BE && vif->txq[IEEE80211_VIF_TXQ_MULTICAST] && + (!ps || !atomic_read(&ps->num_sta_ps))) + __ieee80211_wake_txq(local, + vif->txq[IEEE80211_VIF_TXQ_MULTICAST]); + list_for_each_entry_rcu(sta, &local->sta_list, list) { if (sdata != sta->sdata) continue; - for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) { + /* IEEE80211_TXQ_NOQUEUE must be ignored here. */ + for (i = 0; i <= IEEE80211_NUM_TIDS; i++) { struct ieee80211_txq *txq = sta->sta.txq[i]; if (!txq) continue; - txqi = to_txq_info(txq); - if (ac != txq->ac) continue; - if (!test_and_clear_bit(IEEE80211_TXQ_DIRTY, - &txqi->flags)) - continue; - - spin_unlock(&fq->lock); - drv_wake_tx_queue(local, txqi); - spin_lock(&fq->lock); + __ieee80211_wake_txq(local, txq); } } - - if (!vif->txq[IEEE80211_VIF_TXQ_MULTICAST]) - goto out; - - txqi = to_txq_info(vif->txq[IEEE80211_VIF_TXQ_MULTICAST]); - - if (!test_and_clear_bit(IEEE80211_TXQ_DIRTY, &txqi->flags) || - (ps && atomic_read(&ps->num_sta_ps)) || - ac != vif->txq[IEEE80211_VIF_TXQ_MULTICAST]->ac) - goto out; - - spin_unlock(&fq->lock); - - drv_wake_tx_queue(local, txqi); - local_bh_enable(); - return; out: spin_unlock(&fq->lock); local_bh_enable(); From patchwork Mon Jan 27 16:26:19 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Wetzel X-Patchwork-Id: 860617 Received: from ns2.wdyn.eu (ns2.wdyn.eu [5.252.227.236]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 96B0A155C87 for ; Mon, 27 Jan 2025 16:28:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=5.252.227.236 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737995310; cv=none; b=XjeNtgmmk/PZIpb9uqFtq6wqYpwPU4HowD0ZkCM0RjgKRjlVNvP/w5p92Vh2A6AXQGva+E7mgbyfUiomGoHBZ4IBubXmYLl9JMWZEMXRee3FLkgINVi8DtXd2jjueR17IpVGHdZRdYHm6MLAfomCT4RaL0g9B98dIR0R6JY8pxs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737995310; c=relaxed/simple; bh=+tAx02Z9CkcEO6BTSpSCJ5NP6ypyTm9bhWl6h1he2/k=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Op2cNvUlkXRP+ETVan9v9ZFHcMorBNeeLU7U6x4WJqoGhGqv9xB62UNj/Q1f7E38G98SR/MyQ4axsr/UOF2+mZUmr7hH3kQ3rgqeVl/ZfqvkQ1VebHx2v5H8jabznuRP8pXGBnhUfOuwRowX81Bh11Gr0XnNQ8m96UUlqzUsHD4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=wetzel-home.de; spf=pass smtp.mailfrom=wetzel-home.de; dkim=pass (1024-bit key) header.d=wetzel-home.de header.i=@wetzel-home.de header.b=ARnczBWN; arc=none smtp.client-ip=5.252.227.236 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=wetzel-home.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=wetzel-home.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=wetzel-home.de header.i=@wetzel-home.de header.b="ARnczBWN" From: Alexander Wetzel DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=wetzel-home.de; s=wetzel-home; t=1737995298; bh=+tAx02Z9CkcEO6BTSpSCJ5NP6ypyTm9bhWl6h1he2/k=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=ARnczBWNv6b48zfRkAb/1X1VJshp4ih2ZQsHmaenT+YRFjBYLnUKUMjGxqs4+WAB1 yLBZGRfa9QpQ0rrv3SUjv9RbZiyNCL93bfDXHWCkMlhPRKAV6DzvPno7/sUof0W2IK qwkJ/OnHgWy0WP0lo1jdxHuJbL/fvricLACbm+N8= To: linux-wireless@vger.kernel.org Cc: johannes@sipsolutions.net, Alexander Wetzel Subject: [RFC PATCH 07/13] wifi: mac80211: Stop using legacy TX path Date: Mon, 27 Jan 2025 17:26:19 +0100 Message-ID: <20250127162625.20747-8-Alexander@wetzel-home.de> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250127162625.20747-1-Alexander@wetzel-home.de> References: <20250127162625.20747-1-Alexander@wetzel-home.de> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Alexander Wetzel Stop using the legacy TX path within mac80211 and start using TXQs to handle the not queueable offchannel, disassoc and null-func PS frames. ieee80211_tx() will queue these frames into either the per-vif or per-sta helper TXQ. But instead of scheduling a queue run the frame will immediately be dequeued again and handed over to the driver. With that functionality mac80211 is now only using TXQs to send frames. Signed-off-by: Alexander Wetzel --- net/mac80211/tx.c | 309 +++++++------------------------------------- net/mac80211/util.c | 12 +- 2 files changed, 56 insertions(+), 265 deletions(-) diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index c59cebc66ac6..d50ca692f348 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -1300,9 +1300,13 @@ static struct txq_info *ieee80211_get_txq(struct ieee80211_local *local, struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ieee80211_txq *txq = NULL; - if (unlikely(info->flags & IEEE80211_TX_INTFL_OFFCHAN_TX_OK)) - /* Offchannel queue can't be used, yet */ - return NULL; + if (unlikely(info->flags & IEEE80211_TX_INTFL_OFFCHAN_TX_OK)) { + if (sta) + txq = sta->sta.txq[IEEE80211_TXQ_NOQUEUE]; + else + txq = vif->txq[IEEE80211_VIF_TXQ_NOQUEUE]; + goto out; + } if (unlikely(vif->type == NL80211_IFTYPE_MONITOR || info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM || @@ -1534,7 +1538,7 @@ void ieee80211_txq_init(struct ieee80211_sub_if_data *sdata, return; } - /* for %IEEE80211_NUM_TIDS and %IEEE80211_TXQ_NOQUEUE*/ + /* for %IEEE80211_NUM_TIDS and %IEEE80211_TXQ_NOQUEUE */ if (tid >= IEEE80211_NUM_TIDS) txqi->txq.ac = IEEE80211_AC_VO; else @@ -1642,10 +1646,10 @@ void ieee80211_txq_teardown_flows(struct ieee80211_local *local) spin_unlock_bh(&fq->lock); } -static bool ieee80211_queue_skb(struct ieee80211_local *local, - struct ieee80211_sub_if_data *sdata, - struct sta_info *sta, - struct sk_buff *skb) +static struct txq_info *ieee80211_queue_skb(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata, + struct sta_info *sta, + struct sk_buff *skb) { struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ieee80211_vif *vif = &sdata->vif; @@ -1657,142 +1661,11 @@ static bool ieee80211_queue_skb(struct ieee80211_local *local, vif = &sdata->vif; txqi = ieee80211_get_txq(local, vif, sta, skb); - if (!txqi) - return false; - ieee80211_txq_enqueue(local, txqi, skb); - schedule_and_wake_txq(local, txqi); - - return true; -} - -static bool ieee80211_tx_frags(struct ieee80211_local *local, - struct ieee80211_vif *vif, - struct sta_info *sta, - struct sk_buff_head *skbs, - bool txpending) -{ - struct ieee80211_tx_control control = {}; - struct sk_buff *skb, *tmp; - unsigned long flags; - - skb_queue_walk_safe(skbs, skb, tmp) { - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - int q = info->hw_queue; - -#ifdef CONFIG_MAC80211_VERBOSE_DEBUG - if (WARN_ON_ONCE(q >= local->hw.queues)) { - __skb_unlink(skb, skbs); - ieee80211_free_txskb(&local->hw, skb); - continue; - } -#endif - - spin_lock_irqsave(&local->queue_stop_reason_lock, flags); - if (local->queue_stop_reasons[q] || - (!txpending && !skb_queue_empty(&local->pending[q]))) { - if (unlikely(info->flags & - IEEE80211_TX_INTFL_OFFCHAN_TX_OK)) { - if (local->queue_stop_reasons[q] & - ~BIT(IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL)) { - /* - * Drop off-channel frames if queues - * are stopped for any reason other - * than off-channel operation. Never - * queue them. - */ - spin_unlock_irqrestore( - &local->queue_stop_reason_lock, - flags); - ieee80211_purge_tx_queue(&local->hw, - skbs); - return true; - } - } else { - - /* - * Since queue is stopped, queue up frames for - * later transmission from the tx-pending - * tasklet when the queue is woken again. - */ - if (txpending) - skb_queue_splice_init(skbs, - &local->pending[q]); - else - skb_queue_splice_tail_init(skbs, - &local->pending[q]); - - spin_unlock_irqrestore(&local->queue_stop_reason_lock, - flags); - return false; - } - } - spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); - - info->control.vif = vif; - control.sta = sta ? &sta->sta : NULL; - - __skb_unlink(skb, skbs); - drv_tx(local, &control, skb); - } - - return true; -} - -/* - * Returns false if the frame couldn't be transmitted but was queued instead. - */ -static bool __ieee80211_tx(struct ieee80211_local *local, - struct sk_buff_head *skbs, struct sta_info *sta, - bool txpending) -{ - struct ieee80211_tx_info *info; - struct ieee80211_sub_if_data *sdata; - struct ieee80211_vif *vif; - struct sk_buff *skb; - bool result; - - if (WARN_ON(skb_queue_empty(skbs))) - return true; - - skb = skb_peek(skbs); - info = IEEE80211_SKB_CB(skb); - sdata = vif_to_sdata(info->control.vif); - if (sta && !sta->uploaded) - sta = NULL; - - switch (sdata->vif.type) { - case NL80211_IFTYPE_MONITOR: - if ((sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) || - ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR)) { - vif = &sdata->vif; - break; - } - sdata = rcu_dereference(local->monitor_sdata); - if (sdata && ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF)) { - vif = &sdata->vif; - info->hw_queue = - vif->hw_queue[skb_get_queue_mapping(skb)]; - } else if (ieee80211_hw_check(&local->hw, QUEUE_CONTROL)) { - ieee80211_purge_tx_queue(&local->hw, skbs); - return true; - } else - vif = NULL; - break; - case NL80211_IFTYPE_AP_VLAN: - sdata = container_of(sdata->bss, - struct ieee80211_sub_if_data, u.ap); - fallthrough; - default: - vif = &sdata->vif; - break; - } - - result = ieee80211_tx_frags(local, vif, sta, skbs, txpending); - - WARN_ON_ONCE(!skb_queue_empty(skbs)); + if (likely(txqi->txq.tid != IEEE80211_TXQ_NOQUEUE)) + schedule_and_wake_txq(local, txqi); - return result; + return txqi; } /* @@ -1927,22 +1800,20 @@ bool ieee80211_tx_prepare_skb(struct ieee80211_hw *hw, } EXPORT_SYMBOL(ieee80211_tx_prepare_skb); -/* - * Returns false if the frame couldn't be transmitted but was queued instead. - */ -static bool ieee80211_tx(struct ieee80211_sub_if_data *sdata, - struct sta_info *sta, struct sk_buff *skb, - bool txpending) +static void ieee80211_tx(struct ieee80211_sub_if_data *sdata, + struct sta_info *sta, struct sk_buff *skb) { struct ieee80211_local *local = sdata->local; struct ieee80211_tx_data tx; ieee80211_tx_result res_prepare; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - bool result = true; + bool noqueue = info->flags & IEEE80211_TX_INTFL_OFFCHAN_TX_OK; + struct ieee80211_tx_control control; + struct txq_info *txqi; if (unlikely(skb->len < 10)) { dev_kfree_skb(skb); - return true; + return; } /* initialises tx */ @@ -1950,9 +1821,9 @@ static bool ieee80211_tx(struct ieee80211_sub_if_data *sdata, if (unlikely(res_prepare == TX_DROP)) { ieee80211_free_txskb(&local->hw, skb); - return true; + return; } else if (unlikely(res_prepare == TX_QUEUED)) { - return true; + return; } /* set up hw_queue value early */ @@ -1962,15 +1833,23 @@ static bool ieee80211_tx(struct ieee80211_sub_if_data *sdata, sdata->vif.hw_queue[skb_get_queue_mapping(skb)]; if (invoke_tx_handlers_early(&tx)) - return true; + return; - if (ieee80211_queue_skb(local, sdata, tx.sta, tx.skb)) - return true; + txqi = ieee80211_queue_skb(local, sdata, tx.sta, tx.skb); + + if (likely(!noqueue)) + return; - if (!invoke_tx_handlers_late(&tx)) - result = __ieee80211_tx(local, &tx.skbs, tx.sta, txpending); + /* Noqueue frames bypass the normal TX and go out immediately */ - return result; + if (sta && sta->uploaded) + control.sta = txqi->txq.sta; + else + control.sta = NULL; + + skb = ieee80211_tx_dequeue(&local->hw, &txqi->txq); + if (!WARN_ON(!skb)) + drv_tx(local, &control, skb); } /* device xmit handlers */ @@ -2060,7 +1939,7 @@ void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, } ieee80211_set_qos_hdr(sdata, skb); - ieee80211_tx(sdata, sta, skb, false); + ieee80211_tx(sdata, sta, skb); } static bool ieee80211_validate_radiotap_len(struct sk_buff *skb) @@ -3674,7 +3553,6 @@ void __ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata, struct ieee80211_hdr *hdr = (void *)fast_tx->hdr; struct ieee80211_tx_info *info; struct ieee80211_tx_data tx; - ieee80211_tx_result r; int hw_headroom = sdata->local->hw.extra_tx_headroom; int extra_head = fast_tx->hdr_len - (ETH_HLEN - 2); @@ -3730,22 +3608,7 @@ void __ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata, tx.sta = sta; tx.key = fast_tx->key; - if (ieee80211_queue_skb(local, sdata, sta, skb)) - return; - - tx.skb = skb; - r = ieee80211_xmit_fast_finish(sdata, sta, fast_tx->pn_offs, - fast_tx->key, &tx); - tx.skb = NULL; - if (r == TX_DROP) - goto free; - - if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) - sdata = container_of(sdata->bss, - struct ieee80211_sub_if_data, u.ap); - - __skb_queue_tail(&tx.skbs, skb); - ieee80211_tx_frags(local, &sdata->vif, sta, &tx.skbs, false); + ieee80211_queue_skb(local, sdata, sta, skb); return; free: @@ -4519,65 +4382,6 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, return NETDEV_TX_OK; } - - -static bool __ieee80211_tx_8023(struct ieee80211_sub_if_data *sdata, - struct sk_buff *skb, struct sta_info *sta, - bool txpending) -{ - struct ieee80211_local *local = sdata->local; - struct ieee80211_tx_control control = {}; - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - struct ieee80211_sta *pubsta = NULL; - unsigned long flags; - int q = info->hw_queue; - - spin_lock_irqsave(&local->queue_stop_reason_lock, flags); - - if (local->queue_stop_reasons[q] || - (!txpending && !skb_queue_empty(&local->pending[q]))) { - if (txpending) - skb_queue_head(&local->pending[q], skb); - else - skb_queue_tail(&local->pending[q], skb); - - spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); - - return false; - } - - spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); - - if (sta && sta->uploaded) - pubsta = &sta->sta; - - control.sta = pubsta; - - drv_tx(local, &control, skb); - - return true; -} - -static bool ieee80211_tx_8023(struct ieee80211_sub_if_data *sdata, - struct sk_buff *skb, struct sta_info *sta, - bool txpending) -{ - struct ieee80211_local *local = sdata->local; - struct sk_buff *next; - bool ret = true; - - if (ieee80211_queue_skb(local, sdata, sta, skb)) - return true; - - skb_list_walk_safe(skb, skb, next) { - skb_mark_not_on_list(skb); - if (!__ieee80211_tx_8023(sdata, skb, sta, txpending)) - ret = false; - } - - return ret; -} - static void ieee80211_8023_xmit(struct ieee80211_sub_if_data *sdata, struct net_device *dev, struct sta_info *sta, struct ieee80211_key *key, struct sk_buff *skb) @@ -4656,8 +4460,7 @@ static void ieee80211_8023_xmit(struct ieee80211_sub_if_data *sdata, sta->deflink.tx_stats.bytes[queue] += len; ieee80211_tpt_led_trig_tx(local, len); - - ieee80211_tx_8023(sdata, skb, sta, false); + ieee80211_queue_skb(local, sdata, sta, skb); return; @@ -4764,19 +4567,13 @@ void ieee80211_clear_tx_pending(struct ieee80211_local *local) } } -/* - * Returns false if the frame couldn't be transmitted but was queued instead, - * which in this case means re-queued -- take as an indication to stop sending - * more pending frames. - */ -static bool ieee80211_tx_pending_skb(struct ieee80211_local *local, +static void ieee80211_tx_pending_skb(struct ieee80211_local *local, struct sk_buff *skb) { struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ieee80211_sub_if_data *sdata; struct sta_info *sta; struct ieee80211_hdr *hdr; - bool result; struct ieee80211_chanctx_conf *chanctx_conf; sdata = vif_to_sdata(info->control.vif); @@ -4788,34 +4585,25 @@ static bool ieee80211_tx_pending_skb(struct ieee80211_local *local, rcu_dereference(sdata->vif.bss_conf.chanctx_conf); if (unlikely(!chanctx_conf)) { dev_kfree_skb(skb); - return true; + return; } info->band = chanctx_conf->def.chan->band; } - result = ieee80211_tx(sdata, NULL, skb, true); + ieee80211_tx(sdata, NULL, skb); } else if (info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) { if (ieee80211_lookup_ra_sta(sdata, skb, &sta)) { dev_kfree_skb(skb); - return true; + return; } if (IS_ERR(sta) || (sta && !sta->uploaded)) sta = NULL; - result = ieee80211_tx_8023(sdata, skb, sta, true); + ieee80211_queue_skb(local, sdata, sta, skb); } else { - struct sk_buff_head skbs; - - __skb_queue_head_init(&skbs); - __skb_queue_tail(&skbs, skb); - - hdr = (struct ieee80211_hdr *)skb->data; sta = sta_info_get(sdata, hdr->addr1); - - result = __ieee80211_tx(local, &skbs, sta, true); + ieee80211_tx(sdata, sta, skb); } - - return result; } /* @@ -4827,7 +4615,6 @@ void ieee80211_tx_pending(struct tasklet_struct *t) tx_pending_tasklet); unsigned long flags; int i; - bool txok; rcu_read_lock(); @@ -4853,11 +4640,9 @@ void ieee80211_tx_pending(struct tasklet_struct *t) spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); - txok = ieee80211_tx_pending_skb(local, skb); + ieee80211_tx_pending_skb(local, skb); spin_lock_irqsave(&local->queue_stop_reason_lock, flags); - if (!txok) - break; } } spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); diff --git a/net/mac80211/util.c b/net/mac80211/util.c index c5b4dfab09e5..811448c096a6 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -349,8 +349,6 @@ static void __ieee80211_wake_txqs(struct ieee80211_sub_if_data *sdata, int ac) if (WARN_ON(!sdata)) goto out; - if (!test_bit(SDATA_STATE_RUNNING, &sdata->state)) - goto out; sdata = ieee80211_get_tx_sdata(sdata); vif = &sdata->vif; @@ -417,6 +415,9 @@ _ieee80211_wake_txqs(struct ieee80211_local *local, unsigned long *flags) for (ac = 0; ac < n_acs; ac++) { int ac_queue = sdata->vif.hw_queue[ac]; + if (unlikely(!ieee80211_sdata_running(sdata))) + continue; + if (ac_queue == i || sdata->vif.cab_queue == i) __ieee80211_wake_txqs(sdata, ac); @@ -1176,8 +1177,13 @@ void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata, if (sdata->vif.type != NL80211_IFTYPE_STATION || !(sdata->u.mgd.flags & IEEE80211_STA_MFP_ENABLED)) + /* + * Use offchannel txq and tx to avoid raceing + * the frame with tearing down sta txq's + */ IEEE80211_SKB_CB(skb)->flags |= - IEEE80211_TX_INTFL_DONT_ENCRYPT; + IEEE80211_TX_INTFL_DONT_ENCRYPT | + IEEE80211_TX_INTFL_OFFCHAN_TX_OK; ieee80211_tx_skb(sdata, skb); } From patchwork Mon Jan 27 16:26:20 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Wetzel X-Patchwork-Id: 860353 Received: from ns2.wdyn.eu (ns2.wdyn.eu [5.252.227.236]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 96B98156C79 for ; Mon, 27 Jan 2025 16:28:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=5.252.227.236 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737995310; cv=none; b=AsWznS1feQiSRLRpmrUzf+sGNNyWEVgdJ7qySXCb9rcRf3bLUdchyi/km8usTReIGLSzmsN0+7UzKGP5o4WLdfREbcrrO2lNFbf/mnL/NTysdsXHGSaWPOD1Dfy214kkbuw2Uay3uyKMXYJkuBh1XRJbT9AFbq6B5m2hGQy8o9E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737995310; c=relaxed/simple; bh=0hSQuwsn3oHCk2z5sQdHgygazfzOWqU0DtQIn02OqlA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=W0ji+QQsusKBkSz9qTF2ehyxzOyDIQeleLgP6JI5kixJT9zqf6WQq0bnDVp8afaFvaJAZ2j3I7pNsk05m7z0O8juqHDn+gwavePhfhjqhM4Oz7vPZ0jk8PW2vKs/Vs5FYu8r7ig8PWf5TPPbYbK0UilVdZUdQ+dBOYojw085rEo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=wetzel-home.de; spf=pass smtp.mailfrom=wetzel-home.de; dkim=pass (1024-bit key) header.d=wetzel-home.de header.i=@wetzel-home.de header.b=vyPoN4Og; arc=none smtp.client-ip=5.252.227.236 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=wetzel-home.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=wetzel-home.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=wetzel-home.de header.i=@wetzel-home.de header.b="vyPoN4Og" From: Alexander Wetzel DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=wetzel-home.de; s=wetzel-home; t=1737995298; bh=0hSQuwsn3oHCk2z5sQdHgygazfzOWqU0DtQIn02OqlA=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=vyPoN4Ogm52eDMo8skvJPZ/7MUcKXbe/VjSOirTlP8Ia04+LCU1v+TsflTSgeLKIN s7wh2YXJbHSZOkZm0/64SgkT5pxcyfcMDjlqtsoFwmn8UH21ZOy9buj5rrR6CFFTal QpCAubgBFJeS4FnC531/jozA/DXp99KO0AdTYI3w= To: linux-wireless@vger.kernel.org Cc: johannes@sipsolutions.net, Alexander Wetzel Subject: [RFC PATCH 08/13] wifi: mac80211: Call ieee80211_tx_h_select_key only once Date: Mon, 27 Jan 2025 17:26:20 +0100 Message-ID: <20250127162625.20747-9-Alexander@wetzel-home.de> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250127162625.20747-1-Alexander@wetzel-home.de> References: <20250127162625.20747-1-Alexander@wetzel-home.de> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 ieee80211_tx_dequeue() already calls ieee80211_tx_h_select_key() when needed. Move it from invoke_tx_handlers_early() to invoke_tx_handlers() to avoid calling it twice for TXQs. Signed-off-by: Alexander Wetzel --- net/mac80211/tx.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index d50ca692f348..748edc3dc63a 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -1691,7 +1691,6 @@ static int invoke_tx_handlers_early(struct ieee80211_tx_data *tx) CALL_TXH(ieee80211_tx_h_check_assoc); CALL_TXH(ieee80211_tx_h_ps_buf); CALL_TXH(ieee80211_tx_h_check_control_port_protocol); - CALL_TXH(ieee80211_tx_h_select_key); txh_done: if (unlikely(res == TX_DROP)) { @@ -1759,6 +1758,17 @@ static int invoke_tx_handlers(struct ieee80211_tx_data *tx) if (r) return r; + + r = ieee80211_tx_h_select_key(tx); + if (unlikely(r != TX_CONTINUE)) { + I802_DEBUG_INC(tx->local->tx_handlers_drop); + if (tx->skb) + ieee80211_free_txskb(&tx->local->hw, tx->skb); + else + ieee80211_purge_tx_queue(&tx->local->hw, &tx->skbs); + return -1; + } + return invoke_tx_handlers_late(tx); } From patchwork Mon Jan 27 16:26:21 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Wetzel X-Patchwork-Id: 860351 Received: from ns2.wdyn.eu (ns2.wdyn.eu [5.252.227.236]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 96B52156968 for ; Mon, 27 Jan 2025 16:28:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=5.252.227.236 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737995310; cv=none; b=RuwRyfGHqqg1KDr51oVaQ9tVFRLNVpb4ms587O950HO7ZFcgQPr+SlhhLyp+0W+vyaDIUOiVkPackNbiqFhx+twepswVDCn/13RwQHDuPvjXPP1yzJqwfJnhSmwt2O32owvtpFi53gTgzIa5zzNY9+97evw9fqQrzNsLwgzys0s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737995310; c=relaxed/simple; bh=z6mnBU3xaoXhwth5x4w3+gbUAHtCzp/KsUrD78p4jW0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Qx8wkVpyHFyJ+pKH++EfpSl/e6XDcM7mlbSGiEozNGr3i/DATyPzb33EhrT0hpgFDnQcWkzKPZqwxx5RGuYerb9TeifEWRWTYnXeWPYhksF59yX6WJ+PAkdUhGC6Dr8ZpqBCoLozMVGohoy+UwCQcHQ7VRR0xAOJ0hLReZystwM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=wetzel-home.de; spf=pass smtp.mailfrom=wetzel-home.de; dkim=pass (1024-bit key) header.d=wetzel-home.de header.i=@wetzel-home.de header.b=Bm4JkkRW; arc=none smtp.client-ip=5.252.227.236 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=wetzel-home.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=wetzel-home.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=wetzel-home.de header.i=@wetzel-home.de header.b="Bm4JkkRW" From: Alexander Wetzel DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=wetzel-home.de; s=wetzel-home; t=1737995298; bh=z6mnBU3xaoXhwth5x4w3+gbUAHtCzp/KsUrD78p4jW0=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=Bm4JkkRWLsuS14To0WFo1D/NedtNwXiXLGtQXO98dYNcrMSMGjObrMk/rrYlV58RN EUK3LI7IxeD5z0p1Zyfm8QitWfq+u29ufZmLZ41+TxX2u4caBj20zNFg7BYVwUoeCM zKHw83gmTc/AbR1hdBLj0HA71f6yVn7YjdNXBpcs= To: linux-wireless@vger.kernel.org Cc: johannes@sipsolutions.net, Alexander Wetzel Subject: [RFC PATCH 09/13] wifi: mac80211: Rename IEEE80211_TX_INTFL_OFFCHAN_TX_OK Date: Mon, 27 Jan 2025 17:26:21 +0100 Message-ID: <20250127162625.20747-10-Alexander@wetzel-home.de> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250127162625.20747-1-Alexander@wetzel-home.de> References: <20250127162625.20747-1-Alexander@wetzel-home.de> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 To make it clear that IEEE80211_TX_INTFL_OFFCHAN_TX_OK is now selecting the alternate TX path in mac80211 - which immediately sends the frame - the flag is renamed to IEEE80211_TX_INTFL_NOQUEUE_TX. Signed-off-by: Alexander Wetzel --- include/net/mac80211.h | 8 ++++---- net/mac80211/mlme.c | 2 +- net/mac80211/offchannel.c | 2 +- net/mac80211/rx.c | 2 +- net/mac80211/scan.c | 2 +- net/mac80211/tx.c | 6 +++--- net/mac80211/util.c | 2 +- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 41d91d69d61f..bec465595d41 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -897,9 +897,9 @@ struct ieee80211_bss_conf { * @IEEE80211_TX_CTL_RATE_CTRL_PROBE: internal to mac80211, can be * set by rate control algorithms to indicate probe rate, will * be cleared for fragmented frames (except on the last fragment) - * @IEEE80211_TX_INTFL_OFFCHAN_TX_OK: Internal to mac80211. Used to indicate - * that a frame can be transmitted while the queues are stopped for - * off-channel operation. + * @IEEE80211_TX_INTFL_NOQUEUE_TX: Internal to mac80211. Indicates that a frame + * can't be queued and must be transmitted immediately. Frames with this + * flag ignore offchannel queue stops and bypass wake_tx_queue(). * @IEEE80211_TX_CTL_HW_80211_ENCAP: This frame uses hardware encapsulation * (header conversion) * @IEEE80211_TX_INTFL_RETRIED: completely internal to mac80211, @@ -969,7 +969,7 @@ enum mac80211_tx_info_flags { IEEE80211_TX_STAT_AMPDU = BIT(10), IEEE80211_TX_STAT_AMPDU_NO_BACK = BIT(11), IEEE80211_TX_CTL_RATE_CTRL_PROBE = BIT(12), - IEEE80211_TX_INTFL_OFFCHAN_TX_OK = BIT(13), + IEEE80211_TX_INTFL_NOQUEUE_TX = BIT(13), IEEE80211_TX_CTL_HW_80211_ENCAP = BIT(14), IEEE80211_TX_INTFL_RETRIED = BIT(15), IEEE80211_TX_INTFL_DONT_ENCRYPT = BIT(16), diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 61c318f5239f..757df176c678 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -2033,7 +2033,7 @@ void ieee80211_send_nullfunc(struct ieee80211_local *local, nullfunc->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM); IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT | - IEEE80211_TX_INTFL_OFFCHAN_TX_OK; + IEEE80211_TX_INTFL_NOQUEUE_TX; if (ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS)) IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c index 29fab7ae47b4..85c27df0f423 100644 --- a/net/mac80211/offchannel.c +++ b/net/mac80211/offchannel.c @@ -1026,7 +1026,7 @@ int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, } IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_TX_OFFCHAN | - IEEE80211_TX_INTFL_OFFCHAN_TX_OK; + IEEE80211_TX_INTFL_NOQUEUE_TX; if (ieee80211_hw_check(&local->hw, QUEUE_CONTROL)) IEEE80211_SKB_CB(skb)->hw_queue = local->hw.offchannel_tx_hw_queue; diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 58c1b9a4e8b5..fa4d9a270de9 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -3970,7 +3970,7 @@ ieee80211_rx_h_action_return(struct ieee80211_rx_data *rx) struct ieee80211_tx_info *info = IEEE80211_SKB_CB(nskb); info->flags = IEEE80211_TX_CTL_TX_OFFCHAN | - IEEE80211_TX_INTFL_OFFCHAN_TX_OK | + IEEE80211_TX_INTFL_NOQUEUE_TX | IEEE80211_TX_CTL_NO_CCK_RATE; if (ieee80211_hw_check(&local->hw, QUEUE_CONTROL)) info->hw_queue = diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 4eb0cf5f73ca..ff81bf3d2781 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c @@ -668,7 +668,7 @@ static void ieee80211_scan_state_send_probe(struct ieee80211_local *local, scan_req = rcu_dereference_protected(local->scan_req, lockdep_is_held(&local->hw.wiphy->mtx)); - tx_flags = IEEE80211_TX_INTFL_OFFCHAN_TX_OK; + tx_flags = IEEE80211_TX_INTFL_NOQUEUE_TX; if (scan_req->no_cck) tx_flags |= IEEE80211_TX_CTL_NO_CCK_RATE; if (scan_req->flags & NL80211_SCAN_FLAG_MIN_PREQ_CONTENT) diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 748edc3dc63a..065c139eca92 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -230,7 +230,7 @@ ieee80211_tx_h_dynamic_ps(struct ieee80211_tx_data *tx) if (tx->sdata->vif.type != NL80211_IFTYPE_STATION) return TX_CONTINUE; - if (unlikely(info->flags & IEEE80211_TX_INTFL_OFFCHAN_TX_OK)) + if (unlikely(info->flags & IEEE80211_TX_INTFL_NOQUEUE_TX)) return TX_CONTINUE; ifmgd = &tx->sdata->u.mgd; @@ -1300,7 +1300,7 @@ static struct txq_info *ieee80211_get_txq(struct ieee80211_local *local, struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ieee80211_txq *txq = NULL; - if (unlikely(info->flags & IEEE80211_TX_INTFL_OFFCHAN_TX_OK)) { + if (unlikely(info->flags & IEEE80211_TX_INTFL_NOQUEUE_TX)) { if (sta) txq = sta->sta.txq[IEEE80211_TXQ_NOQUEUE]; else @@ -1817,7 +1817,7 @@ static void ieee80211_tx(struct ieee80211_sub_if_data *sdata, struct ieee80211_tx_data tx; ieee80211_tx_result res_prepare; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - bool noqueue = info->flags & IEEE80211_TX_INTFL_OFFCHAN_TX_OK; + bool noqueue = info->flags & IEEE80211_TX_INTFL_NOQUEUE_TX; struct ieee80211_tx_control control; struct txq_info *txqi; diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 811448c096a6..ef7d482d1984 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -1183,7 +1183,7 @@ void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata, */ IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT | - IEEE80211_TX_INTFL_OFFCHAN_TX_OK; + IEEE80211_TX_INTFL_NOQUEUE_TX; ieee80211_tx_skb(sdata, skb); } From patchwork Mon Jan 27 16:26:22 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Wetzel X-Patchwork-Id: 860352 Received: from ns2.wdyn.eu (ns2.wdyn.eu [5.252.227.236]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 96C2F157A6C for ; Mon, 27 Jan 2025 16:28:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=5.252.227.236 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737995310; cv=none; b=YV3HpBsnG4cdKM//zyq1mSzlt1ndKo0egcH3dw4YtsYDfIYj7gLcdhDH/6imgBd35TpOltmA3iAeHOjTF0Cwime+reOiOVeXk1B2pOuRetjyY8U6RzqrLHbJ/atGS9XGxHYR9puhFhCdBSEOfOhBp1gaafSA30dWk8nKPqzbclc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737995310; c=relaxed/simple; bh=+c9rJuQHj4MN/yByGlQ4vZcWoPEK5SOttbmvTjut6b8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=oXh9uU1ckKYfCD8F0n97f3ycAFLwl9X+Ekg7/MFr/alHOY1AAuctlQJJ+zDE9nvvmnO4RVB63TaWz6BHU8o3JfVfL0jW/9AfYbgvb0jDwnYXxhg8LHP/5s2XNVhrM/EmjfabjBz4Fy+1TfQwsOAcTCpDDRpSr3A8NHnf0JOJpbs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=wetzel-home.de; spf=pass smtp.mailfrom=wetzel-home.de; dkim=pass (1024-bit key) header.d=wetzel-home.de header.i=@wetzel-home.de header.b=km95iETQ; arc=none smtp.client-ip=5.252.227.236 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=wetzel-home.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=wetzel-home.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=wetzel-home.de header.i=@wetzel-home.de header.b="km95iETQ" From: Alexander Wetzel DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=wetzel-home.de; s=wetzel-home; t=1737995298; bh=+c9rJuQHj4MN/yByGlQ4vZcWoPEK5SOttbmvTjut6b8=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=km95iETQUX3YC3i98HXkh1leUaQBROxkkiB/ZevXOI5AOevFZ08qi4T8YqW1LIx/f +1BnG3NrtZFb5jkjeUCdHvqDnkHQQ90nL5aup/Wsg1qvA4iPJfQCcIziHXLe5ynjdp WUAhfVHlepzFzLkQxToML//rlPyjkP6Oj/GXq0yE= To: linux-wireless@vger.kernel.org Cc: johannes@sipsolutions.net, Alexander Wetzel Subject: [RFC PATCH 10/13] wifi: mac80211: Simplify AMPDU handling Date: Mon, 27 Jan 2025 17:26:22 +0100 Message-ID: <20250127162625.20747-11-Alexander@wetzel-home.de> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250127162625.20747-1-Alexander@wetzel-home.de> References: <20250127162625.20747-1-Alexander@wetzel-home.de> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Alexander Wetzel With all drivers now using TXQ we can simplify the AMPDU handling and avoid stopping the queues when enabling or disabling it. Move AMPDU handling fully into ieee80211_tx_dequeue() and use the flag %IEEE80211_TXQ_AMPDU to detect if AMPDU is operational. Signed-off-by: Alexander Wetzel --- net/mac80211/agg-tx.c | 127 ++----------------------------- net/mac80211/debugfs_sta.c | 2 - net/mac80211/ieee80211_i.h | 5 +- net/mac80211/main.c | 1 - net/mac80211/mesh.c | 13 +--- net/mac80211/rx.c | 9 +-- net/mac80211/sta_info.c | 3 - net/mac80211/sta_info.h | 30 ++++---- net/mac80211/tx.c | 149 ++++--------------------------------- 9 files changed, 38 insertions(+), 301 deletions(-) diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index 61f2cac37728..69663e51d2bb 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c @@ -138,45 +138,6 @@ void ieee80211_assign_tid_tx(struct sta_info *sta, int tid, rcu_assign_pointer(sta->ampdu_mlme.tid_tx[tid], tid_tx); } -/* - * When multiple aggregation sessions on multiple stations - * are being created/destroyed simultaneously, we need to - * refcount the global queue stop caused by that in order - * to not get into a situation where one of the aggregation - * setup or teardown re-enables queues before the other is - * ready to handle that. - * - * These two functions take care of this issue by keeping - * a global "agg_queue_stop" refcount. - */ -static void __acquires(agg_queue) -ieee80211_stop_queue_agg(struct ieee80211_sub_if_data *sdata, int tid) -{ - int queue = sdata->vif.hw_queue[ieee80211_ac_from_tid(tid)]; - - /* we do refcounting here, so don't use the queue reason refcounting */ - - if (atomic_inc_return(&sdata->local->agg_queue_stop[queue]) == 1) - ieee80211_stop_queue_by_reason( - &sdata->local->hw, queue, - IEEE80211_QUEUE_STOP_REASON_AGGREGATION, - false); - __acquire(agg_queue); -} - -static void __releases(agg_queue) -ieee80211_wake_queue_agg(struct ieee80211_sub_if_data *sdata, int tid) -{ - int queue = sdata->vif.hw_queue[ieee80211_ac_from_tid(tid)]; - - if (atomic_dec_return(&sdata->local->agg_queue_stop[queue]) == 0) - ieee80211_wake_queue_by_reason( - &sdata->local->hw, queue, - IEEE80211_QUEUE_STOP_REASON_AGGREGATION, - false); - __release(agg_queue); -} - static void ieee80211_agg_stop_txq(struct sta_info *sta, int tid) { @@ -224,40 +185,6 @@ ieee80211_agg_start_txq(struct sta_info *sta, int tid, bool enable) local_bh_enable(); } -/* - * splice packets from the STA's pending to the local pending, - * requires a call to ieee80211_agg_splice_finish later - */ -static void __acquires(agg_queue) -ieee80211_agg_splice_packets(struct ieee80211_sub_if_data *sdata, - struct tid_ampdu_tx *tid_tx, u16 tid) -{ - struct ieee80211_local *local = sdata->local; - int queue = sdata->vif.hw_queue[ieee80211_ac_from_tid(tid)]; - unsigned long flags; - - ieee80211_stop_queue_agg(sdata, tid); - - if (WARN(!tid_tx, - "TID %d gone but expected when splicing aggregates from the pending queue\n", - tid)) - return; - - if (!skb_queue_empty(&tid_tx->pending)) { - spin_lock_irqsave(&local->queue_stop_reason_lock, flags); - /* copy over remaining packets */ - skb_queue_splice_tail_init(&tid_tx->pending, - &local->pending[queue]); - spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); - } -} - -static void __releases(agg_queue) -ieee80211_agg_splice_finish(struct ieee80211_sub_if_data *sdata, u16 tid) -{ - ieee80211_wake_queue_agg(sdata, tid); -} - static void ieee80211_remove_tid_tx(struct sta_info *sta, int tid) { struct tid_ampdu_tx *tid_tx; @@ -267,23 +194,8 @@ static void ieee80211_remove_tid_tx(struct sta_info *sta, int tid) tid_tx = rcu_dereference_protected_tid_tx(sta, tid); - /* - * When we get here, the TX path will not be lockless any more wrt. - * aggregation, since the OPERATIONAL bit has long been cleared. - * Thus it will block on getting the lock, if it occurs. So if we - * stop the queue now, we will not get any more packets, and any - * that might be being processed will wait for us here, thereby - * guaranteeing that no packets go to the tid_tx pending queue any - * more. - */ - - ieee80211_agg_splice_packets(sta->sdata, tid_tx, tid); - /* future packets must not find the tid_tx struct any more */ ieee80211_assign_tid_tx(sta, tid, NULL); - - ieee80211_agg_splice_finish(sta->sdata, tid); - kfree_rcu(tid_tx, rcu_head); } @@ -355,6 +267,10 @@ int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, set_bit(HT_AGG_STATE_STOPPING, &tid_tx->state); + /* + * After this packets are no longer handed through + * to the driver + */ ieee80211_agg_stop_txq(sta, tid); spin_unlock_bh(&sta->lock); @@ -365,13 +281,6 @@ int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, del_timer_sync(&tid_tx->addba_resp_timer); del_timer_sync(&tid_tx->session_timer); - /* - * After this packets are no longer handed right through - * to the driver but are put onto tid_tx->pending instead, - * with locking to ensure proper access. - */ - clear_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state); - /* * There might be a few packets being processed right now (on * another CPU) that have already gotten past the aggregation @@ -395,12 +304,7 @@ int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, ret = drv_ampdu_action(local, sta->sdata, ¶ms); /* HW shall not deny going back to legacy */ - if (WARN_ON(ret)) { - /* - * We may have pending packets get stuck in this case... - * Not bothering with a workaround for now. - */ - } + WARN_ON(ret); /* * In the case of AGG_STOP_DESTROY_STA, the driver won't @@ -535,9 +439,7 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid) "BA request denied - HW unavailable for %pM tid %d\n", sta->sta.addr, tid); spin_lock_bh(&sta->lock); - ieee80211_agg_splice_packets(sdata, tid_tx, tid); ieee80211_assign_tid_tx(sta, tid, NULL); - ieee80211_agg_splice_finish(sdata, tid); spin_unlock_bh(&sta->lock); ieee80211_agg_start_txq(sta, tid, false); @@ -710,7 +612,6 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, goto err_unlock_sta; } - skb_queue_head_init(&tid_tx->pending); __set_bit(HT_AGG_STATE_WANT_START, &tid_tx->state); tid_tx->timeout = timeout; @@ -765,24 +666,6 @@ static void ieee80211_agg_tx_operational(struct ieee80211_local *local, sta->sta.addr, tid); drv_ampdu_action(local, sta->sdata, ¶ms); - - /* - * synchronize with TX path, while splicing the TX path - * should block so it won't put more packets onto pending. - */ - spin_lock_bh(&sta->lock); - - ieee80211_agg_splice_packets(sta->sdata, tid_tx, tid); - /* - * Now mark as operational. This will be visible - * in the TX path, and lets it go lock-free in - * the common case. - */ - set_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state); - ieee80211_agg_splice_finish(sta->sdata, tid); - - spin_unlock_bh(&sta->lock); - ieee80211_agg_start_txq(sta, tid, true); } diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c index a67a9d316008..890c01d848e5 100644 --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c @@ -343,8 +343,6 @@ static ssize_t sta_agg_status_do_read(struct wiphy *wiphy, struct file *file, p += scnprintf(p, bufsz + buf - p, "\t\t%x", !!tid_tx); p += scnprintf(p, bufsz + buf - p, "\t%#.2x", tid_tx ? tid_tx->dialog_token : 0); - p += scnprintf(p, bufsz + buf - p, "\t%03d", - tid_tx ? skb_queue_len(&tid_tx->pending) : 0); p += scnprintf(p, bufsz + buf - p, "\n"); } diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 25fdc8ce8644..9c00c4e60cfc 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1248,7 +1248,6 @@ enum queue_stop_reason { IEEE80211_QUEUE_STOP_REASON_DRIVER, IEEE80211_QUEUE_STOP_REASON_PS, IEEE80211_QUEUE_STOP_REASON_CSA, - IEEE80211_QUEUE_STOP_REASON_AGGREGATION, IEEE80211_QUEUE_STOP_REASON_SUSPEND, IEEE80211_QUEUE_STOP_REASON_SKB_ADD, IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL, @@ -1466,8 +1465,6 @@ struct ieee80211_local { struct tasklet_struct tx_pending_tasklet; struct tasklet_struct wake_txqs_tasklet; - atomic_t agg_queue_stop[IEEE80211_MAX_QUEUES]; - /* number of interfaces with allmulti RX */ atomic_t iff_allmultis; @@ -2110,7 +2107,7 @@ int ieee80211_probe_mesh_link(struct wiphy *wiphy, struct net_device *dev, void __ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata, struct sta_info *sta, struct ieee80211_fast_tx *fast_tx, - struct sk_buff *skb, bool ampdu, + struct sk_buff *skb, const u8 *da, const u8 *sa); void ieee80211_aggr_check(struct ieee80211_sub_if_data *sdata, struct sta_info *sta, struct sk_buff *skb); diff --git a/net/mac80211/main.c b/net/mac80211/main.c index f13c14fa82e8..0416ab7e1ca7 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -999,7 +999,6 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len, for (i = 0; i < IEEE80211_MAX_QUEUES; i++) { skb_queue_head_init(&local->pending[i]); - atomic_set(&local->agg_queue_stop[i], 0); } tasklet_setup(&local->tx_pending_tasklet, ieee80211_tx_pending); tasklet_setup(&local->wake_txqs_tasklet, ieee80211_wake_txqs); diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 974081324aa4..4fc91fe743c6 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -753,11 +753,9 @@ bool ieee80211_mesh_xmit_fast(struct ieee80211_sub_if_data *sdata, struct ieee80211_mesh_fast_tx *entry; struct ieee80211s_hdr *meshhdr; u8 sa[ETH_ALEN] __aligned(2); - struct tid_ampdu_tx *tid_tx; struct sta_info *sta; bool copy_sa = false; u16 ethertype; - u8 tid; if (ctrl_flags & IEEE80211_TX_CTRL_SKIP_MPATH_LOOKUP) return false; @@ -799,15 +797,6 @@ bool ieee80211_mesh_xmit_fast(struct ieee80211_sub_if_data *sdata, if (!sta) return false; - tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; - tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]); - if (tid_tx) { - if (!test_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state)) - return false; - if (tid_tx->timeout) - tid_tx->last_tx = jiffies; - } - skb = skb_share_check(skb, GFP_ATOMIC); if (!skb) return true; @@ -832,7 +821,7 @@ bool ieee80211_mesh_xmit_fast(struct ieee80211_sub_if_data *sdata, ether_addr_copy(meshhdr->eaddr2, sa); skb_push(skb, 2 * ETH_ALEN); - __ieee80211_xmit_fast(sdata, sta, &entry->fast_tx, skb, tid_tx, + __ieee80211_xmit_fast(sdata, sta, &entry->fast_tx, skb, entry->mpath->dst, sdata->vif.addr); return true; diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index fa4d9a270de9..1ff86e5969d4 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -2801,13 +2801,6 @@ ieee80211_rx_mesh_fast_forward(struct ieee80211_sub_if_data *sdata, tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]); - if (tid_tx) { - if (!test_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state)) - return false; - - if (tid_tx->timeout) - tid_tx->last_tx = jiffies; - } ieee80211_aggr_check(sdata, sta, skb); @@ -2821,7 +2814,7 @@ ieee80211_rx_mesh_fast_forward(struct ieee80211_sub_if_data *sdata, skb->dev = sdata->dev; memcpy(ð, skb->data, ETH_HLEN - 2); skb_pull(skb, 2); - __ieee80211_xmit_fast(sdata, sta, &entry->fast_tx, skb, tid_tx, + __ieee80211_xmit_fast(sdata, sta, &entry->fast_tx, skb, eth.h_dest, eth.h_source); IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_unicast); IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_frames); diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index ef5e466c5a3d..46695bcac4a7 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -178,9 +178,6 @@ static void __cleanup_single_sta(struct sta_info *sta) for (i = 0; i < IEEE80211_NUM_TIDS; i++) { kfree(sta->ampdu_mlme.tid_start_tx[i]); tid_tx = rcu_dereference_raw(sta->ampdu_mlme.tid_tx[i]); - if (!tid_tx) - continue; - ieee80211_purge_tx_queue(&local->hw, &tid_tx->pending); kfree(tid_tx); } } diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 9f89fb5bee37..20ae7f5a8760 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h @@ -113,15 +113,17 @@ enum ieee80211_sta_info_flags { #define HT_AGG_BURST_RETRIES 3 #define HT_AGG_RETRIES_PERIOD (15 * HZ) -#define HT_AGG_STATE_DRV_READY 0 -#define HT_AGG_STATE_RESPONSE_RECEIVED 1 -#define HT_AGG_STATE_OPERATIONAL 2 -#define HT_AGG_STATE_STOPPING 3 -#define HT_AGG_STATE_WANT_START 4 -#define HT_AGG_STATE_WANT_STOP 5 -#define HT_AGG_STATE_START_CB 6 -#define HT_AGG_STATE_STOP_CB 7 -#define HT_AGG_STATE_SENT_ADDBA 8 +/* txqi queues using aggregation have %IEEE80211_TXQ_AMPDU set */ +enum ieee80211_ht_agg_state { + HT_AGG_STATE_DRV_READY, + HT_AGG_STATE_RESPONSE_RECEIVED, + HT_AGG_STATE_STOPPING, + HT_AGG_STATE_WANT_START, + HT_AGG_STATE_WANT_STOP, + HT_AGG_STATE_START_CB, + HT_AGG_STATE_STOP_CB, + HT_AGG_STATE_SENT_ADDBA, +}; DECLARE_EWMA(avg_signal, 10, 8) enum ieee80211_agg_stop_reason { @@ -157,7 +159,6 @@ struct sta_info; * @rcu_head: rcu head for freeing structure * @session_timer: check if we keep Tx-ing on the TID (by timeout value) * @addba_resp_timer: timer for peer's response to addba request - * @pending: pending frames queue -- use sta's spinlock to protect * @sta: station we are attached to * @dialog_token: dialog token for aggregation session * @timeout: session timeout value to be filled in ADDBA requests @@ -176,16 +177,15 @@ struct sta_info; * the array holding it must hold the aggregation mutex. * * The TX path can access it under RCU lock-free if, and - * only if, the state has the flag %HT_AGG_STATE_OPERATIONAL - * set. Otherwise, the TX path must also acquire the spinlock - * and re-check the state, see comments in the tx code - * touching it. + * only if, the aggregation is operational (txq has the flag + * %IEEE80211_TXQ_AMPDU set). Otherwise, the TX path must also + * acquire the spinlock and re-check the state, see comments + * in the tx code touching it. */ struct tid_ampdu_tx { struct rcu_head rcu_head; struct timer_list session_timer; struct timer_list addba_resp_timer; - struct sk_buff_head pending; struct sta_info *sta; unsigned long state; unsigned long last_tx; diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 065c139eca92..d7cd27320df2 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -1102,77 +1102,6 @@ ieee80211_tx_h_calculate_duration(struct ieee80211_tx_data *tx) /* actual transmit path */ -static bool ieee80211_tx_prep_agg(struct ieee80211_tx_data *tx, - struct sk_buff *skb, - struct ieee80211_tx_info *info, - struct tid_ampdu_tx *tid_tx, - int tid) -{ - bool queued = false; - bool reset_agg_timer = false; - struct sk_buff *purge_skb = NULL; - - if (test_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state)) { - reset_agg_timer = true; - } else if (test_bit(HT_AGG_STATE_WANT_START, &tid_tx->state)) { - /* - * nothing -- this aggregation session is being started - * but that might still fail with the driver - */ - } else if (!tx->sta->sta.txq[tid]) { - spin_lock(&tx->sta->lock); - /* - * Need to re-check now, because we may get here - * - * 1) in the window during which the setup is actually - * already done, but not marked yet because not all - * packets are spliced over to the driver pending - * queue yet -- if this happened we acquire the lock - * either before or after the splice happens, but - * need to recheck which of these cases happened. - * - * 2) during session teardown, if the OPERATIONAL bit - * was cleared due to the teardown but the pointer - * hasn't been assigned NULL yet (or we loaded it - * before it was assigned) -- in this case it may - * now be NULL which means we should just let the - * packet pass through because splicing the frames - * back is already done. - */ - tid_tx = rcu_dereference_protected_tid_tx(tx->sta, tid); - - if (!tid_tx) { - /* do nothing, let packet pass through */ - } else if (test_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state)) { - reset_agg_timer = true; - } else { - queued = true; - if (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER) { - clear_sta_flag(tx->sta, WLAN_STA_SP); - ps_dbg(tx->sta->sdata, - "STA %pM aid %d: SP frame queued, close the SP w/o telling the peer\n", - tx->sta->sta.addr, tx->sta->sta.aid); - } - info->control.vif = &tx->sdata->vif; - info->control.flags |= IEEE80211_TX_INTCFL_NEED_TXPROCESSING; - info->flags &= ~IEEE80211_TX_TEMPORARY_FLAGS; - __skb_queue_tail(&tid_tx->pending, skb); - if (skb_queue_len(&tid_tx->pending) > STA_MAX_TX_BUFFER) - purge_skb = __skb_dequeue(&tid_tx->pending); - } - spin_unlock(&tx->sta->lock); - - if (purge_skb) - ieee80211_free_txskb(&tx->local->hw, purge_skb); - } - - /* reset session timer */ - if (reset_agg_timer) - tid_tx->last_tx = jiffies; - - return queued; -} - void ieee80211_aggr_check(struct ieee80211_sub_if_data *sdata, struct sta_info *sta, struct sk_buff *skb) { @@ -1208,7 +1137,6 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata, struct ieee80211_hdr *hdr; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); bool aggr_check = false; - int tid; memset(tx, 0, sizeof(*tx)); tx->skb = skb; @@ -1242,30 +1170,6 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata, } } - if (tx->sta && ieee80211_is_data_qos(hdr->frame_control) && - !ieee80211_is_qos_nullfunc(hdr->frame_control) && - ieee80211_hw_check(&local->hw, AMPDU_AGGREGATION) && - !ieee80211_hw_check(&local->hw, TX_AMPDU_SETUP_IN_HW)) { - struct tid_ampdu_tx *tid_tx; - - tid = ieee80211_get_tid(hdr); - tid_tx = rcu_dereference(tx->sta->ampdu_mlme.tid_tx[tid]); - if (!tid_tx && aggr_check) { - ieee80211_aggr_check(sdata, tx->sta, skb); - tid_tx = rcu_dereference(tx->sta->ampdu_mlme.tid_tx[tid]); - } - - if (tid_tx) { - bool queued; - - queued = ieee80211_tx_prep_agg(tx, skb, info, - tid_tx, tid); - - if (unlikely(queued)) - return TX_QUEUED; - } - } - if (is_multicast_ether_addr(hdr->addr1)) { tx->flags &= ~IEEE80211_TX_UNICAST; info->flags |= IEEE80211_TX_CTL_NO_ACK; @@ -3556,7 +3460,7 @@ ieee80211_tx_skb_fixup(struct sk_buff *skb, netdev_features_t features) void __ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata, struct sta_info *sta, struct ieee80211_fast_tx *fast_tx, - struct sk_buff *skb, bool ampdu, + struct sk_buff *skb, const u8 *da, const u8 *sa) { struct ieee80211_local *local = sdata->local; @@ -3631,11 +3535,8 @@ static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) { u16 ethertype = (skb->data[12] << 8) | skb->data[13]; - struct ieee80211_hdr *hdr = (void *)fast_tx->hdr; - struct tid_ampdu_tx *tid_tx = NULL; struct sk_buff *next; struct ethhdr eth; - u8 tid = IEEE80211_NUM_TIDS; /* control port protocol needs a lot of special handling */ if (cpu_to_be16(ethertype) == sdata->control_port_protocol) @@ -3649,17 +3550,6 @@ static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata, if (skb->sk && skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS) return false; - if (hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) { - tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; - tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]); - if (tid_tx) { - if (!test_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state)) - return false; - if (tid_tx->timeout) - tid_tx->last_tx = jiffies; - } - } - memcpy(ð, skb->data, ETH_HLEN - 2); /* after this point (skb is modified) we cannot return false */ @@ -3669,7 +3559,7 @@ static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata, skb_list_walk_safe(skb, skb, next) { skb_mark_not_on_list(skb); - __ieee80211_xmit_fast(sdata, sta, fast_tx, skb, tid_tx, + __ieee80211_xmit_fast(sdata, sta, fast_tx, skb, eth.h_dest, eth.h_source); } @@ -3783,9 +3673,19 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw, goto begin; } - if (test_bit(IEEE80211_TXQ_AMPDU, &txqi->flags)) - info->flags |= (IEEE80211_TX_CTL_AMPDU | - IEEE80211_TX_CTL_DONTFRAG); + ieee80211_aggr_check(tx.sdata, tx.sta, skb); + + if (test_bit(IEEE80211_TXQ_AMPDU, &txqi->flags)) { + struct tid_ampdu_tx *tid_tx; + + tid_tx = rcu_dereference(tx.sta->ampdu_mlme.tid_tx[txq->tid]); + if (!WARN_ON_ONCE(!tid_tx)) { + tid_tx->last_tx = jiffies; + + info->flags |= (IEEE80211_TX_CTL_AMPDU | + IEEE80211_TX_CTL_DONTFRAG); + } + } if (info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) { if (!ieee80211_hw_check(&local->hw, HAS_RATE_CONTROL)) { @@ -4153,7 +4053,6 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb, sta = NULL; skb_set_queue_mapping(skb, ieee80211_select_queue(sdata, sta, skb)); - ieee80211_aggr_check(sdata, sta, skb); if (sta) { struct ieee80211_fast_tx *fast_tx; @@ -4398,11 +4297,9 @@ static void ieee80211_8023_xmit(struct ieee80211_sub_if_data *sdata, { struct ieee80211_tx_info *info; struct ieee80211_local *local = sdata->local; - struct tid_ampdu_tx *tid_tx; struct sk_buff *seg, *next; unsigned int skbs = 0, len = 0; u16 queue; - u8 tid; queue = ieee80211_select_queue(sdata, sta, skb); skb_set_queue_mapping(skb, queue); @@ -4416,22 +4313,6 @@ static void ieee80211_8023_xmit(struct ieee80211_sub_if_data *sdata, return; ieee80211_aggr_check(sdata, sta, skb); - - tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; - tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]); - if (tid_tx) { - if (!test_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state)) { - /* fall back to non-offload slow path */ - __ieee80211_subif_start_xmit(skb, dev, 0, - IEEE80211_TX_CTRL_MLO_LINK_UNSPEC, - NULL); - return; - } - - if (tid_tx->timeout) - tid_tx->last_tx = jiffies; - } - skb = ieee80211_tx_skb_fixup(skb, ieee80211_sdata_netdev_features(sdata)); if (!skb) return; From patchwork Mon Jan 27 16:26:23 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Wetzel X-Patchwork-Id: 860350 Received: from ns2.wdyn.eu (ns2.wdyn.eu [5.252.227.236]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 96A027DA62 for ; Mon, 27 Jan 2025 16:28:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=5.252.227.236 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737995311; cv=none; b=LbHa2qG4bbTVXUxju2l6SuYKD8XgGhBCZbvOI1x2RVN3EI+g+hTqx7veZAQO4Eit2PAKhOk5o9DXb3Jzq5of6DsVM5k4fHq4AHETOk06jOQz6PYEZk3C0uB/wFEHCDTyRpsuQLdwFydJ6rrplFZuFgDguHf/lbi1TSAwUS97WLY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737995311; c=relaxed/simple; bh=CIJcatO2YxJXDSy+Ezf1UHFFgl3uxKNj4mY1sYn4kFw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=SDdPofiM5H9yvUlK3yILziFpS5+MPsJNxCliOXmVmsr7PuxzansF4lvjBiG3vOiPAAc/rYbWEVzsiTuQU5SmsrgrOGuiNyYLUxE3wqU0mTQYPehndnDL1vJgn+maYcHUKTMqSfa6Si5V90OqKd6vSbF2zP5Ob9ZRo/+bLclosLM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=wetzel-home.de; spf=pass smtp.mailfrom=wetzel-home.de; dkim=pass (1024-bit key) header.d=wetzel-home.de header.i=@wetzel-home.de header.b=aTM4vmVX; arc=none smtp.client-ip=5.252.227.236 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=wetzel-home.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=wetzel-home.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=wetzel-home.de header.i=@wetzel-home.de header.b="aTM4vmVX" From: Alexander Wetzel DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=wetzel-home.de; s=wetzel-home; t=1737995298; bh=CIJcatO2YxJXDSy+Ezf1UHFFgl3uxKNj4mY1sYn4kFw=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=aTM4vmVX+kaxEGMTtmDLy6PAVLZnBCySLgw9aBH16qCJKmhgNw+6rFMvrb4g9hfoe CGmUljqErq0mlm/U/sTHMtUBW619y2UwCr5zViPG+cXZdgvG2/HLrlh+JUaUobdlgb BsV1MjDOp+dEhTkewUq9JkGeiN3kQQkYK6vkajxo= To: linux-wireless@vger.kernel.org Cc: johannes@sipsolutions.net, Alexander Wetzel Subject: [RFC PATCH 11/13] wifi: mac80211: Migrate TX to kthread Date: Mon, 27 Jan 2025 17:26:23 +0100 Message-ID: <20250127162625.20747-12-Alexander@wetzel-home.de> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250127162625.20747-1-Alexander@wetzel-home.de> References: <20250127162625.20747-1-Alexander@wetzel-home.de> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Use a per-phy kthread to handle all TX operations except IEEE80211_TX_INTFL_NOQUEUE_TX. Signed-off-by: Alexander Wetzel --- net/mac80211/agg-tx.c | 2 +- net/mac80211/driver-ops.h | 7 ----- net/mac80211/ieee80211_i.h | 7 +++-- net/mac80211/main.c | 7 +++-- net/mac80211/sta_info.c | 2 +- net/mac80211/tx.c | 14 +++++++-- net/mac80211/util.c | 64 +++++++++++++++++++++++++++++++++----- 7 files changed, 80 insertions(+), 23 deletions(-) diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index 69663e51d2bb..ec00e5730f1c 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c @@ -180,7 +180,7 @@ ieee80211_agg_start_txq(struct sta_info *sta, int tid, bool enable) clear_bit(IEEE80211_TXQ_STOP, &txqi->flags); local_bh_disable(); rcu_read_lock(); - schedule_and_wake_txq(sta->sdata->local, txqi); + ieee80211_schedule_txq(&sta->sdata->local->hw, &txqi->txq); rcu_read_unlock(); local_bh_enable(); } diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 3a7980b5a00a..0ddfa16bca7b 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h @@ -1388,13 +1388,6 @@ static inline void drv_wake_tx_queue(struct ieee80211_local *local, local->ops->wake_tx_queue(&local->hw, &txq->txq); } -static inline void schedule_and_wake_txq(struct ieee80211_local *local, - struct txq_info *txqi) -{ - ieee80211_schedule_txq(&local->hw, &txqi->txq); - drv_wake_tx_queue(local, txqi); -} - static inline int drv_can_aggregate_in_amsdu(struct ieee80211_local *local, struct sk_buff *head, struct sk_buff *skb) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 9c00c4e60cfc..8bd1e4f0e5fd 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1341,9 +1341,7 @@ struct ieee80211_local { spinlock_t active_txq_lock[IEEE80211_NUM_ACS]; struct list_head active_txqs[IEEE80211_NUM_ACS]; u16 schedule_round[IEEE80211_NUM_ACS]; - - /* serializes ieee80211_handle_wake_tx_queue */ - spinlock_t handle_wake_tx_queue_lock; + bool txq_scheduler_used; u16 airtime_flags; u32 aql_txq_limit_low[IEEE80211_NUM_ACS]; @@ -1464,6 +1462,8 @@ struct ieee80211_local { struct sk_buff_head pending[IEEE80211_MAX_QUEUES]; struct tasklet_struct tx_pending_tasklet; struct tasklet_struct wake_txqs_tasklet; + struct task_struct *mac80211_tsk; + wait_queue_head_t mac80211_tsk_wq; /* number of interfaces with allmulti RX */ atomic_t iff_allmultis; @@ -2541,6 +2541,7 @@ void ieee80211_txq_remove_vlan(struct ieee80211_local *local, void ieee80211_fill_txq_stats(struct cfg80211_txq_stats *txqstats, struct txq_info *txqi); void ieee80211_wake_txqs(struct tasklet_struct *t); +int mac80211_thread(void *data); void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, u16 transaction, u16 auth_alg, u16 status, const u8 *extra, size_t extra_len, const u8 *bssid, diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 0416ab7e1ca7..25d5a57a74ca 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -972,8 +972,6 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len, local->aql_threshold = IEEE80211_AQL_THRESHOLD; atomic_set(&local->aql_total_pending_airtime, 0); - spin_lock_init(&local->handle_wake_tx_queue_lock); - INIT_LIST_HEAD(&local->chanctx_list); wiphy_delayed_work_init(&local->scan_work, ieee80211_scan_work); @@ -1004,6 +1002,10 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len, tasklet_setup(&local->wake_txqs_tasklet, ieee80211_wake_txqs); tasklet_setup(&local->tasklet, ieee80211_tasklet_handler); + init_waitqueue_head(&local->mac80211_tsk_wq); + local->mac80211_tsk = kthread_run(mac80211_thread, local, + "mac80211-%s", wiphy_name(wiphy)); + skb_queue_head_init(&local->skb_queue); skb_queue_head_init(&local->skb_queue_unreliable); @@ -1655,6 +1657,7 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) { struct ieee80211_local *local = hw_to_local(hw); + kthread_stop(local->mac80211_tsk); tasklet_kill(&local->tx_pending_tasklet); tasklet_kill(&local->tasklet); diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 46695bcac4a7..7342f9466299 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -1714,7 +1714,7 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) if (!sta->sta.txq[i] || !txq_has_queue(sta->sta.txq[i])) continue; - schedule_and_wake_txq(local, to_txq_info(sta->sta.txq[i])); + ieee80211_schedule_txq(&local->hw, sta->sta.txq[i]); } skb_queue_head_init(&pending); diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index d7cd27320df2..bd2f3c183e49 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -1567,7 +1567,7 @@ static struct txq_info *ieee80211_queue_skb(struct ieee80211_local *local, ieee80211_txq_enqueue(local, txqi, skb); if (likely(txqi->txq.tid != IEEE80211_TXQ_NOQUEUE)) - schedule_and_wake_txq(local, txqi); + ieee80211_schedule_txq(&local->hw, &txqi->txq); return txqi; } @@ -3823,6 +3823,11 @@ struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, u8 ac) found_eligible_txq = false; } + if (test_bit(IEEE80211_TXQ_DIRTY, &txqi->flags)) { + list_del_init(&txqi->schedule_order); + goto begin; + } + if (!head) head = txqi; @@ -3889,8 +3894,9 @@ void __ieee80211_schedule_txq(struct ieee80211_hw *hw, &local->active_txqs[txq->ac]); if (has_queue) ieee80211_txq_set_active(txqi); - } + wake_up_interruptible(&local->mac80211_tsk_wq); + } spin_unlock_bh(&local->active_txq_lock[txq->ac]); } EXPORT_SYMBOL(__ieee80211_schedule_txq); @@ -4006,6 +4012,8 @@ void ieee80211_txq_schedule_start(struct ieee80211_hw *hw, u8 ac) { struct ieee80211_local *local = hw_to_local(hw); + local->txq_scheduler_used = true; + spin_lock_bh(&local->active_txq_lock[ac]); if (ieee80211_txq_schedule_airtime_check(local, ac)) { @@ -4032,6 +4040,8 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb, struct sk_buff *next; int len = skb->len; + skb->dev = dev; + if (unlikely(!ieee80211_sdata_running(sdata) || skb->len < ETH_HLEN)) { kfree_skb(skb); return; diff --git a/net/mac80211/util.c b/net/mac80211/util.c index ef7d482d1984..1f84b83b0ea4 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -307,16 +307,14 @@ void ieee80211_handle_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_sub_if_data *sdata = vif_to_sdata(txq->vif); struct ieee80211_txq *queue; - spin_lock(&local->handle_wake_tx_queue_lock); - /* Use ieee80211_next_txq() for airtime fairness accounting */ ieee80211_txq_schedule_start(hw, txq->ac); - while ((queue = ieee80211_next_txq(hw, txq->ac))) { + queue = ieee80211_next_txq(hw, txq->ac); + if (queue) { wake_tx_push_queue(local, sdata, queue); ieee80211_return_txq(hw, queue, false); } ieee80211_txq_schedule_end(hw, txq->ac); - spin_unlock(&local->handle_wake_tx_queue_lock); } EXPORT_SYMBOL(ieee80211_handle_wake_tx_queue); @@ -326,11 +324,9 @@ static void __ieee80211_wake_txq(struct ieee80211_local *local, struct txq_info *txqi = to_txq_info(txq); struct fq *fq = &local->fq; - if (WARN_ON(!txq)) - return; if (test_and_clear_bit(IEEE80211_TXQ_DIRTY, &txqi->flags)) { spin_unlock(&fq->lock); - drv_wake_tx_queue(local, txqi); + ieee80211_schedule_txq(&local->hw, txq); spin_lock(&fq->lock); } } @@ -486,6 +482,60 @@ static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue, _ieee80211_wake_txqs(local, flags); } +static int ac_has_active_txq(struct ieee80211_local *local) +{ + int ac; + + for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { + spin_lock_bh(&local->active_txq_lock[ac]); + if (!list_empty(&local->active_txqs[ac])) + goto out; + spin_unlock_bh(&local->active_txq_lock[ac]); + } + return IEEE80211_NUM_ACS; +out: + spin_unlock_bh(&local->active_txq_lock[ac]); + return ac; +} + +int mac80211_thread(void *data) +{ + struct ieee80211_local *local = data; + struct txq_info *txqi, *tmp; + unsigned int ac = IEEE80211_NUM_ACS; + + while (1) { + wait_event_interruptible(local->mac80211_tsk_wq, + (ac = ac_has_active_txq(local)) + != IEEE80211_NUM_ACS); + if (kthread_should_stop()) + break; + + rcu_read_lock(); + + list_for_each_entry_safe(txqi, tmp, + &local->active_txqs[ac], + schedule_order) { + local->txq_scheduler_used = false; + local_bh_disable(); + drv_wake_tx_queue(local, txqi); + local_bh_enable(); + if (!local->txq_scheduler_used) { + /* Driver is not using + * ieee80211_txq_schedule_start(). + * Take over cleaning up the schedule. + */ + spin_lock_bh(&local->active_txq_lock[ac]); + list_del_init(&txqi->schedule_order); + spin_unlock_bh(&local->active_txq_lock[ac]); + } + } + + rcu_read_unlock(); + } + return 0; +} + void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue, enum queue_stop_reason reason, bool refcounted) From patchwork Mon Jan 27 16:26:24 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Wetzel X-Patchwork-Id: 860618 Received: from ns2.wdyn.eu (ns2.wdyn.eu [5.252.227.236]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 96A77155382 for ; Mon, 27 Jan 2025 16:28:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=5.252.227.236 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737995310; cv=none; b=g3KnNREO9oxpzZRCEOdGp/8mfutMke5W2chSuP6yPKtos6ayZ19K526fjHyVj58CycOQAJNkx3yqiDmaVA5JWBPmeoyvld9/tDHYihc/17xTN9jWkNQW/7D1GKd5tevZR0MSpLrjuXi3UJ0iiTneKuvCH/nv5u0dJNJAinLDh5U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737995310; c=relaxed/simple; bh=zALIxcHhdlrIeE0+Nh3VjnJG+JShCnkMPBwDDnFgZBA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Ntwe44vJ2cduSaCuC4aYlW9NY4GQ0sZl5xhiorScKa4ZLJuyvwWvEF9YMq/EmM4IFfqy38CQbZjmXQQvlGHqeleIVfmWni8emEpZuxFgsmVHVM7NCnFOaJk5/syy3mi0x1GJn94JcdCCqAyPHa5/ddoIv76Z6p2PFkgpdoW4lcc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=wetzel-home.de; spf=pass smtp.mailfrom=wetzel-home.de; dkim=pass (1024-bit key) header.d=wetzel-home.de header.i=@wetzel-home.de header.b=HFZqmdIw; arc=none smtp.client-ip=5.252.227.236 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=wetzel-home.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=wetzel-home.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=wetzel-home.de header.i=@wetzel-home.de header.b="HFZqmdIw" From: Alexander Wetzel DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=wetzel-home.de; s=wetzel-home; t=1737995298; bh=zALIxcHhdlrIeE0+Nh3VjnJG+JShCnkMPBwDDnFgZBA=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=HFZqmdIwJz762wcJfwbGG/8z3qa1/r/4Ew9g3VbRz+hlHCVllRu+kNOFksbiEQlNV FGmq91zfZK0wwx/abfQdwoFq93ET9icxxroCXbw7UZgMAYbZ6HdGoelbR/Nb+gSIvG 6urBSaVHZZ2ocfusMlnXRIhJt4yP7VPJ37BTQsK0= To: linux-wireless@vger.kernel.org Cc: johannes@sipsolutions.net, Alexander Wetzel Subject: [RFC PATCH 12/13] wifi: mac80211: Drop wake_txqs_tasklet Date: Mon, 27 Jan 2025 17:26:24 +0100 Message-ID: <20250127162625.20747-13-Alexander@wetzel-home.de> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250127162625.20747-1-Alexander@wetzel-home.de> References: <20250127162625.20747-1-Alexander@wetzel-home.de> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 _ieee80211_wake_txqs() is no longer handling TX, making the wake_txqs_tasklet unnecessary. Signed-off-by: Alexander Wetzel --- net/mac80211/ieee80211_i.h | 2 -- net/mac80211/main.c | 1 - net/mac80211/util.c | 16 +--------------- 3 files changed, 1 insertion(+), 18 deletions(-) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 8bd1e4f0e5fd..cecf2363fd85 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1461,7 +1461,6 @@ struct ieee80211_local { struct sk_buff_head pending[IEEE80211_MAX_QUEUES]; struct tasklet_struct tx_pending_tasklet; - struct tasklet_struct wake_txqs_tasklet; struct task_struct *mac80211_tsk; wait_queue_head_t mac80211_tsk_wq; @@ -2540,7 +2539,6 @@ void ieee80211_txq_remove_vlan(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata); void ieee80211_fill_txq_stats(struct cfg80211_txq_stats *txqstats, struct txq_info *txqi); -void ieee80211_wake_txqs(struct tasklet_struct *t); int mac80211_thread(void *data); void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, u16 transaction, u16 auth_alg, u16 status, diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 25d5a57a74ca..c634a781970b 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -999,7 +999,6 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len, skb_queue_head_init(&local->pending[i]); } tasklet_setup(&local->tx_pending_tasklet, ieee80211_tx_pending); - tasklet_setup(&local->wake_txqs_tasklet, ieee80211_wake_txqs); tasklet_setup(&local->tasklet, ieee80211_tasklet_handler); init_waitqueue_head(&local->mac80211_tsk_wq); diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 1f84b83b0ea4..0513a1da2b51 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -425,17 +425,6 @@ _ieee80211_wake_txqs(struct ieee80211_local *local, unsigned long *flags) rcu_read_unlock(); } -void ieee80211_wake_txqs(struct tasklet_struct *t) -{ - struct ieee80211_local *local = from_tasklet(local, t, - wake_txqs_tasklet); - unsigned long flags; - - spin_lock_irqsave(&local->queue_stop_reason_lock, flags); - _ieee80211_wake_txqs(local, &flags); - spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); -} - static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue, enum queue_stop_reason reason, bool refcounted, @@ -476,10 +465,7 @@ static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue, * release someone's lock, but it is fine because all the callers of * __ieee80211_wake_queue call it right before releasing the lock. */ - if (reason == IEEE80211_QUEUE_STOP_REASON_DRIVER) - tasklet_schedule(&local->wake_txqs_tasklet); - else - _ieee80211_wake_txqs(local, flags); + _ieee80211_wake_txqs(local, flags); } static int ac_has_active_txq(struct ieee80211_local *local) From patchwork Mon Jan 27 16:26:25 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Wetzel X-Patchwork-Id: 860616 Received: from ns2.wdyn.eu (ns2.wdyn.eu [5.252.227.236]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 96BED157493 for ; Mon, 27 Jan 2025 16:28:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=5.252.227.236 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737995310; cv=none; b=f5nap2bayhxoUCwzrDo1ZpgwIYn4Y1THhsODW3rKarA1LRIDqSYLxIShO++SPP9/CzDhKH3xvzPteUeDfW72NyJwld5+1Q+4W+qP//R7NaDxjaMTslkEBaeDbD4CMUwV8rIz88FS5xM7QGJ5LyL0aOlGXfFpZrynuOiq+G0P3iY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737995310; c=relaxed/simple; bh=yNGmMPQsNAIKQisDkqd0Xdu1EpRz+A2n4k3y9qo0380=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=V/hNnEYNKT0lWaZGcp1FyP3P1f+fR9lu2Xd5Vszyf4nUYaVOKb0a8RxfWfv6z9RsDBbb81disA9/7+pm1YTpxvd1fPsZ84vn3yKQZrRxjR9kKp/mPnqWTf5fXh/3m58RJs1hRVWuQ+DdoD3hj1hQ+7k6UjUOXPLTKgB8H6lLuGA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=wetzel-home.de; spf=pass smtp.mailfrom=wetzel-home.de; dkim=pass (1024-bit key) header.d=wetzel-home.de header.i=@wetzel-home.de header.b=J4rBDNgw; arc=none smtp.client-ip=5.252.227.236 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=wetzel-home.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=wetzel-home.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=wetzel-home.de header.i=@wetzel-home.de header.b="J4rBDNgw" From: Alexander Wetzel DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=wetzel-home.de; s=wetzel-home; t=1737995298; bh=yNGmMPQsNAIKQisDkqd0Xdu1EpRz+A2n4k3y9qo0380=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=J4rBDNgwXHKSYUKB1oLobUBaSCm1KV76Gd3dqFneR9/AuECaDu3gIh/9OQaaDZeVR T3hbule4y6Cv2CvQ5w+ObFyJ+6sLww43WSvs/0Qw2a0IPRnREa1f0OhJQspfY+odXZ QVyCNLAPwu3SHpSkgsDSrCmEwnr/NQGFTzFjToL0= To: linux-wireless@vger.kernel.org Cc: johannes@sipsolutions.net, Alexander Wetzel Subject: [RFC PATCH 13/13] wifi: mac80211: Cleanup *ieee80211_wake_txq* naming Date: Mon, 27 Jan 2025 17:26:25 +0100 Message-ID: <20250127162625.20747-14-Alexander@wetzel-home.de> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250127162625.20747-1-Alexander@wetzel-home.de> References: <20250127162625.20747-1-Alexander@wetzel-home.de> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 ieee80211_wake_txq() and ieee80211_wake_txqs() are not used. Rename: _ieee80211_wake_txqs() -> ieee80211_wake_txqs() __ieee80211_wake_txqs() -> _ieee80211_wake_txqs() __ieee80211_wake_txq() -> ieee80211_wake_txq() Signed-off-by: Alexander Wetzel --- net/mac80211/iface.c | 2 +- net/mac80211/util.c | 26 ++++++++++++-------------- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 9b2d0b3ae132..c650bc3df986 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -467,7 +467,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do lockdep_assert_wiphy(local->hw.wiphy); clear_bit(SDATA_STATE_RUNNING, &sdata->state); - synchronize_rcu(); /* flush _ieee80211_wake_txqs() */ + synchronize_rcu(); /* flush ieee80211_wake_txqs() */ cancel_scan = rcu_access_pointer(local->scan_sdata) == sdata; if (cancel_scan) diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 0513a1da2b51..985644949d7e 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -318,8 +318,8 @@ void ieee80211_handle_wake_tx_queue(struct ieee80211_hw *hw, } EXPORT_SYMBOL(ieee80211_handle_wake_tx_queue); -static void __ieee80211_wake_txq(struct ieee80211_local *local, - struct ieee80211_txq *txq) +static void ieee80211_wake_txq(struct ieee80211_local *local, + struct ieee80211_txq *txq) { struct txq_info *txqi = to_txq_info(txq); struct fq *fq = &local->fq; @@ -331,7 +331,7 @@ static void __ieee80211_wake_txq(struct ieee80211_local *local, } } -static void __ieee80211_wake_txqs(struct ieee80211_sub_if_data *sdata, int ac) +static void _ieee80211_wake_txqs(struct ieee80211_sub_if_data *sdata, int ac) { struct ieee80211_local *local = sdata->local; struct fq *fq = &local->fq; @@ -354,15 +354,13 @@ static void __ieee80211_wake_txqs(struct ieee80211_sub_if_data *sdata, int ac) /* %IEEE80211_VIF_TXQ_NOQUEUE must be ignored here */ - if (ac == IEEE80211_AC_VO) { - __ieee80211_wake_txq(local, - vif->txq[IEEE80211_VIF_TXQ_FALLBACK]); - } + if (ac == IEEE80211_AC_VO) + ieee80211_wake_txq(local, vif->txq[IEEE80211_VIF_TXQ_FALLBACK]); if (ac == IEEE80211_AC_BE && vif->txq[IEEE80211_VIF_TXQ_MULTICAST] && (!ps || !atomic_read(&ps->num_sta_ps))) - __ieee80211_wake_txq(local, - vif->txq[IEEE80211_VIF_TXQ_MULTICAST]); + ieee80211_wake_txq(local, + vif->txq[IEEE80211_VIF_TXQ_MULTICAST]); list_for_each_entry_rcu(sta, &local->sta_list, list) { if (sdata != sta->sdata) @@ -378,7 +376,7 @@ static void __ieee80211_wake_txqs(struct ieee80211_sub_if_data *sdata, int ac) if (ac != txq->ac) continue; - __ieee80211_wake_txq(local, txq); + ieee80211_wake_txq(local, txq); } } out: @@ -389,7 +387,7 @@ static void __ieee80211_wake_txqs(struct ieee80211_sub_if_data *sdata, int ac) static void __releases(&local->queue_stop_reason_lock) __acquires(&local->queue_stop_reason_lock) -_ieee80211_wake_txqs(struct ieee80211_local *local, unsigned long *flags) +ieee80211_wake_txqs(struct ieee80211_local *local, unsigned long *flags) { struct ieee80211_sub_if_data *sdata; int n_acs = IEEE80211_NUM_ACS; @@ -416,7 +414,7 @@ _ieee80211_wake_txqs(struct ieee80211_local *local, unsigned long *flags) if (ac_queue == i || sdata->vif.cab_queue == i) - __ieee80211_wake_txqs(sdata, ac); + _ieee80211_wake_txqs(sdata, ac); } } spin_lock_irqsave(&local->queue_stop_reason_lock, *flags); @@ -459,13 +457,13 @@ static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue, tasklet_schedule(&local->tx_pending_tasklet); /* - * Calling _ieee80211_wake_txqs here can be a problem because it may + * Calling ieee80211_wake_txqs here can be a problem because it may * release queue_stop_reason_lock which has been taken by * __ieee80211_wake_queue's caller. It is certainly not very nice to * release someone's lock, but it is fine because all the callers of * __ieee80211_wake_queue call it right before releasing the lock. */ - _ieee80211_wake_txqs(local, flags); + ieee80211_wake_txqs(local, flags); } static int ac_has_active_txq(struct ieee80211_local *local)