From nobody Sun Feb 18 21:11:19 2024 X-Original-To: dev-commits-src-branches@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4TdJHr41kRz5Bm8g; Sun, 18 Feb 2024 21:11:20 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4TdJHq4MLNz42XH; Sun, 18 Feb 2024 21:11:19 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1708290679; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=3nC5taLtdkXgYTSS4L4YCvSqTF1ctm/Jbo1oeD6K8kc=; b=fCzfaUTb/tZT5BBZ7h4gat3YTKoHASrX98hrFLBgggxj7f9cyyldzYo12Nf3Xm40mlEBLz /ZGp6tN3GhnLi0hEmXOBua8fD9LM2gGxC8US4gLMsaJgDhwkRQfBSgoJGe8nnPB4DuCETl JxTFzz4IH2KkO5w9wcHa5QItBaCf0KGLm4yLcQN3BIcs64rk3V57bQnz64ZkPFQZ6hxbt3 3QUOSJ61INM9vMdTQqKJexDWRfmquTd7N6AHZ9uwmja/BeMJy6e9WyQyRxAWO0b2YFlfav j4IHWF+3E/tILc8kf+Li5RMf0z9Krq103QPL4bnJHrgWjxUoJc3ZV6vA3WVQ0g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1708290679; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=3nC5taLtdkXgYTSS4L4YCvSqTF1ctm/Jbo1oeD6K8kc=; b=TZEV+pGvNrJIsbzbWRgi48JuWwTxd/s4kCIwUTTWYqIzfDFHz+9m/8MJrOA4EwGKb5jLan qrrKRglYt0fdUbWEGLmAoURLKaVebG82miiiU2DLf33GriMv0ANi0ZJzjigbJlvyyeYUcu gcmxEaVCQW112V3myDkghdgzCcT3VHY+QfJr37PQVXMRauljIDjyMY7l1jKpwLGIbJRdaA 7JXayqvLTRUwKUzt5ZsUXHIEH0Xt/lAvsgzoPBUzvG0fG7FBzMQyJbK+ptcCyO+EHxYYsi qKWcc5ggnD32uHmVJlBHHIF1IboJ3yVz4Kz853GyVLVKUG2V9tyYXn5OHHEhcg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1708290679; a=rsa-sha256; cv=none; b=vWfh67JIaiFn0NR7U5qAKc1oHUq8zbM3WTT3QmSgDNecleJZgEAMkaaEUW2/3r1C2QOxRs eb1baWCZuqLffsxcHIEmB2h65FMWY+xMYimw/UaDu/TUdzMzq5HmhMXdErXVa6254lhLAo 9zfkTjAW5boU1B6rSWqEweyN9ma7Jhi+F20dGf82q9DwxvW4j7CrD/CpeKTIh5OCwiK+oZ eKTVzaxZWU1k3+fVrvLtLZy63523RLQ7vlrFaeI604oPw/gSmRU/TGJiKYEYqdVYn/7osP BilA4NqjyemUYAA/UBYmMxK6Az/KOKixEOeyy6g+DrBBHfwOX+zxUXkZ92DSAA== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4TdJHq3JjTz15xt; Sun, 18 Feb 2024 21:11:19 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.17.1/8.17.1) with ESMTP id 41ILBJqb014510; Sun, 18 Feb 2024 21:11:19 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 41ILBJrB014507; Sun, 18 Feb 2024 21:11:19 GMT (envelope-from git) Date: Sun, 18 Feb 2024 21:11:19 GMT Message-Id: <202402182111.41ILBJrB014507@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: "Bjoern A. Zeeb" Subject: git: 1c7be8ecaddf - stable/14 - LinuxKPI: 802.11: more TXQ implementation and locking List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-branches@freebsd.org X-BeenThere: dev-commits-src-branches@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: bz X-Git-Repository: src X-Git-Refname: refs/heads/stable/14 X-Git-Reftype: branch X-Git-Commit: 1c7be8ecaddfac2b412244e91f924bf73f95658a Auto-Submitted: auto-generated The branch stable/14 has been updated by bz: URL: https://cgit.FreeBSD.org/src/commit/?id=1c7be8ecaddfac2b412244e91f924bf73f95658a commit 1c7be8ecaddfac2b412244e91f924bf73f95658a Author: Bjoern A. Zeeb AuthorDate: 2023-12-12 01:59:17 +0000 Commit: Bjoern A. Zeeb CommitDate: 2024-02-18 18:31:14 +0000 LinuxKPI: 802.11: more TXQ implementation and locking Implement ieee80211_handle_wake_tx_queue() and ieee80211_tx_dequeue_ni() while looking at the code. They are needed by various wireless drivers. Introduce an ltxq lock and protect the skbq by that. This prevents panics due to a race between a driver upcall and the net80211 tx downcall. While the former should be rcu protected we cannot rely on that. It remains questionable if we need to protect further fields there (with a different lock?). Also introduce a txq_mtx on the lhw which needs to be further deployed but we need to come up with a good strategy to not end up with 7 different locks. Sponsored by: The FreeBSD Foundation PR: 274178, 275710 Tested by: cc (cherry picked from commit eac3646fcdd445297cade756630335e23e92ea13) --- sys/compat/linuxkpi/common/include/net/mac80211.h | 27 +++++---- sys/compat/linuxkpi/common/src/linux_80211.c | 67 +++++++++++++++++++++-- sys/compat/linuxkpi/common/src/linux_80211.h | 29 +++++++++- 3 files changed, 107 insertions(+), 16 deletions(-) diff --git a/sys/compat/linuxkpi/common/include/net/mac80211.h b/sys/compat/linuxkpi/common/include/net/mac80211.h index fa36bd84ac6e..c4d001b3a7e8 100644 --- a/sys/compat/linuxkpi/common/include/net/mac80211.h +++ b/sys/compat/linuxkpi/common/include/net/mac80211.h @@ -1117,6 +1117,8 @@ void linuxkpi_ieee80211_txq_schedule_start(struct ieee80211_hw *, uint8_t); struct ieee80211_txq *linuxkpi_ieee80211_next_txq(struct ieee80211_hw *, uint8_t); void linuxkpi_ieee80211_schedule_txq(struct ieee80211_hw *, struct ieee80211_txq *, bool); +void linuxkpi_ieee80211_handle_wake_tx_queue(struct ieee80211_hw *, + struct ieee80211_txq *); /* -------------------------------------------------------------------------- */ @@ -1681,7 +1683,7 @@ static inline void ieee80211_return_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq, bool withoutpkts) { - linuxkpi_ieee80211_schedule_txq(hw, txq, true); + linuxkpi_ieee80211_schedule_txq(hw, txq, withoutpkts); } static inline void @@ -1706,7 +1708,7 @@ static inline void ieee80211_handle_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *txq) { - TODO(); + linuxkpi_ieee80211_handle_wake_tx_queue(hw, txq); } /* -------------------------------------------------------------------------- */ @@ -2197,13 +2199,25 @@ ieee80211_tkip_add_iv(u8 *crypto_hdr, struct ieee80211_key_conf *keyconf, TODO(); } -static __inline struct sk_buff * +static inline struct sk_buff * ieee80211_tx_dequeue(struct ieee80211_hw *hw, struct ieee80211_txq *txq) { return (linuxkpi_ieee80211_tx_dequeue(hw, txq)); } +static inline struct sk_buff * +ieee80211_tx_dequeue_ni(struct ieee80211_hw *hw, struct ieee80211_txq *txq) +{ + struct sk_buff *skb; + + local_bh_disable(); + skb = linuxkpi_ieee80211_tx_dequeue(hw, txq); + local_bh_enable(); + + return (skb); +} + static __inline void ieee80211_update_mu_groups(struct ieee80211_vif *vif, u_int _i, uint8_t *ms, uint8_t *up) @@ -2456,13 +2470,6 @@ ieee80211_stop_rx_ba_session_offl(struct ieee80211_vif *vif, uint8_t *addr, TODO(); } -static __inline struct sk_buff * -ieee80211_tx_dequeue_ni(struct ieee80211_hw *hw, struct ieee80211_txq *txq) -{ - TODO(); - return (NULL); -} - static __inline void ieee80211_tx_rate_update(struct ieee80211_hw *hw, struct ieee80211_sta *sta, struct ieee80211_tx_info *info) diff --git a/sys/compat/linuxkpi/common/src/linux_80211.c b/sys/compat/linuxkpi/common/src/linux_80211.c index d5eaddc0a520..0c547429a529 100644 --- a/sys/compat/linuxkpi/common/src/linux_80211.c +++ b/sys/compat/linuxkpi/common/src/linux_80211.c @@ -330,6 +330,7 @@ lkpi_lsta_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN], ltxq->txq.sta = sta; TAILQ_ELEM_INIT(ltxq, txq_entry); skb_queue_head_init(<xq->skbq); + LKPI_80211_LTXQ_LOCK_INIT(ltxq); sta->txq[tid] = <xq->txq; } @@ -381,8 +382,13 @@ lkpi_lsta_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN], return (lsta); cleanup: - for (; tid >= 0; tid--) + for (; tid >= 0; tid--) { + struct lkpi_txq *ltxq; + + ltxq = TXQ_TO_LTXQ(sta->txq[tid]); + LKPI_80211_LTXQ_LOCK_DESTROY(ltxq); free(sta->txq[tid], M_LKPI80211); + } free(lsta, M_LKPI80211); return (NULL); } @@ -976,6 +982,7 @@ lkpi_wake_tx_queues(struct ieee80211_hw *hw, struct ieee80211_sta *sta, { struct lkpi_txq *ltxq; int tid; + bool ltxq_empty; /* Wake up all queues to know they are allocated in the driver. */ for (tid = 0; tid < nitems(sta->txq); tid++) { @@ -994,7 +1001,10 @@ lkpi_wake_tx_queues(struct ieee80211_hw *hw, struct ieee80211_sta *sta, if (dequeue_seen && !ltxq->seen_dequeue) continue; - if (no_emptyq && skb_queue_empty(<xq->skbq)) + LKPI_80211_LTXQ_LOCK(ltxq); + ltxq_empty = skb_queue_empty(<xq->skbq); + LKPI_80211_LTXQ_UNLOCK(ltxq); + if (no_emptyq && ltxq_empty) continue; lkpi_80211_mo_wake_tx_queue(hw, sta->txq[tid]); @@ -3541,6 +3551,7 @@ lkpi_80211_txq_tx_one(struct lkpi_sta *lsta, struct mbuf *m) KASSERT(ltxq != NULL, ("%s: lsta %p sta %p m %p skb %p " "ltxq %p != NULL\n", __func__, lsta, sta, m, skb, ltxq)); + LKPI_80211_LTXQ_LOCK(ltxq); skb_queue_tail(<xq->skbq, skb); #ifdef LINUXKPI_DEBUG_80211 if (linuxkpi_debug_80211 & D80211_TRACE_TX) @@ -3553,6 +3564,7 @@ lkpi_80211_txq_tx_one(struct lkpi_sta *lsta, struct mbuf *m) skb_queue_len(<xq->skbq), ltxq->txq.ac, ltxq->txq.tid, ac, skb->priority, skb->qmap); #endif + LKPI_80211_LTXQ_UNLOCK(ltxq); lkpi_80211_mo_wake_tx_queue(hw, <xq->txq); return; } @@ -4075,6 +4087,7 @@ linuxkpi_ieee80211_alloc_hw(size_t priv_len, const struct ieee80211_ops *ops) LKPI_80211_LHW_LOCK_INIT(lhw); LKPI_80211_LHW_SCAN_LOCK_INIT(lhw); + LKPI_80211_LHW_TXQ_LOCK_INIT(lhw); sx_init_flags(&lhw->lvif_sx, "lhw-lvif", SX_RECURSE | SX_DUPOK); TAILQ_INIT(&lhw->lvif_head); for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { @@ -4113,9 +4126,10 @@ linuxkpi_ieee80211_iffree(struct ieee80211_hw *hw) lhw->ic = NULL; /* Cleanup more of lhw here or in wiphy_free()? */ - sx_destroy(&lhw->lvif_sx); - LKPI_80211_LHW_LOCK_DESTROY(lhw); + LKPI_80211_LHW_TXQ_LOCK_DESTROY(lhw); LKPI_80211_LHW_SCAN_LOCK_DESTROY(lhw); + LKPI_80211_LHW_LOCK_DESTROY(lhw); + sx_destroy(&lhw->lvif_sx); IMPROVE(); } @@ -5018,7 +5032,11 @@ linuxkpi_ieee80211_tx_dequeue(struct ieee80211_hw *hw, goto stopped; } + IMPROVE("hw(TX_FRAG_LIST)"); + + LKPI_80211_LTXQ_LOCK(ltxq); skb = skb_dequeue(<xq->skbq); + LKPI_80211_LTXQ_UNLOCK(ltxq); stopped: return (skb); @@ -5035,10 +5053,12 @@ linuxkpi_ieee80211_txq_get_depth(struct ieee80211_txq *txq, ltxq = TXQ_TO_LTXQ(txq); fc = bc = 0; + LKPI_80211_LTXQ_LOCK(ltxq); skb_queue_walk(<xq->skbq, skb) { fc++; bc += skb->len; } + LKPI_80211_LTXQ_UNLOCK(ltxq); if (frame_cnt) *frame_cnt = fc; if (byte_cnt) @@ -5591,13 +5611,17 @@ void linuxkpi_ieee80211_schedule_txq(struct ieee80211_hw *hw, { struct lkpi_hw *lhw; struct lkpi_txq *ltxq; + bool ltxq_empty; ltxq = TXQ_TO_LTXQ(txq); IMPROVE_TXQ("LOCKING"); /* Only schedule if work to do or asked to anyway. */ - if (!withoutpkts && skb_queue_empty(<xq->skbq)) + LKPI_80211_LTXQ_LOCK(ltxq); + ltxq_empty = skb_queue_empty(<xq->skbq); + LKPI_80211_LTXQ_UNLOCK(ltxq); + if (!withoutpkts && ltxq_empty) goto out; /* Make sure we do not double-schedule. */ @@ -5610,6 +5634,39 @@ out: return; } +void +linuxkpi_ieee80211_handle_wake_tx_queue(struct ieee80211_hw *hw, + struct ieee80211_txq *txq) +{ + struct lkpi_hw *lhw; + struct ieee80211_txq *ntxq; + struct ieee80211_tx_control control; + struct sk_buff *skb; + + lhw = HW_TO_LHW(hw); + + LKPI_80211_LHW_TXQ_LOCK(lhw); + ieee80211_txq_schedule_start(hw, txq->ac); + do { + ntxq = ieee80211_next_txq(hw, txq->ac); + if (ntxq == NULL) + break; + + memset(&control, 0, sizeof(control)); + control.sta = ntxq->sta; + do { + skb = linuxkpi_ieee80211_tx_dequeue(hw, ntxq); + if (skb == NULL) + break; + lkpi_80211_mo_tx(hw, &control, skb); + } while(1); + + ieee80211_return_txq(hw, ntxq, false); + } while (1); + ieee80211_txq_schedule_end(hw, txq->ac); + LKPI_80211_LHW_TXQ_UNLOCK(lhw); +} + /* -------------------------------------------------------------------------- */ struct lkpi_cfg80211_bss { diff --git a/sys/compat/linuxkpi/common/src/linux_80211.h b/sys/compat/linuxkpi/common/src/linux_80211.h index ef1f841e4f22..c9ac19321ab3 100644 --- a/sys/compat/linuxkpi/common/src/linux_80211.h +++ b/sys/compat/linuxkpi/common/src/linux_80211.h @@ -109,6 +109,7 @@ struct lkpi_radiotap_rx_hdr { struct lkpi_txq { TAILQ_ENTRY(lkpi_txq) txq_entry; + struct mtx ltxq_mtx; bool seen_dequeue; bool stopped; uint32_t txq_generation; @@ -184,6 +185,7 @@ struct lkpi_hw { /* name it mac80211_sc? */ struct sx sx; + struct mtx txq_mtx; uint32_t txq_generation[IEEE80211_NUM_ACS]; TAILQ_HEAD(, lkpi_txq) scheduled_txqs[IEEE80211_NUM_ACS]; @@ -279,13 +281,26 @@ struct lkpi_wiphy { mtx_destroy(&(_lhw)->scan_mtx); #define LKPI_80211_LHW_SCAN_LOCK(_lhw) \ mtx_lock(&(_lhw)->scan_mtx) -#define LKPI_80211_LHW_SCAN_UNLOCK(_lhw) \ +#define LKPI_80211_LHW_SCAN_UNLOCK(_lhw) \ mtx_unlock(&(_lhw)->scan_mtx) #define LKPI_80211_LHW_SCAN_LOCK_ASSERT(_lhw) \ mtx_assert(&(_lhw)->scan_mtx, MA_OWNED) #define LKPI_80211_LHW_SCAN_UNLOCK_ASSERT(_lhw) \ mtx_assert(&(_lhw)->scan_mtx, MA_NOTOWNED) +#define LKPI_80211_LHW_TXQ_LOCK_INIT(_lhw) \ + mtx_init(&(_lhw)->txq_mtx, "lhw-txq", NULL, MTX_DEF | MTX_RECURSE); +#define LKPI_80211_LHW_TXQ_LOCK_DESTROY(_lhw) \ + mtx_destroy(&(_lhw)->txq_mtx); +#define LKPI_80211_LHW_TXQ_LOCK(_lhw) \ + mtx_lock(&(_lhw)->txq_mtx) +#define LKPI_80211_LHW_TXQ_UNLOCK(_lhw) \ + mtx_unlock(&(_lhw)->txq_mtx) +#define LKPI_80211_LHW_TXQ_LOCK_ASSERT(_lhw) \ + mtx_assert(&(_lhw)->txq_mtx, MA_OWNED) +#define LKPI_80211_LHW_TXQ_UNLOCK_ASSERT(_lhw) \ + mtx_assert(&(_lhw)->txq_mtx, MA_NOTOWNED) + #define LKPI_80211_LHW_LVIF_LOCK(_lhw) sx_xlock(&(_lhw)->lvif_sx) #define LKPI_80211_LHW_LVIF_UNLOCK(_lhw) sx_xunlock(&(_lhw)->lvif_sx) @@ -295,6 +310,18 @@ struct lkpi_wiphy { #define LKPI_80211_LSTA_LOCK(_lsta) mtx_lock(&(_lsta)->txq_mtx) #define LKPI_80211_LSTA_UNLOCK(_lsta) mtx_unlock(&(_lsta)->txq_mtx) +#define LKPI_80211_LTXQ_LOCK_INIT(_ltxq) \ + mtx_init(&(_ltxq)->ltxq_mtx, "ltxq", NULL, MTX_DEF); +#define LKPI_80211_LTXQ_LOCK_DESTROY(_ltxq) \ + mtx_destroy(&(_ltxq)->ltxq_mtx); +#define LKPI_80211_LTXQ_LOCK(_ltxq) \ + mtx_lock(&(_ltxq)->ltxq_mtx) +#define LKPI_80211_LTXQ_UNLOCK(_ltxq) \ + mtx_unlock(&(_ltxq)->ltxq_mtx) +#define LKPI_80211_LTXQ_LOCK_ASSERT(_ltxq) \ + mtx_assert(&(_ltxq)->ltxq_mtx, MA_OWNED) +#define LKPI_80211_LTXQ_UNLOCK_ASSERT(_ltxq) \ + mtx_assert(&(_ltxq)->ltxq_mtx, MA_NOTOWNED) int lkpi_80211_mo_start(struct ieee80211_hw *); void lkpi_80211_mo_stop(struct ieee80211_hw *);