Skip to content

Commit 18781cc

Browse files
lkpdngregkh
authored andcommitted
NTB: ntb_netdev: Preserve RX queue depth on allocation failure
[ Upstream commit d2121fa ] ntb_netdev_rx_handler() hands the received skb to the network stack before allocating its replacement. If the allocation fails, nothing is reposted. Every failure therefore takes one buffer out of the RX queue while the interface remains up, and enough failures eventually stall reception. A retry path could refill the queue later, but ntb_netdev has none. Allocate the replacement first instead. If that fails, drop the packet and repost the same skb. This keeps the queue full and lets packet delivery resume as soon as memory is available again. Fixes: 548c237 ("net: Add support for NTB virtual ethernet device") Cc: stable@vger.kernel.org Signed-off-by: Koichiro Den <den@valinux.co.jp> Reviewed-by: Dave Jiang <dave.jiang@intel.com> Link: https://patch.msgid.link/20260806032537.3526498-1-den@valinux.co.jp Signed-off-by: Paolo Abeni <pabeni@redhat.com> [ kept HEAD's `struct net_device *ndev = qp_data;` declaration instead of the per-queue context variables, adding only `new_skb` to the existing `skb` declaration ] Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 8e92e03 commit 18781cc

1 file changed

Lines changed: 8 additions & 7 deletions

File tree

‎drivers/net/ntb_netdev.c‎

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ static void ntb_netdev_rx_handler(struct ntb_transport_qp *qp, void *qp_data,
100100
void *data, int len)
101101
{
102102
struct net_device *ndev = qp_data;
103-
struct sk_buff *skb;
103+
struct sk_buff *skb, *new_skb;
104104
int rc;
105105

106106
skb = data;
@@ -115,6 +115,12 @@ static void ntb_netdev_rx_handler(struct ntb_transport_qp *qp, void *qp_data,
115115
goto enqueue_again;
116116
}
117117

118+
new_skb = netdev_alloc_skb(ndev, ndev->mtu + ETH_HLEN);
119+
if (!new_skb) {
120+
ndev->stats.rx_dropped++;
121+
goto enqueue_again;
122+
}
123+
118124
skb_put(skb, len);
119125
skb->protocol = eth_type_trans(skb, ndev);
120126
skb->ip_summed = CHECKSUM_NONE;
@@ -127,12 +133,7 @@ static void ntb_netdev_rx_handler(struct ntb_transport_qp *qp, void *qp_data,
127133
ndev->stats.rx_bytes += len;
128134
}
129135

130-
skb = netdev_alloc_skb(ndev, ndev->mtu + ETH_HLEN);
131-
if (!skb) {
132-
ndev->stats.rx_errors++;
133-
ndev->stats.rx_frame_errors++;
134-
return;
135-
}
136+
skb = new_skb;
136137

137138
enqueue_again:
138139
rc = ntb_transport_rx_enqueue(qp, skb, skb->data, ndev->mtu + ETH_HLEN);

0 commit comments

Comments
 (0)