Browse Source

[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 7 years ago
parent
commit
b782a56be7
2 changed files with 20 additions and 19 deletions
  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 View File

391
             off * notify_offset_multiplier, 2,
391
             off * notify_offset_multiplier, 2,
392
             &vq->notification);
392
             &vq->notification);
393
         if (err) {
393
         if (err) {
394
-            goto err_map_notify;
394
+            return err;
395
         }
395
         }
396
     }
396
     }
397
 
397
 
405
         vpm_iowrite16(vdev, &vdev->common, 1, COMMON_OFFSET(queue_enable));
405
         vpm_iowrite16(vdev, &vdev->common, 1, COMMON_OFFSET(queue_enable));
406
     }
406
     }
407
     return 0;
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 View File

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
 /** Open network device, legacy virtio 0.9.5
194
 /** Open network device, legacy virtio 0.9.5
179
  *
195
  *
180
  * @v netdev	Network device
196
  * @v netdev	Network device
200
 		if ( vp_find_vq ( ioaddr, i, &virtnet->virtqueue[i] ) == -1 ) {
216
 		if ( vp_find_vq ( ioaddr, i, &virtnet->virtqueue[i] ) == -1 ) {
201
 			DBGC ( virtnet, "VIRTIO-NET %p cannot register queue %d\n",
217
 			DBGC ( virtnet, "VIRTIO-NET %p cannot register queue %d\n",
202
 			       virtnet, i );
218
 			       virtnet, i );
203
-			free ( virtnet->virtqueue );
204
-			virtnet->virtqueue = NULL;
219
+			virtnet_free_virtqueues ( netdev );
205
 			return -ENOENT;
220
 			return -ENOENT;
206
 		}
221
 		}
207
 	}
222
 	}
263
 	if ( vpm_find_vqs ( &virtnet->vdev, QUEUE_NB, virtnet->virtqueue ) ) {
278
 	if ( vpm_find_vqs ( &virtnet->vdev, QUEUE_NB, virtnet->virtqueue ) ) {
264
 		DBGC ( virtnet, "VIRTIO-NET %p cannot register queues\n",
279
 		DBGC ( virtnet, "VIRTIO-NET %p cannot register queues\n",
265
 		       virtnet );
280
 		       virtnet );
266
-		free ( virtnet->virtqueue );
267
-		virtnet->virtqueue = NULL;
281
+		virtnet_free_virtqueues ( netdev );
268
 		vpm_add_status ( &virtnet->vdev, VIRTIO_CONFIG_S_FAILED );
282
 		vpm_add_status ( &virtnet->vdev, VIRTIO_CONFIG_S_FAILED );
269
 		return -ENOENT;
283
 		return -ENOENT;
270
 	}
284
 	}
304
 	struct virtnet_nic *virtnet = netdev->priv;
318
 	struct virtnet_nic *virtnet = netdev->priv;
305
 	struct io_buffer *iobuf;
319
 	struct io_buffer *iobuf;
306
 	struct io_buffer *next_iobuf;
320
 	struct io_buffer *next_iobuf;
307
-	int i;
308
 
321
 
309
 	if ( virtnet->virtio_version ) {
322
 	if ( virtnet->virtio_version ) {
310
 		vpm_reset ( &virtnet->vdev );
323
 		vpm_reset ( &virtnet->vdev );
313
 	}
326
 	}
314
 
327
 
315
 	/* Virtqueues can be freed now that NIC is reset */
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
 	/* Free rx iobufs */
331
 	/* Free rx iobufs */
324
 	list_for_each_entry_safe ( iobuf, next_iobuf, &virtnet->rx_iobufs, list ) {
332
 	list_for_each_entry_safe ( iobuf, next_iobuf, &virtnet->rx_iobufs, list ) {

Loading…
Cancel
Save