aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKangjie Xu <kangjie.xu@linux.alibaba.com>2022-10-17 17:25:53 +0800
committerMichael S. Tsirkin <mst@redhat.com>2022-11-07 13:12:20 -0500
commit10f8a115a862045a836932c5d519a848dda5d461 (patch)
tree82632dc9d16738f6e0f9beed0a932d59025532cc
parentc2daa08e1713c4799487bae6daf5d41e024ff736 (diff)
downloadqemu-10f8a115a862045a836932c5d519a848dda5d461.zip
qemu-10f8a115a862045a836932c5d519a848dda5d461.tar.gz
qemu-10f8a115a862045a836932c5d519a848dda5d461.tar.bz2
vhost-net: vhost-kernel: introduce vhost_net_virtqueue_restart()
Introduce vhost_net_virtqueue_restart(), which can restart the specific virtqueue when the vhost net started running before. If it fails to restart the virtqueue, the device will be stopped. Here we do not reuse vhost_net_start_one() or vhost_dev_start() because they work at queue pair level. The mem table and features do not change, so we can call the vhost_virtqueue_start() to restart a specific queue. This patch only considers the case of vhost-kernel, when NetClientDriver is NET_CLIENT_DRIVER_TAP. Signed-off-by: Kangjie Xu <kangjie.xu@linux.alibaba.com> Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com> Acked-by: Jason Wang <jasowang@redhat.com> Message-Id: <20221017092558.111082-11-xuanzhuo@linux.alibaba.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
-rw-r--r--hw/net/vhost_net-stub.c6
-rw-r--r--hw/net/vhost_net.c53
-rw-r--r--include/net/vhost_net.h2
3 files changed, 61 insertions, 0 deletions
diff --git a/hw/net/vhost_net-stub.c b/hw/net/vhost_net-stub.c
index 2d745e3..9f7daae 100644
--- a/hw/net/vhost_net-stub.c
+++ b/hw/net/vhost_net-stub.c
@@ -107,3 +107,9 @@ void vhost_net_virtqueue_reset(VirtIODevice *vdev, NetClientState *nc,
{
}
+
+int vhost_net_virtqueue_restart(VirtIODevice *vdev, NetClientState *nc,
+ int vq_index)
+{
+ return 0;
+}
diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
index 8beecb4..d2926e2 100644
--- a/hw/net/vhost_net.c
+++ b/hw/net/vhost_net.c
@@ -34,6 +34,7 @@
#include "standard-headers/linux/virtio_ring.h"
#include "hw/virtio/vhost.h"
#include "hw/virtio/virtio-bus.h"
+#include "linux-headers/linux/vhost.h"
/* Features supported by host kernel. */
@@ -556,3 +557,55 @@ void vhost_net_virtqueue_reset(VirtIODevice *vdev, NetClientState *nc,
net->dev.vqs + idx,
net->dev.vq_index + idx);
}
+
+int vhost_net_virtqueue_restart(VirtIODevice *vdev, NetClientState *nc,
+ int vq_index)
+{
+ VHostNetState *net = get_vhost_net(nc->peer);
+ const VhostOps *vhost_ops = net->dev.vhost_ops;
+ struct vhost_vring_file file = { };
+ int idx, r;
+
+ if (!net->dev.started) {
+ return -EBUSY;
+ }
+
+ /* should only be called after backend is connected */
+ assert(vhost_ops);
+
+ idx = vhost_ops->vhost_get_vq_index(&net->dev, vq_index);
+
+ r = vhost_virtqueue_start(&net->dev,
+ vdev,
+ net->dev.vqs + idx,
+ net->dev.vq_index + idx);
+ if (r < 0) {
+ goto err_start;
+ }
+
+ if (net->nc->info->type == NET_CLIENT_DRIVER_TAP) {
+ file.index = idx;
+ file.fd = net->backend;
+ r = vhost_net_set_backend(&net->dev, &file);
+ if (r < 0) {
+ r = -errno;
+ goto err_start;
+ }
+ }
+
+ return 0;
+
+err_start:
+ error_report("Error when restarting the queue.");
+
+ if (net->nc->info->type == NET_CLIENT_DRIVER_TAP) {
+ file.fd = VHOST_FILE_UNBIND;
+ file.index = idx;
+ int r = vhost_net_set_backend(&net->dev, &file);
+ assert(r >= 0);
+ }
+
+ vhost_dev_stop(&net->dev, vdev);
+
+ return r;
+}
diff --git a/include/net/vhost_net.h b/include/net/vhost_net.h
index 85d85a4..40b9a40 100644
--- a/include/net/vhost_net.h
+++ b/include/net/vhost_net.h
@@ -50,4 +50,6 @@ int vhost_net_set_mtu(struct vhost_net *net, uint16_t mtu);
void vhost_net_virtqueue_reset(VirtIODevice *vdev, NetClientState *nc,
int vq_index);
+int vhost_net_virtqueue_restart(VirtIODevice *vdev, NetClientState *nc,
+ int vq_index);
#endif