]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[virtio] Simplify virtqueue shutdown
authorLadi Prosek <lprosek@redhat.com>
Fri, 16 Dec 2016 12:31:22 +0000 (13:31 +0100)
committerMichael Brown <mcb30@ipxe.org>
Sun, 22 Jan 2017 13:20:42 +0000 (13:20 +0000)
This commit introduces virtnet_free_virtqueues called on all virtqueue
error and shutdown paths. vpm_find_vqs no longer cleans up after itself
and instead expects virtnet_free_virtqueues to be always called to undo
its effect.

Signed-off-by: Ladi Prosek <lprosek@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/drivers/bus/virtio-pci.c
src/drivers/net/virtio-net.c

index 1fcf9bae0ec5fa9dc0e8b078d83e0cf94382ee19..c50602a3118750cbc67df0980f70590c69b0183b 100644 (file)
@@ -391,7 +391,7 @@ int vpm_find_vqs(struct virtio_pci_modern_device *vdev,
             off * notify_offset_multiplier, 2,
             &vq->notification);
         if (err) {
-            goto err_map_notify;
+            return err;
         }
     }
 
@@ -405,11 +405,4 @@ int vpm_find_vqs(struct virtio_pci_modern_device *vdev,
         vpm_iowrite16(vdev, &vdev->common, 1, COMMON_OFFSET(queue_enable));
     }
     return 0;
-
-err_map_notify:
-    /* Undo the virtio_pci_map_capability calls. */
-    while (i-- > 0) {
-        virtio_pci_unmap_capability(&vqs[i].notification);
-    }
-    return err;
 }
index fe0fd4b8608753140bafa5f16fe4da30e543bcc8..de3333d2f202716940577594fc4d00bad12e1c4c 100644 (file)
@@ -175,6 +175,22 @@ static void virtnet_refill_rx_virtqueue ( struct net_device *netdev ) {
        }
 }
 
+/** Helper to free all virtqueue memory
+ *
+ * @v netdev           Network device
+ */
+static void virtnet_free_virtqueues ( struct net_device *netdev ) {
+       struct virtnet_nic *virtnet = netdev->priv;
+       int i;
+
+       for ( i = 0; i < QUEUE_NB; i++ ) {
+               virtio_pci_unmap_capability ( &virtnet->virtqueue[i].notification );
+       }
+
+       free ( virtnet->virtqueue );
+       virtnet->virtqueue = NULL;
+}
+
 /** Open network device, legacy virtio 0.9.5
  *
  * @v netdev   Network device
@@ -200,8 +216,7 @@ static int virtnet_open_legacy ( struct net_device *netdev ) {
                if ( vp_find_vq ( ioaddr, i, &virtnet->virtqueue[i] ) == -1 ) {
                        DBGC ( virtnet, "VIRTIO-NET %p cannot register queue %d\n",
                               virtnet, i );
-                       free ( virtnet->virtqueue );
-                       virtnet->virtqueue = NULL;
+                       virtnet_free_virtqueues ( netdev );
                        return -ENOENT;
                }
        }
@@ -263,8 +278,7 @@ static int virtnet_open_modern ( struct net_device *netdev ) {
        if ( vpm_find_vqs ( &virtnet->vdev, QUEUE_NB, virtnet->virtqueue ) ) {
                DBGC ( virtnet, "VIRTIO-NET %p cannot register queues\n",
                       virtnet );
-               free ( virtnet->virtqueue );
-               virtnet->virtqueue = NULL;
+               virtnet_free_virtqueues ( netdev );
                vpm_add_status ( &virtnet->vdev, VIRTIO_CONFIG_S_FAILED );
                return -ENOENT;
        }
@@ -304,7 +318,6 @@ static void virtnet_close ( struct net_device *netdev ) {
        struct virtnet_nic *virtnet = netdev->priv;
        struct io_buffer *iobuf;
        struct io_buffer *next_iobuf;
-       int i;
 
        if ( virtnet->virtio_version ) {
                vpm_reset ( &virtnet->vdev );
@@ -313,12 +326,7 @@ static void virtnet_close ( struct net_device *netdev ) {
        }
 
        /* Virtqueues can be freed now that NIC is reset */
-       for ( i = 0 ; i < QUEUE_NB ; i++ ) {
-               virtio_pci_unmap_capability ( &virtnet->virtqueue[i].notification );
-       }
-
-       free ( virtnet->virtqueue );
-       virtnet->virtqueue = NULL;
+       virtnet_free_virtqueues ( netdev );
 
        /* Free rx iobufs */
        list_for_each_entry_safe ( iobuf, next_iobuf, &virtnet->rx_iobufs, list ) {