Introduce vhost_virtqueue_restart(), which can restart the virtqueue when the vhost net started running before.
Introduce vhost_virtqueue_stop(), which can disable the vq and unmap vrings and the desc of the vq. When disabling the vq, the function is blocked and waits for a reply. Combining the two functions, we can reset a virtqueue with a started vhost net. Signed-off-by: Kangjie Xu <kangjie...@linux.alibaba.com> Signed-off-by: Xuan Zhuo <xuanz...@linux.alibaba.com> --- hw/net/vhost_net.c | 55 +++++++++++++++++++++++++++++++++++++++++ include/net/vhost_net.h | 5 ++++ 2 files changed, 60 insertions(+) diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c index ccac5b7a64..4f5f034c11 100644 --- a/hw/net/vhost_net.c +++ b/hw/net/vhost_net.c @@ -514,3 +514,58 @@ int vhost_net_set_mtu(struct vhost_net *net, uint16_t mtu) return vhost_ops->vhost_net_set_mtu(&net->dev, mtu); } + +void vhost_virtqueue_stop(VirtIODevice *vdev, NetClientState *nc, + int vq_index) +{ + VHostNetState *net = get_vhost_net(nc->peer); + const VhostOps *vhost_ops = net->dev.vhost_ops; + int r; + + assert(vhost_ops); + + r = vhost_ops->vhost_set_single_vring_enable(&net->dev, vq_index, 0, true); + if (r < 0) { + goto err_queue_disable; + } + + vhost_dev_virtqueue_release(&net->dev, vdev, vq_index); + + return; + +err_queue_disable: + error_report("Error when releasing the qeuue."); +} + +int vhost_virtqueue_restart(VirtIODevice *vdev, NetClientState *nc, + int vq_index) +{ + VHostNetState *net = get_vhost_net(nc->peer); + const VhostOps *vhost_ops = net->dev.vhost_ops; + int r; + + if (!net->dev.started) { + return 0; + } + + assert(vhost_ops); + + r = vhost_dev_virtqueue_restart(&net->dev, vdev, vq_index); + if (r < 0) { + goto err_start; + } + + r = vhost_ops->vhost_set_single_vring_enable(&net->dev, vq_index, 1, + false); + if (r < 0) { + goto err_start; + } + + return 0; + +err_start: + error_report("Error when restarting the queue."); + vhost_dev_stop(&net->dev, vdev); + + return r; +} diff --git a/include/net/vhost_net.h b/include/net/vhost_net.h index 387e913e4e..fcb09e36ef 100644 --- a/include/net/vhost_net.h +++ b/include/net/vhost_net.h @@ -48,4 +48,9 @@ uint64_t vhost_net_get_acked_features(VHostNetState *net); int vhost_net_set_mtu(struct vhost_net *net, uint16_t mtu); +void vhost_virtqueue_stop(VirtIODevice *vdev, NetClientState *nc, + int vq_index); +int vhost_virtqueue_restart(VirtIODevice *vdev, NetClientState *nc, + int vq_index); + #endif -- 2.32.0