Skip to content

Commit

Permalink
mlxbf_gige: fix receive packet race condition
Browse files Browse the repository at this point in the history
[ Upstream commit dcea1bd ]

Under heavy traffic, the BlueField Gigabit interface can
become unresponsive. This is due to a possible race condition
in the mlxbf_gige_rx_packet function, where the function exits
with producer and consumer indices equal but there are remaining
packet(s) to be processed. In order to prevent this situation,
read receive consumer index *before* the HW replenish so that
the mlxbf_gige_rx_packet function returns an accurate return
value even if a packet is received into just-replenished buffer
prior to exiting this routine. If the just-replenished buffer
is received and occupies the last RX ring entry, the interface
would not recover and instead would encounter RX packet drops
related to internal buffer shortages since the driver RX logic
is not being triggered to drain the RX ring. This patch will
address and prevent this "ring full" condition.

Fixes: f92e186 ("Add Mellanox BlueField Gigabit Ethernet driver")
Reviewed-by: Asmaa Mnebhi <asmaa@nvidia.com>
Signed-off-by: David Thompson <davthompson@nvidia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
dthompso authored and gregkh committed Jan 10, 2024
1 parent ad0ea7a commit 463fe69
Showing 1 changed file with 7 additions and 2 deletions.
9 changes: 7 additions & 2 deletions drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,13 @@ static bool mlxbf_gige_rx_packet(struct mlxbf_gige *priv, int *rx_pkts)
priv->stats.rx_truncate_errors++;
}

/* Read receive consumer index before replenish so that this routine
* returns accurate return value even if packet is received into
* just-replenished buffer prior to exiting this routine.
*/
rx_ci = readq(priv->base + MLXBF_GIGE_RX_CQE_PACKET_CI);
rx_ci_rem = rx_ci % priv->rx_q_entries;

/* Let hardware know we've replenished one buffer */
rx_pi++;

Expand All @@ -279,8 +286,6 @@ static bool mlxbf_gige_rx_packet(struct mlxbf_gige *priv, int *rx_pkts)
rx_pi_rem = rx_pi % priv->rx_q_entries;
if (rx_pi_rem == 0)
priv->valid_polarity ^= 1;
rx_ci = readq(priv->base + MLXBF_GIGE_RX_CQE_PACKET_CI);
rx_ci_rem = rx_ci % priv->rx_q_entries;

if (skb)
netif_receive_skb(skb);
Expand Down

0 comments on commit 463fe69

Please sign in to comment.