From nobody Fri Oct 09 10:12:34 2026 X-Original-To: dev-commits-src-main@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 4j1N2q0v5xz6vQst for ; Fri, 09 Oct 2026 10:12:35 +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 "YR2" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4j1N2p6HtSz4Xb7 for ; Fri, 09 Oct 2026 10:12:34 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1791540754; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=+NdSx6jdQuQg/Qt4H/PShB5sdx+V3nrbWMmX1bMn3ak=; b=AQQC6UYfVUWoXYYJe2KnuHFcc48KiJhWd9VI+EP6EG7uW80XVBrOZ2uKo/9M2BqhQDkoX9 26CvIh5+xbCkfWOnwPX9sXOdx6pvd3bNVRl4BFgkVS0PMvC77+/CwghULlSH6J3Rl+TTxO MbqbN8SFdxuYSOD3RKDWsgZHrTpj920Eum2xK2rIeAJYm61vHwuFRW3pNdjkGIWhnT1e0X OhNvLQY5bxL1/hi3VTgXv67+I9wErWbF29de3UvXNwK23PsYi3D3SBH0AGRkxZUL0ky/J3 pxq1ddf32eO4j/8eA/qAH5LWpv/9Qlj/8fey5sS6AeGZhhzNyfpNteBzU8IjYg== ARC-Seal: i=1; a=rsa-sha256; d=freebsd.org; s=dkim; cv=none; t=1791540754; b=KBVEXDKP4PxFpCIa4cE+VdjBMzNu+bMUCYKHqJJVTvrfL4xYal0eIkl3R76S0vN5QxWdV7 qKfmNaGgBJx8eUpLysgIxBJYgPBcaLZRzFCs8cl1b/HUvo5qpW8NfkM1vfE1U4XElkccTt uKJNcn7sc1sxZGsrXCy5tmcPL+JO+pQUHRrBBer1M5nUTcSFRQbMkXuRHrWyyq/L1Qvflh ESASFPJb9++KDKbLaxPfzVQUF+aZ7bZwR7/fc++NfGHZETAmS3x1TOA2GdlTcb5TPm+7+T uppVgSERpEM4QZipU0yqNX7iU+/EqpGt4tk59qGwkW8jGgupugquAkficUbwkw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1791540754; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=+NdSx6jdQuQg/Qt4H/PShB5sdx+V3nrbWMmX1bMn3ak=; b=Lmwguteq97/0S/gahkHSN6UxhVDLiatICdKVj/cHCDTHRZG2xnamR5KTBbfr11r5xDKyFx H8v+5ExXW8fItMdsE5iuJt7s8IYfN3cfbwEmWDwBza84ULNjhJJbn6eGttXoH+ixfPOMfD FycrxGHmqSNC1fAgpge4h4pnxsNoFQkvUkOVDeLcHimK8hD0jKmAeJc2snAL9Mv0c8+/ZA YWMves0CdACeejzicFiYjW7DvXLZEuVpnu/j3cTC+3yDn6PrhsXhnOkQQ4tA6RoAaBRo4V P8j7WTjDAHR5cWP/cIuhbxtu7wTW6nplVkiBPp7Z0gfekAkyi54t6/mJc06hmg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4j1N2p5Gw1z1L3r for ; Fri, 09 Oct 2026 10:12:34 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 40dd5 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Fri, 09 Oct 2026 10:12:34 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Cc: Sumit Saxena From: Sumit Saxena Subject: git: 3c995919dc4a - main - if_bnxt: add host-based TX completion coalescing List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: ssaxena X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 3c995919dc4a7f5de35534b3220f972bf0153fb9 Auto-Submitted: auto-generated Date: Fri, 09 Oct 2026 10:12:34 +0000 Message-Id: <6ac8be12.40dd5.48e7a806@gitrepo.freebsd.org> The branch main has been updated by ssaxena: URL: https://cgit.FreeBSD.org/src/commit/?id=3c995919dc4a7f5de35534b3220f972bf0153fb9 commit 3c995919dc4a7f5de35534b3220f972bf0153fb9 Author: Sumit Saxena AuthorDate: 2026-08-03 09:07:36 +0000 Commit: Sumit Saxena CommitDate: 2026-10-09 08:24:42 +0000 if_bnxt: add host-based TX completion coalescing Suppress per-BD completions (TX_BD_LONG_FLAGS_NO_CMPL/_COAL_NOW) and accumulate a running_bds count per ring, forcing a real completion when iflib requests one or when the count nears overflowing the opaque bd-count field. Replaces the previous raw (bd_count << 24 | idx) TX completion opaque encoding, which only had 8 bits for the count and would overflow well within these coalescing thresholds, with a tx_bd_opaque bitfield (16-bit idx + 15-bit bds + 1-bit ktls_replay for later use). Add tx_host_coal_bds/tx_host_coal_enable sysctls to tune and toggle it. Reviewed by: gallatin MFC after: 2 weeks Sponsored by: Broadcom Inc. Differential Revision: https://reviews.freebsd.org/D58600 --- sys/dev/bnxt/bnxt_en/bnxt.h | 22 +++++++++++++++++++ sys/dev/bnxt/bnxt_en/bnxt_sysctl.c | 44 ++++++++++++++++++++++++++++++++++++++ sys/dev/bnxt/bnxt_en/bnxt_txrx.c | 32 +++++++++++++++++++++++++-- sys/dev/bnxt/bnxt_en/if_bnxt.c | 7 ++++++ 4 files changed, 103 insertions(+), 2 deletions(-) diff --git a/sys/dev/bnxt/bnxt_en/bnxt.h b/sys/dev/bnxt/bnxt_en/bnxt.h index ac91661eda7f..80cc8905d66b 100644 --- a/sys/dev/bnxt/bnxt_en/bnxt.h +++ b/sys/dev/bnxt/bnxt_en/bnxt.h @@ -600,6 +600,14 @@ struct bnxt_grp_info { #define EPOCH_ARR_SZ 4096 +struct tx_bd_opaque { + uint16_t idx; + uint16_t bds:15, + ktls_replay:1; +} __packed; + +#define TX_RING_MASK(txr) ((txr)->ring_size - 1) + struct bnxt_ring { uint64_t paddr; vm_offset_t doorbell; @@ -609,6 +617,7 @@ struct bnxt_ring { uint16_t id; /* Logical ID */ uint16_t phys_id; uint16_t idx; + uint16_t running_bds; /* host TX-completion-coalescing accumulator */ struct bnxt_full_tpa_start *tpa_start; union { u64 db_key64; @@ -1433,6 +1442,19 @@ struct bnxt_softc { #define BNXT_CAGR_TICK_RES_MAX 0x4 #define BNXT_CAGR_TICK_RES_OFFSET 16 uint32_t cagr_tick_res; + + /* Matches this branch's scctx->isc_tx_nsegments; cached for the + * tx_host_coal_bds underflow guard below. */ +#define BNXT_MAX_NUM_SEGS 31 + uint32_t tx_ring_size; /* cached scctx->isc_ntxd[1] */ + /* + * Host-based TX coalescing: driver suppresses per-BD completions by + * setting TX_BD_LONG_FLAGS_NO_CMPL / TX_BD_LONG_FLAGS_COAL_NOW on BDs. + */ +#define BNXT_TX_HOST_COAL_BDS_MIN 33 /* must be > BNXT_MAX_NUM_SEGS+1 to avoid uint underflow */ +#define BNXT_TX_HOST_COAL_BDS_DEFAULT 256 /* cap for large rings; halved for small rings */ + uint32_t tx_host_coal_bds; /* max BDs before forcing completion */ + bool tx_host_coal_enable; /* enable host-driven TX coalescing */ /* Firmware coalesces completions autonomously based on cmpl_coal_cnt * (only valid when BNXT_FLAG_TX_COAL_CMPL is set); raw codes map to * counts 4,8,12,16,24,32,48,64,96,128,192,256,320,384,MAX. */ diff --git a/sys/dev/bnxt/bnxt_en/bnxt_sysctl.c b/sys/dev/bnxt/bnxt_en/bnxt_sysctl.c index 729d0aa1f5c7..cfe57cf25c2c 100644 --- a/sys/dev/bnxt/bnxt_en/bnxt_sysctl.c +++ b/sys/dev/bnxt/bnxt_en/bnxt_sysctl.c @@ -1580,6 +1580,30 @@ bnxt_set_cagr_tick_res(SYSCTL_HANDLER_ARGS) { return rc; } +static int +bnxt_set_tx_host_coal_bds(SYSCTL_HANDLER_ARGS) +{ + struct bnxt_softc *softc = arg1; + uint32_t val; + int rc; + + if (softc == NULL) + return EBUSY; + + val = softc->tx_host_coal_bds; + + rc = sysctl_handle_int(oidp, (int *)&val, 0, req); + if (rc || !req->newptr) + return rc; + + if (val < BNXT_TX_HOST_COAL_BDS_MIN || val > softc->tx_ring_size) + return EINVAL; + + softc->tx_host_coal_bds = val; + + return 0; +} + static int bnxt_set_tx_hw_coal_cnt(SYSCTL_HANDLER_ARGS) { @@ -1700,7 +1724,27 @@ bnxt_create_config_sysctls_pre(struct bnxt_softc *softc) CTLTYPE_INT | CTLFLAG_RDTUN | CTLFLAG_MPSAFE, softc, 0, bnxt_set_cagr_tick_res, "I", "CAGR tick resolution"); + /* + * Default coal_bds to half the Tx ring depth, clamped between + * BNXT_TX_HOST_COAL_BDS_MIN and DEFAULT; disable below the floor to + * avoid uint underflow in (coal_bds - (BNXT_MAX_NUM_SEGS+1)). + */ + softc->tx_host_coal_bds = min(softc->tx_ring_size, + max(BNXT_TX_HOST_COAL_BDS_MIN, + min(BNXT_TX_HOST_COAL_BDS_DEFAULT, softc->tx_ring_size / 2))); + softc->tx_host_coal_enable = + (softc->tx_ring_size >= BNXT_TX_HOST_COAL_BDS_MIN); softc->tx_hw_coal_cnt = BNXT_TX_HW_COAL_CNT_DEFAULT; + SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "tx_host_coal_bds", + CTLTYPE_INT | CTLFLAG_RDTUN | CTLFLAG_MPSAFE, softc, 0, + bnxt_set_tx_host_coal_bds, "I", + "host-driven TX coalescing: max BDs before forcing completion " + "(33 to Tx ring size, default max(33, min(256, ring_size/2)) " + "clamped to ring_size; feature auto-disabled if ring_size < 33)"); + SYSCTL_ADD_BOOL(ctx, children, OID_AUTO, "tx_host_coal_enable", CTLFLAG_RDTUN, + &softc->tx_host_coal_enable, 0, + "enable host-driven TX coalescing via NO_CMPL/COAL_NOW BD flags " + "(default enabled)"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "tx_hw_coal_cnt", CTLTYPE_INT | CTLFLAG_RDTUN | CTLFLAG_MPSAFE, softc, 0, bnxt_set_tx_hw_coal_cnt, "I", diff --git a/sys/dev/bnxt/bnxt_en/bnxt_txrx.c b/sys/dev/bnxt/bnxt_en/bnxt_txrx.c index 40b02744c6c1..430913c61547 100644 --- a/sys/dev/bnxt/bnxt_en/bnxt_txrx.c +++ b/sys/dev/bnxt/bnxt_en/bnxt_txrx.c @@ -94,12 +94,24 @@ bnxt_isc_txd_encap(void *sc, if_pkt_info_t pi) struct bnxt_ring *txr = &softc->tx_rings[pi->ipi_qsidx]; struct tx_bd_long *tbd; struct tx_bd_long_hi *tbdh; + bool need_cpl = false; bool need_hi = false; uint16_t flags_type; uint16_t lflags; uint32_t cfa_meta; int seg = 0; uint8_t wrap = 0; + struct tx_bd_opaque *opq; + + if ((pi->ipi_flags & IPI_TX_INTR) != 0) + need_cpl = true; + + if (softc->tx_host_coal_enable) { + /* BD field of opaque is only 15 bits; respect tx_host_coal_bds threshold */ + if (txr->running_bds > + (softc->tx_host_coal_bds - (BNXT_MAX_NUM_SEGS + 1))) + need_cpl = true; + } /* If we have offloads enabled, we need to use two BDs. */ if ((pi->ipi_csum_flags & (CSUM_OFFLOAD | CSUM_TSO | CSUM_IP)) || @@ -112,12 +124,26 @@ bnxt_isc_txd_encap(void *sc, if_pkt_info_t pi) pi->ipi_new_pidx = pi->ipi_pidx; tbd = &((struct tx_bd_long *)txr->vaddr)[pi->ipi_new_pidx]; pi->ipi_ndescs = 0; + opq = (struct tx_bd_opaque *)&tbd->opaque; /* No need to byte-swap the opaque value */ - tbd->opaque = ((pi->ipi_nsegs + need_hi) << 24) | pi->ipi_new_pidx; + opq->ktls_replay = 0; + opq->idx = pi->ipi_new_pidx & TX_RING_MASK(txr); + opq->bds = txr->running_bds + pi->ipi_nsegs + need_hi; tbd->len = htole16(pi->ipi_segs[seg].ds_len); tbd->addr = htole64(pi->ipi_segs[seg++].ds_addr); flags_type = ((pi->ipi_nsegs + need_hi) << TX_BD_SHORT_FLAGS_BD_CNT_SFT) & TX_BD_SHORT_FLAGS_BD_CNT_MASK; + + if (softc->tx_host_coal_enable) { + flags_type |= TX_BD_LONG_FLAGS_COAL_NOW; + if (need_cpl) + txr->running_bds = 0; + else { + txr->running_bds += (pi->ipi_nsegs + 1); + flags_type |= TX_BD_LONG_FLAGS_NO_CMPL; + } + } + if (pi->ipi_len >= 2048) flags_type |= TX_BD_SHORT_FLAGS_LHINT_GTE2K; else @@ -235,6 +261,7 @@ bnxt_isc_txd_credits_update(void *sc, uint16_t txqid, bool clear) uint32_t last_raw_cons; uint16_t type; uint16_t err; + struct tx_bd_opaque *opq; for (;;) { last_cons = cons; @@ -258,7 +285,8 @@ bnxt_isc_txd_credits_update(void *sc, uint16_t txqid, bool clear) device_printf(softc->dev, "TX completion error %u\n", err); /* No need to byte-swap the opaque value */ - avail += cmpl[cons].opaque >> 24; + opq = (struct tx_bd_opaque *)&cmpl[cons].opaque; + avail += opq->bds; /* * If we're not clearing, iflib only cares if there's * at least one buffer. Don't scan the whole ring in diff --git a/sys/dev/bnxt/bnxt_en/if_bnxt.c b/sys/dev/bnxt/bnxt_en/if_bnxt.c index 512afb450494..098fb0685dd3 100644 --- a/sys/dev/bnxt/bnxt_en/if_bnxt.c +++ b/sys/dev/bnxt/bnxt_en/if_bnxt.c @@ -2913,6 +2913,13 @@ bnxt_attach_pre(if_ctx_t ctx) HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV6 | HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6; + /* + * Cache the Tx BD ring size so sysctl validators (e.g. + * tx_host_coal_bds) can compare against it before per-queue + * tx_rings[i].ring_size has been populated. + */ + softc->tx_ring_size = scctx->isc_ntxd[1]; + if (BNXT_CHIP_P7(softc)) softc->cagr_tick_res = BNXT_CAGR_TICK_RES_DEFAULT;