aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/virtio/virtio_pci.c
diff options
context:
space:
mode:
authorMichael S. Tsirkin <mst@redhat.com>2009-07-23 07:57:37 -0400
committerRusty Russell <rusty@rustcorp.com.au>2009-07-30 02:33:44 -0400
commitff52c3fc7188855ede75d87b022271f0da309e5b (patch)
treee10333755598cfbee6676f75dd87168ecdf2d5ce /drivers/virtio/virtio_pci.c
parent8ef562d112c82ec539775698f8b63ac5ec1bd766 (diff)
virtio: fix memory leak on device removal
Make vp_free_vectors do the reverse of vq_request_vectors. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'drivers/virtio/virtio_pci.c')
-rw-r--r--drivers/virtio/virtio_pci.c28
1 files changed, 15 insertions, 13 deletions
diff --git a/drivers/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c
index bcec78ffc765..ca40517ef9c2 100644
--- a/drivers/virtio/virtio_pci.c
+++ b/drivers/virtio/virtio_pci.c
@@ -258,7 +258,6 @@ static void vp_free_vectors(struct virtio_device *vdev)
258 258
259 for (i = 0; i < vp_dev->msix_used_vectors; ++i) 259 for (i = 0; i < vp_dev->msix_used_vectors; ++i)
260 free_irq(vp_dev->msix_entries[i].vector, vp_dev); 260 free_irq(vp_dev->msix_entries[i].vector, vp_dev);
261 vp_dev->msix_used_vectors = 0;
262 261
263 if (vp_dev->msix_enabled) { 262 if (vp_dev->msix_enabled) {
264 /* Disable the vector used for configuration */ 263 /* Disable the vector used for configuration */
@@ -267,9 +266,16 @@ static void vp_free_vectors(struct virtio_device *vdev)
267 /* Flush the write out to device */ 266 /* Flush the write out to device */
268 ioread16(vp_dev->ioaddr + VIRTIO_MSI_CONFIG_VECTOR); 267 ioread16(vp_dev->ioaddr + VIRTIO_MSI_CONFIG_VECTOR);
269 268
270 vp_dev->msix_enabled = 0;
271 pci_disable_msix(vp_dev->pci_dev); 269 pci_disable_msix(vp_dev->pci_dev);
270 vp_dev->msix_enabled = 0;
271 vp_dev->msix_vectors = 0;
272 } 272 }
273
274 vp_dev->msix_used_vectors = 0;
275 kfree(vp_dev->msix_names);
276 vp_dev->msix_names = NULL;
277 kfree(vp_dev->msix_entries);
278 vp_dev->msix_entries = NULL;
273} 279}
274 280
275static int vp_enable_msix(struct pci_dev *dev, struct msix_entry *entries, 281static int vp_enable_msix(struct pci_dev *dev, struct msix_entry *entries,
@@ -297,11 +303,11 @@ static int vp_request_vectors(struct virtio_device *vdev, unsigned max_vqs)
297 vp_dev->msix_entries = kmalloc(nvectors * sizeof *vp_dev->msix_entries, 303 vp_dev->msix_entries = kmalloc(nvectors * sizeof *vp_dev->msix_entries,
298 GFP_KERNEL); 304 GFP_KERNEL);
299 if (!vp_dev->msix_entries) 305 if (!vp_dev->msix_entries)
300 goto error_entries; 306 goto error;
301 vp_dev->msix_names = kmalloc(nvectors * sizeof *vp_dev->msix_names, 307 vp_dev->msix_names = kmalloc(nvectors * sizeof *vp_dev->msix_names,
302 GFP_KERNEL); 308 GFP_KERNEL);
303 if (!vp_dev->msix_names) 309 if (!vp_dev->msix_names)
304 goto error_names; 310 goto error;
305 311
306 for (i = 0; i < nvectors; ++i) 312 for (i = 0; i < nvectors; ++i)
307 vp_dev->msix_entries[i].entry = i; 313 vp_dev->msix_entries[i].entry = i;
@@ -314,7 +320,7 @@ static int vp_request_vectors(struct virtio_device *vdev, unsigned max_vqs)
314 err = request_irq(vp_dev->pci_dev->irq, vp_interrupt, 320 err = request_irq(vp_dev->pci_dev->irq, vp_interrupt,
315 IRQF_SHARED, name, vp_dev); 321 IRQF_SHARED, name, vp_dev);
316 if (err) 322 if (err)
317 goto error_irq; 323 goto error;
318 vp_dev->intx_enabled = 1; 324 vp_dev->intx_enabled = 1;
319 } else { 325 } else {
320 vp_dev->msix_vectors = err; 326 vp_dev->msix_vectors = err;
@@ -328,7 +334,7 @@ static int vp_request_vectors(struct virtio_device *vdev, unsigned max_vqs)
328 vp_config_changed, 0, vp_dev->msix_names[v], 334 vp_config_changed, 0, vp_dev->msix_names[v],
329 vp_dev); 335 vp_dev);
330 if (err) 336 if (err)
331 goto error_irq; 337 goto error;
332 ++vp_dev->msix_used_vectors; 338 ++vp_dev->msix_used_vectors;
333 339
334 iowrite16(v, vp_dev->ioaddr + VIRTIO_MSI_CONFIG_VECTOR); 340 iowrite16(v, vp_dev->ioaddr + VIRTIO_MSI_CONFIG_VECTOR);
@@ -336,7 +342,7 @@ static int vp_request_vectors(struct virtio_device *vdev, unsigned max_vqs)
336 v = ioread16(vp_dev->ioaddr + VIRTIO_MSI_CONFIG_VECTOR); 342 v = ioread16(vp_dev->ioaddr + VIRTIO_MSI_CONFIG_VECTOR);
337 if (v == VIRTIO_MSI_NO_VECTOR) { 343 if (v == VIRTIO_MSI_NO_VECTOR) {
338 err = -EBUSY; 344 err = -EBUSY;
339 goto error_irq; 345 goto error;
340 } 346 }
341 } 347 }
342 348
@@ -349,16 +355,12 @@ static int vp_request_vectors(struct virtio_device *vdev, unsigned max_vqs)
349 vp_vring_interrupt, 0, vp_dev->msix_names[v], 355 vp_vring_interrupt, 0, vp_dev->msix_names[v],
350 vp_dev); 356 vp_dev);
351 if (err) 357 if (err)
352 goto error_irq; 358 goto error;
353 ++vp_dev->msix_used_vectors; 359 ++vp_dev->msix_used_vectors;
354 } 360 }
355 return 0; 361 return 0;
356error_irq: 362error:
357 vp_free_vectors(vdev); 363 vp_free_vectors(vdev);
358 kfree(vp_dev->msix_names);
359error_names:
360 kfree(vp_dev->msix_entries);
361error_entries:
362 return err; 364 return err;
363} 365}
364 366