Skip to content

Commit 05ba3f6

Browse files
jasowangmstsirkin
authored andcommitted
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 <[email protected]> Message-Id: <[email protected]> Reviewed-by: Michael S. Tsirkin <[email protected]> Signed-off-by: Michael S. Tsirkin <[email protected]>
1 parent 2f849db commit 05ba3f6

File tree

4 files changed

+40
-17
lines changed

4 files changed

+40
-17
lines changed

hw/net/vhost_net-stub.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,13 @@ struct vhost_net *vhost_net_init(VhostNetOptions *options)
3333

3434
int vhost_net_start(VirtIODevice *dev,
3535
NetClientState *ncs,
36-
int total_queues)
36+
int data_queue_pairs, int cvq)
3737
{
3838
return -ENOSYS;
3939
}
4040
void vhost_net_stop(VirtIODevice *dev,
4141
NetClientState *ncs,
42-
int total_queues)
42+
int data_queue_pairs, int cvq)
4343
{
4444
}
4545

hw/net/vhost_net.c

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -315,11 +315,14 @@ static void vhost_net_stop_one(struct vhost_net *net,
315315
}
316316

317317
int vhost_net_start(VirtIODevice *dev, NetClientState *ncs,
318-
int total_queues)
318+
int data_queue_pairs, int cvq)
319319
{
320320
BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(dev)));
321321
VirtioBusState *vbus = VIRTIO_BUS(qbus);
322322
VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(vbus);
323+
int total_notifiers = data_queue_pairs * 2 + cvq;
324+
VirtIONet *n = VIRTIO_NET(dev);
325+
int nvhosts = data_queue_pairs + cvq;
323326
struct vhost_net *net;
324327
int r, e, i;
325328
NetClientState *peer;
@@ -329,9 +332,14 @@ int vhost_net_start(VirtIODevice *dev, NetClientState *ncs,
329332
return -ENOSYS;
330333
}
331334

332-
for (i = 0; i < total_queues; i++) {
335+
for (i = 0; i < nvhosts; i++) {
336+
337+
if (i < data_queue_pairs) {
338+
peer = qemu_get_peer(ncs, i);
339+
} else { /* Control Virtqueue */
340+
peer = qemu_get_peer(ncs, n->max_queues);
341+
}
333342

334-
peer = qemu_get_peer(ncs, i);
335343
net = get_vhost_net(peer);
336344
vhost_net_set_vq_index(net, i * 2);
337345

@@ -344,14 +352,18 @@ int vhost_net_start(VirtIODevice *dev, NetClientState *ncs,
344352
}
345353
}
346354

347-
r = k->set_guest_notifiers(qbus->parent, total_queues * 2, true);
355+
r = k->set_guest_notifiers(qbus->parent, total_notifiers, true);
348356
if (r < 0) {
349357
error_report("Error binding guest notifier: %d", -r);
350358
goto err;
351359
}
352360

353-
for (i = 0; i < total_queues; i++) {
354-
peer = qemu_get_peer(ncs, i);
361+
for (i = 0; i < nvhosts; i++) {
362+
if (i < data_queue_pairs) {
363+
peer = qemu_get_peer(ncs, i);
364+
} else {
365+
peer = qemu_get_peer(ncs, n->max_queues);
366+
}
355367
r = vhost_net_start_one(get_vhost_net(peer), dev);
356368

357369
if (r < 0) {
@@ -375,7 +387,7 @@ int vhost_net_start(VirtIODevice *dev, NetClientState *ncs,
375387
peer = qemu_get_peer(ncs , i);
376388
vhost_net_stop_one(get_vhost_net(peer), dev);
377389
}
378-
e = k->set_guest_notifiers(qbus->parent, total_queues * 2, false);
390+
e = k->set_guest_notifiers(qbus->parent, total_notifiers, false);
379391
if (e < 0) {
380392
fprintf(stderr, "vhost guest notifier cleanup failed: %d\n", e);
381393
fflush(stderr);
@@ -385,18 +397,27 @@ int vhost_net_start(VirtIODevice *dev, NetClientState *ncs,
385397
}
386398

387399
void vhost_net_stop(VirtIODevice *dev, NetClientState *ncs,
388-
int total_queues)
400+
int data_queue_pairs, int cvq)
389401
{
390402
BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(dev)));
391403
VirtioBusState *vbus = VIRTIO_BUS(qbus);
392404
VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(vbus);
405+
VirtIONet *n = VIRTIO_NET(dev);
406+
NetClientState *peer;
407+
int total_notifiers = data_queue_pairs * 2 + cvq;
408+
int nvhosts = data_queue_pairs + cvq;
393409
int i, r;
394410

395-
for (i = 0; i < total_queues; i++) {
396-
vhost_net_stop_one(get_vhost_net(ncs[i].peer), dev);
411+
for (i = 0; i < nvhosts; i++) {
412+
if (i < data_queue_pairs) {
413+
peer = qemu_get_peer(ncs, i);
414+
} else {
415+
peer = qemu_get_peer(ncs, n->max_queues);
416+
}
417+
vhost_net_stop_one(get_vhost_net(peer), dev);
397418
}
398419

399-
r = k->set_guest_notifiers(qbus->parent, total_queues * 2, false);
420+
r = k->set_guest_notifiers(qbus->parent, total_notifiers, false);
400421
if (r < 0) {
401422
fprintf(stderr, "vhost guest notifier cleanup failed: %d\n", r);
402423
fflush(stderr);

hw/net/virtio-net.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -285,14 +285,14 @@ static void virtio_net_vhost_status(VirtIONet *n, uint8_t status)
285285
}
286286

287287
n->vhost_started = 1;
288-
r = vhost_net_start(vdev, n->nic->ncs, queues);
288+
r = vhost_net_start(vdev, n->nic->ncs, queues, 0);
289289
if (r < 0) {
290290
error_report("unable to start vhost net: %d: "
291291
"falling back on userspace virtio", -r);
292292
n->vhost_started = 0;
293293
}
294294
} else {
295-
vhost_net_stop(vdev, n->nic->ncs, queues);
295+
vhost_net_stop(vdev, n->nic->ncs, queues, 0);
296296
n->vhost_started = 0;
297297
}
298298
}

include/net/vhost_net.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@ typedef struct VhostNetOptions {
2121
uint64_t vhost_net_get_max_queues(VHostNetState *net);
2222
struct vhost_net *vhost_net_init(VhostNetOptions *options);
2323

24-
int vhost_net_start(VirtIODevice *dev, NetClientState *ncs, int total_queues);
25-
void vhost_net_stop(VirtIODevice *dev, NetClientState *ncs, int total_queues);
24+
int vhost_net_start(VirtIODevice *dev, NetClientState *ncs,
25+
int data_queue_pairs, int cvq);
26+
void vhost_net_stop(VirtIODevice *dev, NetClientState *ncs,
27+
int data_queue_pairs, int cvq);
2628

2729
void vhost_net_cleanup(VHostNetState *net);
2830

0 commit comments

Comments
 (0)