Skip to contentSkip to conversation

Prepare virtio for upstream QEMU merging

RFC PATCH In review Anthony Liguori 2 participants 8 messages Oct 13, 2008 – Oct 16, 2008 KVM

lore
Share & tools
lore
#0 lore raw

RFC PATCH 1/1 Prepare virtio for upstream QEMU merging

Subject: [PATCH][RFC] Prepare virtio for upstream QEMU merging
Cc: Avi Kivity <[email protected]>

For merging virtio, I thought I'd try a different approach from the fix out of tree and merge all at once approach I took with live migration.

What I would like to do is make some minimal changes to virtio in kvm-userspace so that some form of virtio could be merged in upstream QEMU. We'll have to maintain a small diff in the kvm-userspace tree until we work out some of the issues, but I'd rather work out those issues in the QEMU tree instead of fixing them all outside of the tree first.

The attached patch uses USE_KVM guards to separate KVM specific code. This is not KVM code, per say, but rather routines that aren't mergable right now. I think using the guards make it more clear and easier to deal with merges.

When we submit virtio to qemu-devel and eventually commit, we'll strip out any ifdef USE_KVM block.

The only real significant change in this patch is the use of accessors for the virtio queues. We've discussed patches like this before.

The point of this patch is to make no functional change in the KVM tree. I've confirmed that performance does not regress in virtio-net and that both virtio-blk and virtio-net seem to be functional.

qemu/hw/virtio-blk.c +5 -0
index 727119b..fb703eb 100644
@@ -276,7 +276,9 @@ void *virtio_blk_init(PCIBus *bus, uint16_t vendor, uint16_t device,
 		      BlockDriverState *bs)
 {
     VirtIOBlock *s;
+#ifdef USE_KVM
     int cylinders, heads, secs;
+#endif
     static int virtio_blk_id;
 
     s = (VirtIOBlock *)virtio_init_pci(bus, "virtio-blk", vendor, device,
@@ -290,9 +292,12 @@ void *virtio_blk_init(PCIBus *bus, uint16_t vendor, uint16_t device,
     s->vdev.get_features = virtio_blk_get_features;
     s->vdev.reset = virtio_blk_reset;
     s->bs = bs;
+#ifdef USE_KVM
     bs->devfn = s->vdev.pci_dev.devfn;
+    /* FIXME this can definitely go in upstream QEMU */
     bdrv_guess_geometry(s->bs, &cylinders, &heads, &secs);
     bdrv_set_geometry_hint(s->bs, cylinders, heads, secs);
+#endif
 
     s->vq = virtio_add_queue(&s->vdev, 128, virtio_blk_handle_output);
 
qemu/hw/virtio-net.c +54 -8

175 lines not on this page · raw message

qemu/hw/virtio.c +312 -31

450 lines not on this page · raw message

qemu/hw/virtio.h +10 -48

90 lines not on this page · raw message

#1 lore raw
Quoted 40 lines · Anthony Liguori

For merging virtio, I thought I'd try a different approach from the fix out of tree and merge all at once approach I took with live migration.

What I would like to do is make some minimal changes to virtio in kvm-userspace so that some form of virtio could be merged in upstream QEMU. We'll have to maintain a small diff in the kvm-userspace tree until we work out some of the issues, but I'd rather work out those issues in the QEMU tree instead of fixing them all outside of the tree first.

The attached patch uses USE_KVM guards to separate KVM specific code. This is not KVM code, per say, but rather routines that aren't mergable right now. I think using the guards make it more clear and easier to deal with merges.

When we submit virtio to qemu-devel and eventually commit, we'll strip out any ifdef USE_KVM block.

The only real significant change in this patch is the use of accessors for the virtio queues. We've discussed patches like this before.

The point of this patch is to make no functional change in the KVM tree. I've confirmed that performance does not regress in virtio-net and that both virtio-blk and virtio-net seem to be functional.

qemu/hw/virtio-blk.c +2 -0
index 727119b..fb703eb 100644
@@ -276,7 +276,9 @@ void *virtio_blk_init(PCIBus *bus, uint16_t vendor, uint16_t device,
 		      BlockDriverState *bs)
 {
     VirtIOBlock *s;
+#ifdef USE_KVM
     int cylinders, heads, secs;
+#endif
     static int virtio_blk_id;
 
     s = (VirtIOBlock *)virtio_init_pci(bus, "virtio-blk", vendor, device,

qemu/hw/virtio-blk.c void *virtio_blk_init(PCIBus *bus, uint16_t vendor, uint16_t device, · line 301

Quoted 10 lines
qemu/hw/virtio-blk.c +3 -0
@@ -290,9 +292,12 @@ void *virtio_blk_init(PCIBus *bus, uint16_t vendor, uint16_t device,
     s->vdev.get_features = virtio_blk_get_features;
     s->vdev.reset = virtio_blk_reset;
     s->bs = bs;
+#ifdef USE_KVM
     bs->devfn = s->vdev.pci_dev.devfn;
+    /* FIXME this can definitely go in upstream QEMU */
     bdrv_guess_geometry(s->bs, &cylinders, &heads, &secs);
     bdrv_set_geometry_hint(s->bs, cylinders, heads, secs);
+#endif
 

Why not merge these bits prior to merging virtio? They aren't kvm specific and would be good in mainline qemu.

Quoted 12 lines
qemu/hw/virtio-blk.c +0 -0
 static int virtio_net_can_receive(void *opaque)
 {
     VirtIONet *n = opaque;
qemu/hw/virtio-blk.c +1 -2
-    if (n->rx_vq->vring.avail == NULL ||
+    if (!virtio_queue_ready(n->rx_vq) ||
 	!(n->vdev.status & VIRTIO_CONFIG_S_DRIVER_OK))
 	return 0;
 
-    if (n->rx_vq->vring.avail->idx == n->rx_vq->last_avail_idx) {

qemu/hw/virtio-blk.c

Quoted 10 lines
qemu/hw/virtio-blk.c +3 -2
-	n->rx_vq->vring.used->flags &= ~VRING_USED_F_NO_NOTIFY;
+    if (virtio_queue_empty(n->rx_vq)) {
+        virtio_queue_set_notification(n->rx_vq, 1);
 	return 0;
     }
 
-    n->rx_vq->vring.used->flags |= VRING_USED_F_NO_NOTIFY;
+    virtio_queue_set_notification(n->rx_vq, 0);
     return 1;
 }

This should be in a separate patch.

qemu/hw/virtio-blk.c static void work_around_broken_dhclient(struct virtio_net_hdr *hdr, · line 194

Quoted 11 lines
qemu/hw/virtio-blk.c +2 -0
+#ifdef USE_KVM
 /* dhclient uses AF_PACKET but doesn't pass auxdata to the kernel so
  * it never finds out that the packets don't have valid checksums.  This
  * causes dhclient to get upset.  Fedora's carried a patch for ages to
@@ -181,6 +190,7 @@ static void work_around_broken_dhclient(struct virtio_net_hdr *hdr,
         hdr->flags &= ~VIRTIO_NET_HDR_F_NEEDS_CSUM;
     }
 }
+#endif
 

Is this kvm specific?

qemu/hw/virtio-blk.c static void virtio_net_receive(void *opaque, const uint8_t *buf, int size) · line 208

Quoted 13 lines
qemu/hw/virtio-blk.c +5 -0
 static void virtio_net_receive(void *opaque, const uint8_t *buf, int size)
 {
@@ -190,6 +200,11 @@ static void virtio_net_receive(void *opaque, const uint8_t *buf, int size)
     int offset, i;
     int total;
 
+#ifndef USE_KVM
+    if (!virtio_queue_ready(n->rx_vq))
+        return;
+#endif
+
 

Or this?

qemu/hw/virtio-blk.c static void virtio_net_receive(void *opaque, const uint8_t *buf, int size)

Quoted 9 lines
qemu/hw/virtio-blk.c +2 -0
+#ifdef USE_KVM
     if (tap_has_vnet_hdr(n->vc->vlan->first_client)) {
 	memcpy(hdr, buf, sizeof(*hdr));
 	offset += total;
         work_around_broken_dhclient(hdr, buf + offset, size - offset);
     }
+#endif

Or this?

qemu/hw/virtio-blk.c static void virtio_net_receive(void *opaque, const uint8_t *buf, int size) · line 255

Quoted 13 lines
 
     /* copy in packet.  ugh */
     i = 1;
qemu/hw/virtio-blk.c +4 -0
@@ -230,7 +247,11 @@ static void virtio_net_receive(void *opaque, const uint8_t *buf, int size)
 static void virtio_net_flush_tx(VirtIONet *n, VirtQueue *vq)
 {
     VirtQueueElement elem;
+#ifdef USE_KVM
     int has_vnet_hdr = tap_has_vnet_hdr(n->vc->vlan->first_client);
+#else
+    int has_vnet_hdr = 0;
+#endif
 

Or this?

Quoted 24 lines
qemu/hw/virtio-blk.c +16 -0
     if (!(n->vdev.status & VIRTIO_CONFIG_S_DRIVER_OK))
         return;
@@ -252,7 +273,32 @@ static void virtio_net_flush_tx(VirtIONet *n, VirtQueue *vq)
 	    len += sizeof(struct virtio_net_hdr);
 	}
 
+#ifdef USE_KVM
 	len += qemu_sendv_packet(n->vc, out_sg, out_num);
+#else
+        {
+            size_t size = 0;
+            size_t offset = 0;
+            int i;
+            void *packet;
+
+            for (i = 0; i < out_num; i++)
+                size += out_sg[i].iov_len;
+
+            packet = qemu_malloc(size);
+            if (packet) {
+                for (i = 0; i < out_num; i++) {
+                    memcpy(packet + offset,
+                           out_sg[i].iov_base,

qemu/hw/virtio-blk.c static void virtio_net_flush_tx(VirtIONet *n, VirtQueue *vq) · line 302

Quoted 10 lines
qemu/hw/virtio-blk.c +9 -0
+                           out_sg[i].iov_len);
+                    offset += out_sg[i].iov_len;
+                }
+                qemu_send_packet(n->vc, packet, size);
+                len += size;
+            }
+            qemu_free(packet);
+        }
+#endif
 

Why not merge qemu_sendv_packet? Perhaps with the alternate code as the body if some infrastructure in qemu is missing?

qemu/hw/virtio-blk.c static void virtio_net_handle_tx(VirtIODevice *vdev, VirtQueue *vq) · line 314

Quoted 10 lines
qemu/hw/virtio-blk.c +1 -1
 	virtqueue_push(vq, &elem, len);
 	virtio_notify(&n->vdev, vq);
@@ -264,7 +310,7 @@ static void virtio_net_handle_tx(VirtIODevice *vdev, VirtQueue *vq)
     VirtIONet *n = to_virtio_net(vdev);
 
     if (n->tx_timer_active) {
-	vq->vring.used->flags &= ~VRING_USED_F_NO_NOTIFY;
+        virtio_queue_set_notification(vq, 1);
 

Separate patch.

qemu/hw/virtio-blk.c static void virtio_net_handle_tx(VirtIODevice *vdev, VirtQueue *vq)

Quoted 11 lines
qemu/hw/virtio-blk.c +10 -0
+#ifdef USE_KVM
+    VRingDesc *desc;
+    VRingAvail *avail;
+    VRingUsed *used;
+#else
+    target_phys_addr_t desc;
+    target_phys_addr_t avail;
+    target_phys_addr_t used;
+#endif
+} VRing;

Stumped. Why?

Signature · 1 line
Do not meddle in the internals of kernels, for they are subtle and quick to panic.
#2 lore raw
Quoted 40 lines · Avi Kivity
Quoted 38 lines · Anthony Liguori

For merging virtio, I thought I'd try a different approach from the fix out of tree and merge all at once approach I took with live migration.

What I would like to do is make some minimal changes to virtio in kvm-userspace so that some form of virtio could be merged in upstream QEMU. We'll have to maintain a small diff in the kvm-userspace tree until we work out some of the issues, but I'd rather work out those issues in the QEMU tree instead of fixing them all outside of the tree first.

The attached patch uses USE_KVM guards to separate KVM specific code. This is not KVM code, per say, but rather routines that aren't mergable right now. I think using the guards make it more clear and easier to deal with merges.

When we submit virtio to qemu-devel and eventually commit, we'll strip out any ifdef USE_KVM block.

The only real significant change in this patch is the use of accessors for the virtio queues. We've discussed patches like this before.

The point of this patch is to make no functional change in the KVM tree. I've confirmed that performance does not regress in virtio-net and that both virtio-blk and virtio-net seem to be functional.

qemu/hw/virtio-blk.c +2 -0
index 727119b..fb703eb 100644
@@ -276,7 +276,9 @@ void *virtio_blk_init(PCIBus *bus, uint16_t vendor, uint16_t device,
 		      BlockDriverState *bs)
 {
     VirtIOBlock *s;
+#ifdef USE_KVM
     int cylinders, heads, secs;
+#endif
     static int virtio_blk_id;
 
Quoted 17 lines

qemu/hw/virtio-blk.c void *virtio_blk_init(PCIBus *bus, uint16_t vendor, uint16_t device, · line 302

Quoted 13 lines
qemu/hw/virtio-blk.c +3 -0
     s = (VirtIOBlock *)virtio_init_pci(bus, "virtio-blk", vendor, device,
@@ -290,9 +292,12 @@ void *virtio_blk_init(PCIBus *bus, uint16_t vendor, uint16_t device,
     s->vdev.get_features = virtio_blk_get_features;
     s->vdev.reset = virtio_blk_reset;
     s->bs = bs;
+#ifdef USE_KVM
     bs->devfn = s->vdev.pci_dev.devfn;
+    /* FIXME this can definitely go in upstream QEMU */
     bdrv_guess_geometry(s->bs, &cylinders, &heads, &secs);
     bdrv_set_geometry_hint(s->bs, cylinders, heads, secs);
+#endif
 
 

Why not merge these bits prior to merging virtio? They aren't kvm specific and would be good in mainline qemu.

I'd rather have a consumer of an interface before merging the actual infrastructure.

Quoted 17 lines
Quoted 17 lines
qemu/hw/virtio-blk.c +0 -0
 static int virtio_net_can_receive(void *opaque)
 {
     VirtIONet *n = opaque;
qemu/hw/virtio-blk.c +3 -3
-    if (n->rx_vq->vring.avail == NULL ||
+    if (!virtio_queue_ready(n->rx_vq) ||
 	!(n->vdev.status & VIRTIO_CONFIG_S_DRIVER_OK))
 	return 0;
 
-    if (n->rx_vq->vring.avail->idx == n->rx_vq->last_avail_idx) {
-	n->rx_vq->vring.used->flags &= ~VRING_USED_F_NO_NOTIFY;
+    if (virtio_queue_empty(n->rx_vq)) {
+        virtio_queue_set_notification(n->rx_vq, 1);
 	return 0;
     }
Quoted 9 lines

qemu/hw/virtio-blk.c

Quoted 6 lines
qemu/hw/virtio-blk.c +1 -1
-    n->rx_vq->vring.used->flags |= VRING_USED_F_NO_NOTIFY;
+    virtio_queue_set_notification(n->rx_vq, 0);
     return 1;
 }

This should be in a separate patch.

Sure.

Quoted 15 lines

qemu/hw/virtio-blk.c static void work_around_broken_dhclient(struct virtio_net_hdr *hdr, · line 195

Quoted 12 lines
qemu/hw/virtio-blk.c +2 -0
+#ifdef USE_KVM
 /* dhclient uses AF_PACKET but doesn't pass auxdata to the kernel so
  * it never finds out that the packets don't have valid checksums.  This
  * causes dhclient to get upset.  Fedora's carried a patch for ages to
@@ -181,6 +190,7 @@ static void work_around_broken_dhclient(struct virtio_net_hdr *hdr,
         hdr->flags &= ~VIRTIO_NET_HDR_F_NEEDS_CSUM;
     }
 }
+#endif
 
 

Is this kvm specific?

It is because the GSO stuff has not gone into upstream QEMU yet. I'd rather merge a crippled virtio implementation, and then merge each of the optimizations than vice-versa. Primarily because I'm concerned some of these optimizations will require refactoring.

Quoted 7 lines
Quoted 7 lines
qemu/hw/virtio-blk.c +0 -0
 static void virtio_net_receive(void *opaque, const uint8_t *buf, int size)

{

qemu/hw/virtio-blk.c +0 -0
@@ -190,6 +200,11 @@ static void virtio_net_receive(void *opaque, const uint8_t *buf, int size)
     int offset, i;
     int total;
 
Quoted 10 lines

qemu/hw/virtio-blk.c static void virtio_net_receive(void *opaque, const uint8_t *buf, int size) · line 209

Quoted 7 lines
qemu/hw/virtio-blk.c +5 -0
+#ifndef USE_KVM
+    if (!virtio_queue_ready(n->rx_vq))
+        return;
+#endif
+
 
 

Or this?

This is necessary because of the net optimizations, which yes, should go upstream into QEMU.

Quoted 3 lines

Why not merge qemu_sendv_packet? Perhaps with the alternate code as the body if some infrastructure in qemu is missing?

I will, but I'd rather have a consumer first.

Quoted 6 lines
Quoted 6 lines
qemu/hw/virtio-blk.c +6 -0
+#ifdef USE_KVM
+    VRingDesc *desc;
+    VRingAvail *avail;
+    VRingUsed *used;
+#else
+    target_phys_addr_t desc;
Quoted 9 lines

qemu/hw/virtio-blk.c

Quoted 6 lines
qemu/hw/virtio-blk.c +4 -0
+    target_phys_addr_t avail;
+    target_phys_addr_t used;
+#endif
+} VRing;

Stumped. Why?

In KVM, desc points directly to guest memory. The non-KVM accessors use stl/ldl et al so they only need the physical address base.

If you agree with this approach, I'll clean up the patch and send again.

Regards,

Anthony Liguori

#3 lore raw
Quoted 8 lines · Anthony Liguori
Quoted 4 lines

Why not merge these bits prior to merging virtio? They aren't kvm specific and would be good in mainline qemu.

I'd rather have a consumer of an interface before merging the actual infrastructure.

So merge them all into qemu at the same time (as separate patches, if you like).

Quoted 17 lines
Quoted 16 lines

qemu/hw/virtio-net.c static void work_around_broken_dhclient(struct · line 195

Quoted 13 lines

+#ifdef USE_KVM
/* dhclient uses AF_PACKET but doesn't pass auxdata to the kernel so
* it never finds out that the packets don't have valid checksums.
This
* causes dhclient to get upset. Fedora's carried a patch for ages to

qemu/hw/virtio-net.c +1 -0
@@ -181,6 +190,7 @@ static void work_around_broken_dhclient(struct
 virtio_net_hdr *hdr,
         hdr->flags &= ~VIRTIO_NET_HDR_F_NEEDS_CSUM;
     }
 }
+#endif
 

Is this kvm specific?

Quoted 5 lines

It is because the GSO stuff has not gone into upstream QEMU yet. I'd rather merge a crippled virtio implementation, and then merge each of the optimizations than vice-versa. Primarily because I'm concerned some of these optimizations will require refactoring.

Ok.

Quoted 16 lines
Quoted 15 lines

qemu/hw/virtio.c line 100

Quoted 12 lines
qemu/hw/virtio.c +10 -0
+#ifdef USE_KVM
+    VRingDesc *desc;
+    VRingAvail *avail;
+    VRingUsed *used;
+#else
+    target_phys_addr_t desc;
+    target_phys_addr_t avail;
+    target_phys_addr_t used;
+#endif
+} VRing;

Stumped. Why?

Quoted 4 lines

In KVM, desc points directly to guest memory. The non-KVM accessors use stl/ldl et al so they only need the physical address base.

If you agree with this approach, I'll clean up the patch and send again.

The amount of code duplication is frightening.

I suggest a target_phys_ptr_t which is a struct containing either a pointer or a target_phys_ptr_t, depending on guest/host endianness. Accessors through this type will either deref the pointer or call the qemu variant.

Oh, and we need to set the dirty bit so live migration works. Or do we have a hack in place to force copying of the ring at the last stage?

Signature · 1 line
Do not meddle in the internals of kernels, for they are subtle and quick to panic.
#4 lore raw
Quoted 6 lines · Avi Kivity
Quoted 4 lines · Anthony Liguori
Quoted 4 lines

Why not merge these bits prior to merging virtio? They aren't kvm specific and would be good in mainline qemu.

Quoted 8 lines
Quoted 4 lines

I'd rather have a consumer of an interface before merging the actual infrastructure.

So merge them all into qemu at the same time (as separate patches, if you like).

But that will require refactoring a lot of these optimizations. In order to do that right, they need to be presented on qemu-devel. It's a whole lot easier to do that incrementally so that people can digest it all instead of blasting a big series.

I've posted virtio before on the qemu-devel and what has always been problematic are the various optimizations we do. They tend to cloud the actual implementation of virtio. I think taking this approach will make it all a lot easier.

Quoted 2 lines

The amount of code duplication is frightening.

I've already got that worked out. I need to prepare and commit a patch to fix stw/lduw in upstream QEMU and then we can switch to always using those functions in KVM. I've done some performance testing and that seems to be enough. With that, there is no longer any scary code duplication.

Quoted 3 lines

Oh, and we need to set the dirty bit so live migration works. Or do we have a hack in place to force copying of the ring at the last stage?

With the above fix, the rings accesses are no longer an issue. We just need to dirty memory in the scatter/gather lists on write. That's a very simple change and I'll include it in the next patch series.

Regards,

Anthony Liguori

#5 lore raw
Quoted 8 lines · Anthony Liguori
Quoted 8 lines
Quoted 7 lines
Quoted 3 lines

Why not merge these bits prior to merging virtio? They aren't kvm specific and would be good in mainline qemu.

I'd rather have a consumer of an interface before merging the actual infrastructure.

Quoted 5 lines
Quoted 3 lines

So merge them all into qemu at the same time (as separate patches, if you like).

But that will require refactoring a lot of these optimizations. In order to do that right, they need to be presented on qemu-devel. It's a whole lot easier to do that incrementally so that people can digest it all instead of blasting a big series.

Can you elaborate? Which interfaces will need rework, and why?

Quoted 5 lines
Quoted 3 lines

The amount of code duplication is frightening.

I've already got that worked out. I need to prepare and commit a patch to fix stw/lduw in upstream QEMU and then we can switch to always using those functions in KVM. I've done some performance testing and that seems to be enough. With that, there is no longer any scary code duplication.

Yes, your patch on qemu-devel looks good. Even if we do have a performance problem (which may well turn out after we optimize things some more), it's easy to have a cached pointer along with the phys address.

Signature · 1 line
error compiling committee.c: too many arguments to function
#6 lore raw
Quoted 9 lines · Avi Kivity
Quoted 8 lines · Anthony Liguori
Quoted 8 lines
Quoted 7 lines
Quoted 3 lines

Why not merge these bits prior to merging virtio? They aren't kvm specific and would be good in mainline qemu.

I'd rather have a consumer of an interface before merging the actual infrastructure.

Quoted 7 lines
Quoted 5 lines
Quoted 3 lines

So merge them all into qemu at the same time (as separate patches, if you like).

But that will require refactoring a lot of these optimizations. In order to do that right, they need to be presented on qemu-devel. It's a whole lot easier to do that incrementally so that people can digest it all instead of blasting a big series.

Can you elaborate? Which interfaces will need rework, and why?

Last time I tried, virtio-net doesn't work with slirp. I believe it's either because of the GSO changes (unlikely) or because of the can_receive changes (more likely). The can_receive changes probably need some refactoring to be more slirp friendly. The GSO changes are a bit vlan unfriendly.

Right now, you could construct something like -net tap -net nic,model=virtio -net model=e1000. e1000 doesn't support GSO and bad things will happen from this. It's very centric to the single-nic, single-host driver model. Also, exposing something like tap_has_vnet_hdr() to the actual network cards violates the layering. The network cards shouldn't have any knowledge of what types of host drivers there are, just what features a particular VLAN supports.

It's also unclear how you handle things like NIC hot-plug. What if you add a nic that doesn't support GSO to a VLAN that is using GSO? What about migration? What if you migrate from a host that has GSO support to a host that doesn't support GSO? This later problem is hard and would require either a feature renegotiation mechanism in virtio or software implementation of GSO within QEMU.

Quoted 7 lines
Quoted 5 lines
Quoted 3 lines

The amount of code duplication is frightening.

I've already got that worked out. I need to prepare and commit a patch to fix stw/lduw in upstream QEMU and then we can switch to always using those functions in KVM. I've done some performance testing and that seems to be enough. With that, there is no longer any scary code duplication.

Yes, your patch on qemu-devel looks good. Even if we do have a performance problem (which may well turn out after we optimize things some more), it's easy to have a cached pointer along with the phys address.

And I don't think that patch matters anymore :-/ I was doing measurements with iperf doing TX in the guest. The numbers are very erratic and I mistakenly attributed a boost to that patch.

Measuring based on RX seems to be more reliable since we're pegging the CPU. We idle too much in TX due to the tx mitigation timeouts.

Regards,

Anthony Liguori

#7 lore raw
Quoted 10 lines · Anthony Liguori
Quoted 4 lines
Quoted 2 lines

But that will require refactoring a lot of these optimizations. In order to do that right, they need to be presented on qemu-devel. It's a whole lot easier to do that incrementally so that people can digest it all instead of blasting a big series.

Can you elaborate? Which interfaces will need rework, and why?

Last time I tried, virtio-net doesn't work with slirp. I believe it's either because of the GSO changes (unlikely) or because of the can_receive changes (more likely). The can_receive changes probably need some refactoring to be more slirp friendly. The GSO changes are a bit vlan unfriendly.

Right now, you could construct something like -net tap -net nic,model=virtio -net model=e1000. e1000 doesn't support GSO and bad things will happen from this. It's very centric to the single-nic, single-host driver model. Also, exposing something like tap_has_vnet_hdr() to the actual network cards violates the layering. The network cards shouldn't have any knowledge of what types of host drivers there are, just what features a particular VLAN supports.

It's also unclear how you handle things like NIC hot-plug. What if you add a nic that doesn't support GSO to a VLAN that is using GSO? What about migration? What if you migrate from a host that has GSO support to a host that doesn't support GSO? This later problem is hard and would require either a feature renegotiation mechanism in virtio or software implementation of GSO within QEMU.

Okay, we can go along with mangling the current virtio implementation like you proposed.

Signature · 1 line
error compiling committee.c: too many arguments to function