On Mon, Mar 6, 2023 at 12:15 PM Xuan Zhuo <xuanzhuo@xxxxxxxxxxxxxxxxx> wrote: > > Separate the logic of checking whether sq is full. The subsequent patch > will reuse this func. > > Signed-off-by: Xuan Zhuo <xuanzhuo@xxxxxxxxxxxxxxxxx> > --- > drivers/net/virtio_net.c | 59 ++++++++++++++++++++++++---------------- > 1 file changed, 35 insertions(+), 24 deletions(-) > > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c > index fb5e68ed3ec2..777de0ec0b1b 100644 > --- a/drivers/net/virtio_net.c > +++ b/drivers/net/virtio_net.c > @@ -1750,6 +1750,40 @@ static void free_old_xmit_skbs(struct send_queue *sq, bool in_napi) > u64_stats_update_end(&sq->stats.syncp); > } > > +static void check_sq_full(struct virtnet_info *vi, struct net_device *dev, > + struct send_queue *sq) > +{ Nit: we need a better name, it's not only the check but also can disable TX. Thanks > + bool use_napi = sq->napi.weight; > + int qnum; > + > + qnum = sq - vi->sq; > + > + /* If running out of space, stop queue to avoid getting packets that we > + * are then unable to transmit. > + * An alternative would be to force queuing layer to requeue the skb by > + * returning NETDEV_TX_BUSY. However, NETDEV_TX_BUSY should not be > + * returned in a normal path of operation: it means that driver is not > + * maintaining the TX queue stop/start state properly, and causes > + * the stack to do a non-trivial amount of useless work. > + * Since most packets only take 1 or 2 ring slots, stopping the queue > + * early means 16 slots are typically wasted. > + */ > + if (sq->vq->num_free < 2+MAX_SKB_FRAGS) { > + netif_stop_subqueue(dev, qnum); > + if (use_napi) { > + if (unlikely(!virtqueue_enable_cb_delayed(sq->vq))) > + virtqueue_napi_schedule(&sq->napi, sq->vq); > + } else if (unlikely(!virtqueue_enable_cb_delayed(sq->vq))) { > + /* More just got used, free them then recheck. */ > + free_old_xmit_skbs(sq, false); > + if (sq->vq->num_free >= 2+MAX_SKB_FRAGS) { > + netif_start_subqueue(dev, qnum); > + virtqueue_disable_cb(sq->vq); > + } > + } > + } > +} > + > static bool is_xdp_raw_buffer_queue(struct virtnet_info *vi, int q) > { > if (q < (vi->curr_queue_pairs - vi->xdp_queue_pairs)) > @@ -1989,30 +2023,7 @@ static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev) > nf_reset_ct(skb); > } > > - /* If running out of space, stop queue to avoid getting packets that we > - * are then unable to transmit. > - * An alternative would be to force queuing layer to requeue the skb by > - * returning NETDEV_TX_BUSY. However, NETDEV_TX_BUSY should not be > - * returned in a normal path of operation: it means that driver is not > - * maintaining the TX queue stop/start state properly, and causes > - * the stack to do a non-trivial amount of useless work. > - * Since most packets only take 1 or 2 ring slots, stopping the queue > - * early means 16 slots are typically wasted. > - */ > - if (sq->vq->num_free < 2+MAX_SKB_FRAGS) { > - netif_stop_subqueue(dev, qnum); > - if (use_napi) { > - if (unlikely(!virtqueue_enable_cb_delayed(sq->vq))) > - virtqueue_napi_schedule(&sq->napi, sq->vq); > - } else if (unlikely(!virtqueue_enable_cb_delayed(sq->vq))) { > - /* More just got used, free them then recheck. */ > - free_old_xmit_skbs(sq, false); > - if (sq->vq->num_free >= 2+MAX_SKB_FRAGS) { > - netif_start_subqueue(dev, qnum); > - virtqueue_disable_cb(sq->vq); > - } > - } > - } > + check_sq_full(vi, dev, sq); > > if (kick || netif_xmit_stopped(txq)) { > if (virtqueue_kick_prepare(sq->vq) && virtqueue_notify(sq->vq)) { > -- > 2.32.0.3.g01195cf9f >