mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-02 15:23:53 -06:00
vhost-net: control virtqueue support
We assume there's no cvq in the past, this is not true when we need control virtqueue support for vhost-user backends. So this patch implements the control virtqueue support for vhost-net. As datapath, the control virtqueue is also required to be coupled with the NetClientState. The vhost_net_start/stop() are tweaked to accept the number of datapath queue pairs plus the the number of control virtqueue for us to start and stop the vhost device. Signed-off-by: Jason Wang <jasowang@redhat.com> Message-Id: <20211020045600.16082-7-jasowang@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
2f849dbdb2
commit
05ba3f63d1
4 changed files with 40 additions and 17 deletions
|
@ -315,11 +315,14 @@ static void vhost_net_stop_one(struct vhost_net *net,
|
|||
}
|
||||
|
||||
int vhost_net_start(VirtIODevice *dev, NetClientState *ncs,
|
||||
int total_queues)
|
||||
int data_queue_pairs, int cvq)
|
||||
{
|
||||
BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(dev)));
|
||||
VirtioBusState *vbus = VIRTIO_BUS(qbus);
|
||||
VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(vbus);
|
||||
int total_notifiers = data_queue_pairs * 2 + cvq;
|
||||
VirtIONet *n = VIRTIO_NET(dev);
|
||||
int nvhosts = data_queue_pairs + cvq;
|
||||
struct vhost_net *net;
|
||||
int r, e, i;
|
||||
NetClientState *peer;
|
||||
|
@ -329,9 +332,14 @@ int vhost_net_start(VirtIODevice *dev, NetClientState *ncs,
|
|||
return -ENOSYS;
|
||||
}
|
||||
|
||||
for (i = 0; i < total_queues; i++) {
|
||||
for (i = 0; i < nvhosts; i++) {
|
||||
|
||||
if (i < data_queue_pairs) {
|
||||
peer = qemu_get_peer(ncs, i);
|
||||
} else { /* Control Virtqueue */
|
||||
peer = qemu_get_peer(ncs, n->max_queues);
|
||||
}
|
||||
|
||||
peer = qemu_get_peer(ncs, i);
|
||||
net = get_vhost_net(peer);
|
||||
vhost_net_set_vq_index(net, i * 2);
|
||||
|
||||
|
@ -344,14 +352,18 @@ int vhost_net_start(VirtIODevice *dev, NetClientState *ncs,
|
|||
}
|
||||
}
|
||||
|
||||
r = k->set_guest_notifiers(qbus->parent, total_queues * 2, true);
|
||||
r = k->set_guest_notifiers(qbus->parent, total_notifiers, true);
|
||||
if (r < 0) {
|
||||
error_report("Error binding guest notifier: %d", -r);
|
||||
goto err;
|
||||
}
|
||||
|
||||
for (i = 0; i < total_queues; i++) {
|
||||
peer = qemu_get_peer(ncs, i);
|
||||
for (i = 0; i < nvhosts; i++) {
|
||||
if (i < data_queue_pairs) {
|
||||
peer = qemu_get_peer(ncs, i);
|
||||
} else {
|
||||
peer = qemu_get_peer(ncs, n->max_queues);
|
||||
}
|
||||
r = vhost_net_start_one(get_vhost_net(peer), dev);
|
||||
|
||||
if (r < 0) {
|
||||
|
@ -375,7 +387,7 @@ err_start:
|
|||
peer = qemu_get_peer(ncs , i);
|
||||
vhost_net_stop_one(get_vhost_net(peer), dev);
|
||||
}
|
||||
e = k->set_guest_notifiers(qbus->parent, total_queues * 2, false);
|
||||
e = k->set_guest_notifiers(qbus->parent, total_notifiers, false);
|
||||
if (e < 0) {
|
||||
fprintf(stderr, "vhost guest notifier cleanup failed: %d\n", e);
|
||||
fflush(stderr);
|
||||
|
@ -385,18 +397,27 @@ err:
|
|||
}
|
||||
|
||||
void vhost_net_stop(VirtIODevice *dev, NetClientState *ncs,
|
||||
int total_queues)
|
||||
int data_queue_pairs, int cvq)
|
||||
{
|
||||
BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(dev)));
|
||||
VirtioBusState *vbus = VIRTIO_BUS(qbus);
|
||||
VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(vbus);
|
||||
VirtIONet *n = VIRTIO_NET(dev);
|
||||
NetClientState *peer;
|
||||
int total_notifiers = data_queue_pairs * 2 + cvq;
|
||||
int nvhosts = data_queue_pairs + cvq;
|
||||
int i, r;
|
||||
|
||||
for (i = 0; i < total_queues; i++) {
|
||||
vhost_net_stop_one(get_vhost_net(ncs[i].peer), dev);
|
||||
for (i = 0; i < nvhosts; i++) {
|
||||
if (i < data_queue_pairs) {
|
||||
peer = qemu_get_peer(ncs, i);
|
||||
} else {
|
||||
peer = qemu_get_peer(ncs, n->max_queues);
|
||||
}
|
||||
vhost_net_stop_one(get_vhost_net(peer), dev);
|
||||
}
|
||||
|
||||
r = k->set_guest_notifiers(qbus->parent, total_queues * 2, false);
|
||||
r = k->set_guest_notifiers(qbus->parent, total_notifiers, false);
|
||||
if (r < 0) {
|
||||
fprintf(stderr, "vhost guest notifier cleanup failed: %d\n", r);
|
||||
fflush(stderr);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue