Просмотр исходного кода

[virtio] Simplify virtqueue shutdown

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>
tags/v1.20.1
Ladi Prosek 8 лет назад
Родитель
Сommit
b782a56be7
2 измененных файлов: 20 добавлений и 19 удалений
  1. 1
    8
      src/drivers/bus/virtio-pci.c
  2. 19
    11
      src/drivers/net/virtio-net.c

+ 1
- 8
src/drivers/bus/virtio-pci.c Просмотреть файл

@@ -391,7 +391,7 @@ int vpm_find_vqs(struct virtio_pci_modern_device *vdev,
391 391
             off * notify_offset_multiplier, 2,
392 392
             &vq->notification);
393 393
         if (err) {
394
-            goto err_map_notify;
394
+            return err;
395 395
         }
396 396
     }
397 397
 
@@ -405,11 +405,4 @@ int vpm_find_vqs(struct virtio_pci_modern_device *vdev,
405 405
         vpm_iowrite16(vdev, &vdev->common, 1, COMMON_OFFSET(queue_enable));
406 406
     }
407 407
     return 0;
408
-
409
-err_map_notify:
410
-    /* Undo the virtio_pci_map_capability calls. */
411
-    while (i-- > 0) {
412
-        virtio_pci_unmap_capability(&vqs[i].notification);
413
-    }
414
-    return err;
415 408
 }

+ 19
- 11
src/drivers/net/virtio-net.c Просмотреть файл

@@ -175,6 +175,22 @@ static void virtnet_refill_rx_virtqueue ( struct net_device *netdev ) {
175 175
 	}
176 176
 }
177 177
 
178
+/** Helper to free all virtqueue memory
179
+ *
180
+ * @v netdev		Network device
181
+ */
182
+static void virtnet_free_virtqueues ( struct net_device *netdev ) {
183
+	struct virtnet_nic *virtnet = netdev->priv;
184
+	int i;
185
+
186
+	for ( i = 0; i < QUEUE_NB; i++ ) {
187
+		virtio_pci_unmap_capability ( &virtnet->virtqueue[i].notification );
188
+	}
189
+
190
+	free ( virtnet->virtqueue );
191
+	virtnet->virtqueue = NULL;
192
+}
193
+
178 194
 /** Open network device, legacy virtio 0.9.5
179 195
  *
180 196
  * @v netdev	Network device
@@ -200,8 +216,7 @@ static int virtnet_open_legacy ( struct net_device *netdev ) {
200 216
 		if ( vp_find_vq ( ioaddr, i, &virtnet->virtqueue[i] ) == -1 ) {
201 217
 			DBGC ( virtnet, "VIRTIO-NET %p cannot register queue %d\n",
202 218
 			       virtnet, i );
203
-			free ( virtnet->virtqueue );
204
-			virtnet->virtqueue = NULL;
219
+			virtnet_free_virtqueues ( netdev );
205 220
 			return -ENOENT;
206 221
 		}
207 222
 	}
@@ -263,8 +278,7 @@ static int virtnet_open_modern ( struct net_device *netdev ) {
263 278
 	if ( vpm_find_vqs ( &virtnet->vdev, QUEUE_NB, virtnet->virtqueue ) ) {
264 279
 		DBGC ( virtnet, "VIRTIO-NET %p cannot register queues\n",
265 280
 		       virtnet );
266
-		free ( virtnet->virtqueue );
267
-		virtnet->virtqueue = NULL;
281
+		virtnet_free_virtqueues ( netdev );
268 282
 		vpm_add_status ( &virtnet->vdev, VIRTIO_CONFIG_S_FAILED );
269 283
 		return -ENOENT;
270 284
 	}
@@ -304,7 +318,6 @@ static void virtnet_close ( struct net_device *netdev ) {
304 318
 	struct virtnet_nic *virtnet = netdev->priv;
305 319
 	struct io_buffer *iobuf;
306 320
 	struct io_buffer *next_iobuf;
307
-	int i;
308 321
 
309 322
 	if ( virtnet->virtio_version ) {
310 323
 		vpm_reset ( &virtnet->vdev );
@@ -313,12 +326,7 @@ static void virtnet_close ( struct net_device *netdev ) {
313 326
 	}
314 327
 
315 328
 	/* Virtqueues can be freed now that NIC is reset */
316
-	for ( i = 0 ; i < QUEUE_NB ; i++ ) {
317
-		virtio_pci_unmap_capability ( &virtnet->virtqueue[i].notification );
318
-	}
319
-
320
-	free ( virtnet->virtqueue );
321
-	virtnet->virtqueue = NULL;
329
+	virtnet_free_virtqueues ( netdev );
322 330
 
323 331
 	/* Free rx iobufs */
324 332
 	list_for_each_entry_safe ( iobuf, next_iobuf, &virtnet->rx_iobufs, list ) {

Загрузка…
Отмена
Сохранить