Re: [PATCH net-next v4 2/5] virtio_net: enable irq for the control vq
From: "Michael S. Tsirkin" <mst@redhat.com>
Date: 2024-06-24 11:30:21
Also in:
virtualization
On Thu, Jun 20, 2024 at 12:19:05AM +0800, Heng Qi wrote:
quoted hunk ↗ jump to hunk
If the device does not respond to a request for a long time, then control vq polling elevates CPU utilization, a problem that exacerbates with more command requests. Enabling control vq's irq is advantageous for the guest, and this still doesn't support concurrent requests. Suggested-by: Jason Wang <jasowang@redhat.com> Signed-off-by: Heng Qi <redacted> --- drivers/net/virtio_net.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-)diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index b45f58a902e3..ed10084997d3 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c@@ -372,6 +372,8 @@ struct virtio_net_ctrl_rss { struct control_buf { struct virtio_net_ctrl_hdr hdr; virtio_net_ctrl_ack status; + /* Wait for the device to complete the cvq request. */ + struct completion completion; }; struct virtnet_info {@@ -664,6 +666,13 @@ static bool virtqueue_napi_complete(struct napi_struct *napi, return false; } +static void virtnet_cvq_done(struct virtqueue *cvq) +{ + struct virtnet_info *vi = cvq->vdev->priv; + + complete(&vi->ctrl->completion); +} + static void skb_xmit_done(struct virtqueue *vq) { struct virtnet_info *vi = vq->vdev->priv;
quoted hunk ↗ jump to hunk
@@ -2724,14 +2733,8 @@ static bool virtnet_send_command_reply(struct virtnet_info *vi, if (unlikely(!virtqueue_kick(vi->cvq))) goto unlock; - /* Spin for a response, the kick causes an ioport write, trapping - * into the hypervisor, so the request should be handled immediately. - */ - while (!virtqueue_get_buf(vi->cvq, &tmp) && - !virtqueue_is_broken(vi->cvq)) { - cond_resched(); - cpu_relax(); - } + wait_for_completion(&ctrl->completion); + virtqueue_get_buf(vi->cvq, &tmp); unlock: ok = ctrl->status == VIRTIO_NET_OK;
Hmm no this is not a good idea, code should be robust in case of spurious interrupts. Also suprise removal is now broken ...
quoted hunk ↗ jump to hunk
@@ -5312,7 +5315,7 @@ static int virtnet_find_vqs(struct virtnet_info *vi) /* Parameters for control virtqueue, if any */ if (vi->has_cvq) { - callbacks[total_vqs - 1] = NULL; + callbacks[total_vqs - 1] = virtnet_cvq_done; names[total_vqs - 1] = "control"; }@@ -5832,6 +5835,7 @@ static int virtnet_probe(struct virtio_device *vdev) if (vi->has_rss || vi->has_rss_hash_report) virtnet_init_default_rss(vi); + init_completion(&vi->ctrl->completion); enable_rx_mode_work(vi); /* serialize netdev register + virtio_device_ready() with ndo_open() */-- 2.32.0.3.g01195cf9f