]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[virtio] Allow for long delays in processing transmit queue submissions
authorMichael Brown <mcb30@ipxe.org>
Thu, 2 Jul 2026 12:09:44 +0000 (13:09 +0100)
committerMichael Brown <mcb30@ipxe.org>
Thu, 2 Jul 2026 12:09:44 +0000 (13:09 +0100)
When using QEMU with the KVM accelerator, MMIO writes to the queue
doorbell register are likely to hit an ioeventfd region.  KVM will
signal readiness on the ioeventfd file descriptor (which will
eventually wake up the QEMU userspace process to handle the MMIO
write) and then immediately resume execution of the iPXE guest.

This can result in high latencies in processing submitted descriptors.
With the small transmit queue fill level used by iPXE, this can easily
overrun the transmit queue and result in large numbers of dropped
transmissions.

Increase the transmit queue fill level to utilise the whole queue if
needed, and use the transmission deferral mechanism to avoid dropping
packets when high latencies occur during operation.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/drivers/net/virtio-net.c
src/drivers/net/virtio-net.h

index ba864daa120f124d0a5115d763da5e6e11bb01d9..e67e4aa9992372aecd20bf7f178d29544e37b184 100644 (file)
@@ -396,14 +396,12 @@ static void virtio_net_close ( struct net_device *netdev ) {
 static int virtio_net_transmit ( struct net_device *netdev,
                                 struct io_buffer *iobuf ) {
        struct virtio_net *vnet = netdev->priv;
-       struct virtio_device *virtio = &vnet->virtio;
        struct virtio_net_queue *queue = &vnet->tx;
 
-       /* Check for an available transmit descriptor */
+       /* Defer packet if there are no available transmit descriptors */
        if ( ( queue->queue.prod - queue->queue.cons ) >= queue->fill ) {
-               DBGC ( vnet, "VNET %s out of transmit descriptors\n",
-                      virtio->name );
-               return -ENOBUFS;
+               netdev_tx_defer ( netdev, iobuf );
+               return 0;
        }
 
        /* Submit I/O buffer */
index 2a3423fb631773cb1c2abb9a07c30b441a629834..6fbe3a92409649d9bad3c247c827e26f6dd7e65d 100644 (file)
@@ -48,7 +48,7 @@ union virtio_net_header {
 #define VIRTIO_NET_TX_COUNT 128
 
 /** Transmit queue maximum fill level */
-#define VIRTIO_NET_TX_MAX 32
+#define VIRTIO_NET_TX_MAX 128
 
 /** Number of descriptors per packet */
 #define VIRTIO_NET_DESCS 2