From: Shivesh <chanelshivesh@gmail.com>
To: arend.vanspriel@broadcom.com
Cc: linux-wireless@vger.kernel.org, brcm80211@lists.linux.dev,
brcm80211-dev-list.pdl@broadcom.com,
linux-kernel@vger.kernel.org, Shivesh <chanelshivesh@gmail.com>
Subject: [PATCH v2 5/8] wifi: brcmfmac: msgbuf: tune thresholds and optimize sleep latency
Date: Thu, 30 Jul 2026 16:21:08 +0000 [thread overview]
Message-ID: <20260730162135.12278-5-shivesh@example.com> (raw)
In-Reply-To: <20260730162135.12278-1-shivesh@example.com>
From: Shivesh <chanelshivesh@gmail.com>
Increases tx pktids and tune flush thresholds. Fixes a silent tx stall
under high load by correctly using test_and_set_bit. Optimizes
initialization polling latency from msleep(10) to usleep_range.
Signed-off-by: Shivesh <chanelshivesh@gmail.com>
---
.../broadcom/brcm80211/brcmfmac/msgbuf.c | 69 ++++++++++++++++---
1 file changed, 61 insertions(+), 8 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
index ba1ce1552e0f..8db6167072da 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
@@ -48,7 +48,19 @@
#define MSGBUF_TYPE_LPBK_DMAXFER 0x13
#define MSGBUF_TYPE_LPBK_DMAXFER_CMPLT 0x14
-#define NR_TX_PKTIDS 2048
+/*
+ * NR_TX_PKTIDS: number of simultaneously in-flight TX packet IDs.
+ * Each outstanding TX frame consumes one ID until the dongle returns
+ * a TX-status completion. The original 2048-entry pool exhausted under
+ * ≥4 concurrent iperf3 streams on Wi-Fi 5/6 (802.11ac/ax) devices,
+ * causing "No PKTID available" drops and TCP retransmits. 4096 gives
+ * headroom for high-aggregation scenarios while still fitting in a
+ * modest amount of host memory (~48 KB for the pktid table entries).
+ *
+ * NR_RX_PKTIDS: RX post buffers pre-allocated to the dongle. 1024 is
+ * sufficient for current hardware RX ring depths; leave unchanged.
+ */
+#define NR_TX_PKTIDS 4096
#define NR_RX_PKTIDS 1024
#define BRCMF_IOCTL_REQ_PKTID 0xFFFE
@@ -64,8 +76,29 @@
#define BRCMF_MSGBUF_PKT_FLAGS_FRAME_MASK 0x07
#define BRCMF_MSGBUF_PKT_FLAGS_PRIO_SHIFT 5
-#define BRCMF_MSGBUF_TX_FLUSH_CNT1 32
-#define BRCMF_MSGBUF_TX_FLUSH_CNT2 96
+/*
+ * TX flush / doorbell-ring thresholds.
+ *
+ * CNT1 is the minimum number of frames to accumulate in the commonring
+ * before the first intermediate write_complete() (doorbell ring) is
+ * issued mid-batch. CNT2 is the hard flush interval: after this many
+ * frames have been written since the last flush, we unconditionally
+ * ring the bell and reset the counter.
+ *
+ * Raising both from the original 32/96 to 64/128 doubles the average
+ * number of TX descriptors committed per MMIO write, halving the PCIe
+ * doorbell rate on sustained throughput workloads. The tradeoff is a
+ * marginally higher worst-case latency for the last frames in a burst,
+ * which in practice is hidden by the time the dongle DMA engine drains
+ * the previous batch.
+ *
+ * TRICKLE_TXWORKER_THRS governs how often brcmf_msgbuf_tx_queue_data()
+ * forces a workqueue schedule when the queue depth is not a multiple of
+ * this value. Keeping it at half of CNT1 (32) preserves responsiveness
+ * for low-rate flows (e.g. VoIP, ICMP) that never accumulate 64 frames.
+ */
+#define BRCMF_MSGBUF_TX_FLUSH_CNT1 64
+#define BRCMF_MSGBUF_TX_FLUSH_CNT2 128
#define BRCMF_MSGBUF_DELAY_TXWORKER_THRS 96
#define BRCMF_MSGBUF_TRICKLE_TXWORKER_THRS 32
@@ -787,10 +820,30 @@ static int brcmf_msgbuf_schedule_txdata(struct brcmf_msgbuf *msgbuf, u32 flowid,
{
struct brcmf_commonring *commonring;
- set_bit(flowid, msgbuf->flow_map);
+ /*
+ * If the bit was already set, a txflow_work item is already
+ * queued or running for this ring. In that case the existing
+ * worker will drain our freshly enqueued frame when it runs,
+ * so we only need to schedule another work item when the
+ * force flag is set or the ring is below the delay threshold.
+ *
+ * If the bit was NOT set (test_and_set_bit returns false), no
+ * worker is pending for this ring at all. We MUST schedule
+ * one unconditionally, otherwise the frame we just enqueued
+ * will sit in the flowring unsent until some unrelated event
+ * triggers the workqueue — causing silent TX stalls under
+ * high load when outstanding_tx >= DELAY_TXWORKER_THRS.
+ */
+ if (!test_and_set_bit(flowid, msgbuf->flow_map)) {
+ /* Bit was clear: no worker pending, always schedule. */
+ queue_work(msgbuf->txflow_wq, &msgbuf->txflow_work);
+ return 0;
+ }
+
+ /* Bit was already set: worker pending, apply coalescing heuristic. */
commonring = msgbuf->flowrings[flowid];
- if ((force) || (atomic_read(&commonring->outstanding_tx) <
- BRCMF_MSGBUF_DELAY_TXWORKER_THRS))
+ if (force || (atomic_read(&commonring->outstanding_tx) <
+ BRCMF_MSGBUF_DELAY_TXWORKER_THRS))
queue_work(msgbuf->txflow_wq, &msgbuf->txflow_work);
return 0;
@@ -1621,11 +1674,11 @@ int brcmf_proto_msgbuf_attach(struct brcmf_pub *drvr)
do {
brcmf_msgbuf_rxbuf_data_fill(msgbuf);
if (msgbuf->max_rxbufpost != msgbuf->rxbufpost)
- msleep(10);
+ usleep_range(1000, 2000);
else
break;
count++;
- } while (count < 10);
+ } while (count < 100);
brcmf_msgbuf_rxbuf_event_post(msgbuf);
brcmf_msgbuf_rxbuf_ioctlresp_post(msgbuf);
--
2.53.0
next prev parent reply other threads:[~2026-07-30 16:21 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-30 16:21 [PATCH v2 1/8] wifi: brcmfmac: flowring: replace O(N) loop with atomic counter Shivesh
2026-07-30 16:21 ` [PATCH v2 2/8] wifi: brcmfmac: sdio: coalesce host locks in rx path Shivesh
2026-07-30 16:21 ` [PATCH v2 3/8] wifi: brcmfmac: core: populate radiotap header with RSSI Shivesh
2026-07-30 16:21 ` [PATCH v2 4/8] wifi: brcmfmac: cfg80211: implement PMKID_V2 and fix delay busy-wait Shivesh
2026-07-30 16:21 ` Shivesh [this message]
2026-07-30 16:21 ` [PATCH v2 6/8] wifi: brcmfmac: pcie: optimize latency and irq teardown Shivesh
2026-07-30 16:21 ` [PATCH v2 7/8] wifi: brcmfmac: fwsignal: safe no-op on duplicate MAC add Shivesh
2026-07-30 16:21 ` [PATCH v2 8/8] wifi: brcmsmac: ampdu: clarify standard compliance on QoS change Shivesh
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260730162135.12278-5-shivesh@example.com \
--to=chanelshivesh@gmail.com \
--cc=arend.vanspriel@broadcom.com \
--cc=brcm80211-dev-list.pdl@broadcom.com \
--cc=brcm80211@lists.linux.dev \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-wireless@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.