From nobody Mon Feb 19 16:10:17 2024 X-Original-To: dev-commits-src-all@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 4TdnZ21t4dz5C58V; Mon, 19 Feb 2024 16:10:18 +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 4TdnZ16cjWz4Nrc; Mon, 19 Feb 2024 16:10:17 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1708359017; 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=cmqXDiBVWyrEFnJp4rQVxZ9FLyuspSk/tjPoiMYb1aw=; b=f3jR1IgI3hhX63MV4Jm82uDuUkqw2PGV/t1smM6r0H2G4BibmB2cyCgytamnzaC2Hf/Gz4 ToFLwgH0gqUI4FFiZBAE6V9F+ikR/PjT71/kirlLr5NBICpgtEVUp+S9gFUUFgCIu6q5vw Tos5KrysPMCf8/ZZuhtHTz9lv0NnDHl2DJcyzqi6RF18wMFEiiTinFT/sLB9IGKR1O+I2q 3oxFdpJ49cDmvoJYtk3T4lzSQKNzaH2FEjYTNkMYYj0EXddebfgZi1M2WPGU7yvbs8X04s bo4oAybaHYW0qssAns9FZp/X3dPcgRNjAJ3beLcbV0DJdvc/CE3oNBG72ASlUg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1708359017; 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=cmqXDiBVWyrEFnJp4rQVxZ9FLyuspSk/tjPoiMYb1aw=; b=sj3ogJBGfINBPoBbt8G/P2Ck9QCpEx/L+Jg9EWuYRBMo/h1Ymm1/N1rtr+XGN5elDZBIq0 g+lvqqUPKIPo6bXjlB6t6x4q0FhEq9qF8OKXjs3Ia6a4jxRZDq1B2oHkIJOEG4dP6ojLiS u3QBMqTczlG9InQM+0SnDwpoKVqc6VCsgV/oCYCcTS4C6q9xUqLF+ZDdUYjHvfaq2nbRwj ExoKx0oz+yvXEF/SgrMywANwrov/aq9Sl5cJmRMUDRsUQSELKCbruYZ7H7RUKnFQ8WINIr m6H8Jdd64AVFFlqtc08qZz1KJm/sijmjd0xT4bfRPOhFYjKdZH4Xis+8GNLyjg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1708359017; a=rsa-sha256; cv=none; b=wRJ30p0s0kCOD/cbTWRrjCgOY2kyhI8jdsyUo6Je6OrYypJAvc5u5g0c4DbSpOPtb/4yDG Gwy3n8YQJECrWxc75GgjVjijLWNlOfaCXGeT5qLxs5S4D2wmxk1VUaG4v92WQ+zm8NuLaX lfNzqEClyoYawNdZbimXdAkM8/bcOXnSo1sULcsaSBEmVyI2jFngMSm1zeCfnzI/YVx0Lb Yzq5vZ+viXAo8hr5YMfN8+xRN2WudniPdOCW27CtPjedHuCDBSsPt5QYuHZ71fj+Gfwb3g FL8tEfgfqdVoVt6fUUKQbPYjL9OINYmgfDUGQCdNbgkGzJ+mq2ePM7Y4NzXp8g== 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 4TdnZ15k2Rzgdy; Mon, 19 Feb 2024 16:10:17 +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 41JGAHeM035524; Mon, 19 Feb 2024 16:10:17 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 41JGAHc4035511; Mon, 19 Feb 2024 16:10:17 GMT (envelope-from git) Date: Mon, 19 Feb 2024 16:10:17 GMT Message-Id: <202402191610.41JGAHc4035511@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: 804a4c1c7b8f - releng/13.3 - LinuxKPI: 802.11: more TXQ implementation and locking List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@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/releng/13.3 X-Git-Reftype: branch X-Git-Commit: 804a4c1c7b8fe00a6924fa5e4ae27a487bdc2337 Auto-Submitted: auto-generated The branch releng/13.3 has been updated by bz: URL: https://cgit.FreeBSD.org/src/commit/?id=804a4c1c7b8fe00a6924fa5e4ae27a487bdc2337 commit 804a4c1c7b8fe00a6924fa5e4ae27a487bdc2337 Author: Bjoern A. Zeeb AuthorDate: 2023-12-12 01:59:17 +0000 Commit: Bjoern A. Zeeb CommitDate: 2024-02-19 16:06:43 +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. Approved by: re (cperciva) Sponsored by: The FreeBSD Foundation PR: 274178, 275710 Tested by: cc (cherry picked from commit eac3646fcdd445297cade756630335e23e92ea13) (cherry picked from commit 3df959638baa60c1c88e9ac66289502f99ad8418) --- 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 7e6fb1bce16e..fee29d3b1a1d 100644 --- a/sys/compat/linuxkpi/common/include/net/mac80211.h +++ b/sys/compat/linuxkpi/common/include/net/mac80211.h @@ -1114,6 +1114,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 *); /* -------------------------------------------------------------------------- */ @@ -1678,7 +1680,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 @@ -1703,7 +1705,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); } /* -------------------------------------------------------------------------- */ @@ -2194,13 +2196,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) @@ -2453,13 +2467,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 340503307c97..3988c5260f66 100644 --- a/sys/compat/linuxkpi/common/src/linux_80211.c +++ b/sys/compat/linuxkpi/common/src/linux_80211.c @@ -249,6 +249,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; } @@ -286,8 +287,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); } @@ -881,6 +887,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++) { @@ -899,7 +906,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]); @@ -3395,6 +3405,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) @@ -3407,6 +3418,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; } @@ -3645,6 +3657,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++) { @@ -3683,9 +3696,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(); } @@ -4564,7 +4578,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); @@ -4581,10 +4599,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) @@ -5137,13 +5157,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. */ @@ -5156,6 +5180,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 74dc3c9f9dee..9100d1c2e73e 100644 --- a/sys/compat/linuxkpi/common/src/linux_80211.h +++ b/sys/compat/linuxkpi/common/src/linux_80211.h @@ -100,6 +100,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; @@ -175,6 +176,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]; @@ -247,13 +249,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) @@ -263,6 +278,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 *);