Re: [PATCH net] NTB: ntb_netdev: Preserve RX queue depth on allocation failure
Dave Jiang <[email protected]>
| Newsgroups | dev.linux.lists.ntb,org.kernel.vger.linux-kernel,org.kernel.vger.netdev |
|---|---|
| Message-ID | <[email protected]> |
On 8/5/26 8:25 PM, Koichiro Den wrote:
> 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: 548c237c0a99 ("net: Add support for NTB virtual ethernet device")
> Cc: [email protected]
> Signed-off-by: Koichiro Den <[email protected]>
Reviewed-by: Dave Jiang <[email protected]>
> ---
> drivers/net/ntb_netdev.c | 15 ++++++++-------
> 1 file changed, 8 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/net/ntb_netdev.c b/drivers/net/ntb_netdev.c
> index c3a6ba96fc8a..029a4a532a10 100644
> --- a/drivers/net/ntb_netdev.c
> +++ b/drivers/net/ntb_netdev.c
> @@ -127,8 +127,8 @@ static void ntb_netdev_rx_handler(struct ntb_transport_qp *qp, void *qp_data,
> {
> struct ntb_netdev_queue *q = qp_data;
> struct ntb_netdev *dev = q->ntdev;
> + struct sk_buff *skb, *new_skb;
> struct net_device *ndev;
> - struct sk_buff *skb;
> int rc;
>
> ndev = dev->ndev;
> @@ -144,6 +144,12 @@ static void ntb_netdev_rx_handler(struct ntb_transport_qp *qp, void *qp_data,
> goto enqueue_again;
> }
>
> + new_skb = netdev_alloc_skb(ndev, ndev->mtu + ETH_HLEN);
> + if (!new_skb) {
> + ndev->stats.rx_dropped++;
> + goto enqueue_again;
> + }
> +
> skb_put(skb, len);
> skb->protocol = eth_type_trans(skb, ndev);
> skb->ip_summed = CHECKSUM_NONE;
> @@ -157,12 +163,7 @@ static void ntb_netdev_rx_handler(struct ntb_transport_qp *qp, void *qp_data,
> ndev->stats.rx_bytes += len;
> }
>
> - skb = netdev_alloc_skb(ndev, ndev->mtu + ETH_HLEN);
> - if (!skb) {
> - ndev->stats.rx_errors++;
> - ndev->stats.rx_frame_errors++;
> - return;
> - }
> + skb = new_skb;
>
> enqueue_again:
> rc = ntb_transport_rx_enqueue(qp, skb, skb->data, ndev->mtu + ETH_HLEN);