git: 4a0ec469934a - main - iflib: Do not ring the transmit doorbell when nothing is pending
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 05 Oct 2026 15:19:05 UTC
The branch main has been updated by rcm:
URL: https://cgit.FreeBSD.org/src/commit/?id=4a0ec469934a5de60b9b540689703a698ac44105
commit 4a0ec469934a5de60b9b540689703a698ac44105
Author: R. Christian McDonald <rcm@FreeBSD.org>
AuthorDate: 2026-10-05 15:17:13 +0000
Commit: R. Christian McDonald <rcm@FreeBSD.org>
CommitDate: 2026-10-05 15:19:01 +0000
iflib: Do not ring the transmit doorbell when nothing is pending
For a lightly used ring iflib_txd_db_check() may defer zero descriptors,
so its "pending >= limit" test is true even when nothing has been queued
since the last doorbell. iflib_txq_drain() calls it before, inside and
after its loop, so a sender that drains its own packet wrote the tail
register three times per packet, twice with the value the hardware
already had.
The log of 81be655266fa ("iflib: ensure that tx interrupts enabled and
cleanups") calls skipping the doorbell when db_pending is zero "an
obvious missing optimization"; the comparison against a limit of zero
defeated it. vmx(4) and mgb(4) have dropped such repeated requests in
the driver since 2019. Return early when nothing is pending.
Reviewed by: gallatin
MFC after: 2 weeks
Sponsored by: Rubicon Communications, LLC ("Netgate")
Differential Revision: https://reviews.freebsd.org/D60290
---
sys/net/iflib.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/sys/net/iflib.c b/sys/net/iflib.c
index c2e70d946bf6..834cc37cb6ab 100644
--- a/sys/net/iflib.c
+++ b/sys/net/iflib.c
@@ -3457,6 +3457,13 @@ iflib_txd_db_check(iflib_txq_t txq, int ring)
if_ctx_t ctx = txq->ift_ctx;
qidx_t dbval, max;
+ /*
+ * Nothing has been queued since the last doorbell. The threshold is
+ * zero for a lightly used ring, so the test below would not catch this.
+ */
+ if (txq->ift_db_pending == 0)
+ return (false);
+
max = TXQ_MAX_DB_DEFERRED(txq, txq->ift_in_use);
/* force || threshold exceeded || at the edge of the ring */