On Tue, Jun 16, 2026 at 07:59:12PM +0800, Menglong Dong wrote:
> For now, XDP_RING_NEED_WAKEUP is not supported properly by the virtio-net
> in the tx path for example: we set xsk_set_tx_need_wakeup() in
> virtnet_xsk_xmit(), but we didn't call xsk_clear_tx_need_wakeup()
> anywhere, which means the user will call send() for every packet.
> 
> We call xsk_set_tx_need_wakeup() after virtnet_xsk_xmit_batch() if sq->vq
> is empty, as we can't be wakeup by the skb_xmit_done() in this case.
> Otherwise, we will clear the wakeup flag.
> 
> Race condition is considered for tx path.
> 
> Fixes: 89f86675cb03 ("virtio_net: xsk: tx: support xmit xsk buffer")
> Signed-off-by: Menglong Dong <[email protected]>

thanks for the patch! yes something to improve.

> ---
> v3:
> - remove the confusing comment
> 
> v2:
> - add the Fixes tag
> ---
>  drivers/net/virtio_net.c | 23 +++++++++++++++++++----
>  1 file changed, 19 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index f4adcfee7a80..6e099edef6e9 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -1440,8 +1440,9 @@ static bool virtnet_xsk_xmit(struct send_queue *sq, 
> struct xsk_buff_pool *pool,
>       struct virtnet_info *vi = sq->vq->vdev->priv;
>       struct virtnet_sq_free_stats stats = {};
>       struct net_device *dev = vi->dev;
> +     int sent, vring_size;
> +     bool need_wakeup;
>       u64 kicks = 0;
> -     int sent;
>  
>       /* Avoid to wakeup napi meanless, so call __free_old_xmit instead of
>        * free_old_xmit().
> @@ -1451,8 +1452,25 @@ static bool virtnet_xsk_xmit(struct send_queue *sq, 
> struct xsk_buff_pool *pool,
>       if (stats.xsk)
>               xsk_tx_completed(sq->xsk_pool, stats.xsk);
>  
> +     vring_size = virtqueue_get_vring_size(sq->vq);
> +     need_wakeup = xsk_uses_need_wakeup(pool);
> +
> +     if (need_wakeup && vring_size == sq->vq->num_free)
> +             xsk_set_tx_need_wakeup(pool);
> +

why are we doing this here?
the check after virtnet_xsk_xmit_batch not enough?
I vaguely think it's some kind of race we are closing?
Pls add a comment to explain.

>       sent = virtnet_xsk_xmit_batch(sq, pool, budget, &kicks);
>  
> +     if (need_wakeup) {
> +             if (vring_size == sq->vq->num_free)
> +                     /* we can't wake up by ourself, and it should be done
> +                      * by the user.
> +                      */
> +                     xsk_set_tx_need_wakeup(pool);
> +             else
> +                     /* we can wake up from skb_xmit_done() */
> +                     xsk_clear_tx_need_wakeup(pool);

But what if we don't have get tx napi so no wakeup in skb_xmit_done?


> +     }
> +
>       if (!is_xdp_raw_buffer_queue(vi, sq - vi->sq))
>               check_sq_full_and_disable(vi, vi->dev, sq);
>  
> @@ -1470,9 +1488,6 @@ static bool virtnet_xsk_xmit(struct send_queue *sq, 
> struct xsk_buff_pool *pool,
>       u64_stats_add(&sq->stats.xdp_tx,  sent);
>       u64_stats_update_end(&sq->stats.syncp);
>  
> -     if (xsk_uses_need_wakeup(pool))
> -             xsk_set_tx_need_wakeup(pool);
> -
>       return sent;
>  }
>  
> -- 
> 2.54.0


Reply via email to