mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-07 17:53:56 -06:00
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>
This commit is contained in:
parent
c2daa08e17
commit
10f8a115a8
3 changed files with 61 additions and 0 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue