mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-16 15:34:48 +08:00
mlxbf_gige: fix receive packet race condition
[ Upstream commitdcea1bd45e
] 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:f92e1869d7
("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>
This commit is contained in:
parent
ad0ea7a290
commit
463fe6953f
@ -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++;
|
||||
|
||||
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user