|
@@ -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);
|