On Wed, 19 May 2021 08:44:01 -0400, Michael S. Tsirkin <mst@xxxxxxxxxx> wrote: > On Wed, May 19, 2021 at 07:47:57PM +0800, Xuan Zhuo wrote: > > Unlike virtqueue_kick(), virtqueue_kick_try() returns true only when the > > kick is successful. In virtio-net, we want to count the number of kicks. > > So we need an interface that can perceive whether the kick is actually > > executed. > > > > Signed-off-by: Xuan Zhuo <xuanzhuo@xxxxxxxxxxxxxxxxx> > > --- > > drivers/net/virtio_net.c | 8 ++++---- > > drivers/virtio/virtio_ring.c | 20 ++++++++++++++++++++ > > include/linux/virtio.h | 2 ++ > > 3 files changed, 26 insertions(+), 4 deletions(-) > > > > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c > > index 9b6a4a875c55..167697030cb6 100644 > > --- a/drivers/net/virtio_net.c > > +++ b/drivers/net/virtio_net.c > > @@ -617,7 +617,7 @@ static int virtnet_xdp_xmit(struct net_device *dev, > > ret = nxmit; > > > > if (flags & XDP_XMIT_FLUSH) { > > - if (virtqueue_kick_prepare(sq->vq) && virtqueue_notify(sq->vq)) > > + if (virtqueue_kick_try(sq->vq)) > > kicks = 1; > > } > > out: > > @@ -1325,7 +1325,7 @@ static bool try_fill_recv(struct virtnet_info *vi, struct receive_queue *rq, > > if (err) > > break; > > } while (rq->vq->num_free); > > - if (virtqueue_kick_prepare(rq->vq) && virtqueue_notify(rq->vq)) { > > + if (virtqueue_kick_try(rq->vq)) { > > unsigned long flags; > > > > flags = u64_stats_update_begin_irqsave(&rq->stats.syncp); > > @@ -1533,7 +1533,7 @@ static int virtnet_poll(struct napi_struct *napi, int budget) > > > > if (xdp_xmit & VIRTIO_XDP_TX) { > > sq = virtnet_xdp_get_sq(vi); > > - if (virtqueue_kick_prepare(sq->vq) && virtqueue_notify(sq->vq)) { > > + if (virtqueue_kick_try(sq->vq)) { > > u64_stats_update_begin(&sq->stats.syncp); > > sq->stats.kicks++; > > u64_stats_update_end(&sq->stats.syncp); > > @@ -1710,7 +1710,7 @@ static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev) > > } > > > > if (kick || netif_xmit_stopped(txq)) { > > - if (virtqueue_kick_prepare(sq->vq) && virtqueue_notify(sq->vq)) { > > + if (virtqueue_kick_try(sq->vq)) { > > u64_stats_update_begin(&sq->stats.syncp); > > sq->stats.kicks++; > > u64_stats_update_end(&sq->stats.syncp); > > diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c > > index 71e16b53e9c1..1462be756875 100644 > > --- a/drivers/virtio/virtio_ring.c > > +++ b/drivers/virtio/virtio_ring.c > > @@ -1874,6 +1874,26 @@ bool virtqueue_kick(struct virtqueue *vq) > > } > > EXPORT_SYMBOL_GPL(virtqueue_kick); > > > > +/** > > + * virtqueue_kick_try - try update after add_buf > > + * @vq: the struct virtqueue > > + * > > + * After one or more virtqueue_add_* calls, invoke this to kick > > + * the other side. > > + * > > + * Caller must ensure we don't call this with other virtqueue > > + * operations at the same time (except where noted). > > + * > > + * Returns true if kick success, otherwise false. > > so what is the difference between this and virtqueue_kick > which says > > * Returns false if kick failed, otherwise true. Calling virtqueue_kick, we can only know whether there is a kick failure, we don't know whether kick is called. It may return true, but kick is not called. virtqueue_kick_try() returns true only if the kick is successful, so that we can know whether kick has been called based on the return value, so as to count the number of kick calls. Thanks. > > > > > > > > > + */ > > +bool virtqueue_kick_try(struct virtqueue *vq) > > +{ > > + if (virtqueue_kick_prepare(vq) && virtqueue_notify(vq)) > > + return true; > > + return false; > > +} > > +EXPORT_SYMBOL_GPL(virtqueue_kick_try); > > + > > /** > > * virtqueue_get_buf - get the next used buffer > > * @_vq: the struct virtqueue we're talking about. > > diff --git a/include/linux/virtio.h b/include/linux/virtio.h > > index b1894e0323fa..45cd6a0af24d 100644 > > --- a/include/linux/virtio.h > > +++ b/include/linux/virtio.h > > @@ -59,6 +59,8 @@ int virtqueue_add_sgs(struct virtqueue *vq, > > > > bool virtqueue_kick(struct virtqueue *vq); > > > > +bool virtqueue_kick_try(struct virtqueue *vq); > > + > > bool virtqueue_kick_prepare(struct virtqueue *vq); > > > > bool virtqueue_notify(struct virtqueue *vq); > > -- > > 2.31.0 > _______________________________________________ Virtualization mailing list Virtualization@xxxxxxxxxxxxxxxxxxxxxxxxxx https://lists.linuxfoundation.org/mailman/listinfo/virtualization