[PATCH net-next 4/5] net/mlx4: track whether a TX doorbell is pending

From: Joe Damato

Date: Tue Nov 10 2026 - 18:14:21 EST


When the stack sets xmit_more, mlx4_en_xmit() skips the doorbell and
relies on a later call in the same batch to write it. Nothing records
that a doorbell is owed, so a path that ends the batch without writing
the doorbell leaves the WQEs posted before it unannounced to HW.

Add ring->doorbell_pending, set when the doorbell is deferred and
cleared whenever a doorbell or a BlueFlame write is issued, so such a
path can flush the deferred doorbell.

Signed-off-by: Joe Damato <joe@xxxxxxx>
---
drivers/net/ethernet/mellanox/mlx4/en_tx.c | 9 +++++++--
drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 1 +
2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c
index 97f27e005810..123071a47bed 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c
@@ -194,6 +194,7 @@ int mlx4_en_activate_tx_ring(struct mlx4_en_priv *priv,
ring->prod = 0;
ring->cons = 0xffffffff;
ring->last_nr_txbb = 1;
+ ring->doorbell_pending = false;
memset(ring->tx_info, 0, ring->size * sizeof(struct mlx4_en_tx_info));
memset(ring->buf, 0, ring->buf_size);
ring->free_tx_desc = mlx4_en_free_tx_desc;
@@ -757,6 +758,7 @@ void mlx4_en_xmit_doorbell(struct mlx4_en_tx_ring *ring)
iowrite32be(
#endif
(__force u32)ring->doorbell_qpn, ring->doorbell_address);
+ ring->doorbell_pending = false;
}

static void mlx4_en_tx_write_desc(struct mlx4_en_tx_ring *ring,
@@ -784,16 +786,19 @@ static void mlx4_en_tx_write_desc(struct mlx4_en_tx_ring *ring,
wmb();

ring->bf.offset ^= ring->bf.buf_size;
+ ring->doorbell_pending = false;
} else {
/* Ensure new descriptor hits memory
* before setting ownership of this descriptor to HW
*/
dma_wmb();
tx_desc->ctrl.owner_opcode = op_own;
- if (send_doorbell)
+ if (send_doorbell) {
mlx4_en_xmit_doorbell(ring);
- else
+ } else {
ring->xmit_more++;
+ ring->doorbell_pending = true;
+ }
}
}

diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
index aab97694f86b..601c09020f38 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
@@ -281,6 +281,7 @@ struct mlx4_en_tx_ring {
unsigned long tso_packets;
unsigned long xmit_more;
struct mlx4_bf bf;
+ bool doorbell_pending;

/* Following part should be mostly read */
void __iomem *doorbell_address;
--
2.53.0-Meta