[libvirt] [PATCH v2 3/3] nodedev: fix pci express memory leak

Eric Blake eblake at redhat.com
Thu Jul 24 03:06:08 UTC 2014


Leak introduced in commit 16ebf10f (v1.2.6), detected by valgrind:

==9816== 216 (96 direct, 120 indirect) bytes in 6 blocks are definitely lost in loss record 665 of 821
==9816==    at 0x4A081D4: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==9816==    by 0x50836FB: virAlloc (viralloc.c:144)
==9816==    by 0x1DBDBE27: udevProcessPCI (node_device_udev.c:546)
==9816==    by 0x1DBDD79D: udevGetDeviceDetails (node_device_udev.c:1293)

* src/util/virpci.h (virPCIEDeviceInfoFree): New prototype.
* src/util/virpci.c (virPCIEDeviceInfoFree): New function.
* src/conf/node_device_conf.c (virNodeDevCapsDefFree): Clear
pci_express under pci case.
(virNodeDevCapPCIDevParseXML): Avoid leak.
* src/node_device/node_device_udev.c (udevProcessPCI): Likewise.
* src/libvirt_private.syms (virpci.h): Export it.

Signed-off-by: Eric Blake <eblake at redhat.com>
---
 src/conf/node_device_conf.c        |  3 ++-
 src/libvirt_private.syms           |  1 +
 src/node_device/node_device_udev.c |  2 +-
 src/util/virpci.c                  | 12 ++++++++++++
 src/util/virpci.h                  |  3 +++
 5 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c
index b244a1f..78bc63f 100644
--- a/src/conf/node_device_conf.c
+++ b/src/conf/node_device_conf.c
@@ -1291,7 +1291,7 @@ virNodeDevCapPCIDevParseXML(xmlXPathContextPtr ctxt,

     ret = 0;
  out:
-    VIR_FREE(pci_express);
+    virPCIEDeviceInfoFree(pci_express);
     ctxt->node = orignode;
     return ret;
 }
@@ -1664,6 +1664,7 @@ void virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps)
             VIR_FREE(data->pci_dev.iommuGroupDevices[i]);
         }
         VIR_FREE(data->pci_dev.iommuGroupDevices);
+        virPCIEDeviceInfoFree(data->pci_dev.pci_express);
         break;
     case VIR_NODE_DEV_CAP_USB_DEV:
         VIR_FREE(data->usb_dev.product_name);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 51504d1..fe02f9c 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1753,6 +1753,7 @@ virPCIDeviceSetUnbindFromStub;
 virPCIDeviceSetUsedBy;
 virPCIDeviceUnbind;
 virPCIDeviceWaitForCleanup;
+virPCIEDeviceInfoFree;
 virPCIGetNetName;
 virPCIGetPhysicalFunction;
 virPCIGetVirtualFunctionIndex;
diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c
index 28d2953..0fe474d 100644
--- a/src/node_device/node_device_udev.c
+++ b/src/node_device/node_device_udev.c
@@ -570,7 +570,7 @@ static int udevProcessPCI(struct udev_device *device,

  out:
     virPCIDeviceFree(pciDev);
-    VIR_FREE(pci_express);
+    virPCIEDeviceInfoFree(pci_express);
     return ret;
 }

diff --git a/src/util/virpci.c b/src/util/virpci.c
index b7400e9..0098d6c 100644
--- a/src/util/virpci.c
+++ b/src/util/virpci.c
@@ -2847,3 +2847,15 @@ virPCIDeviceGetLinkCapSta(virPCIDevicePtr dev,
     virPCIDeviceConfigClose(dev, fd);
     return ret;
 }
+
+
+void
+virPCIEDeviceInfoFree(virPCIEDeviceInfoPtr dev)
+{
+    if (!dev)
+        return;
+
+    VIR_FREE(dev->link_cap);
+    VIR_FREE(dev->link_sta);
+    VIR_FREE(dev);
+}
diff --git a/src/util/virpci.h b/src/util/virpci.h
index edec439..3da8eb3 100644
--- a/src/util/virpci.h
+++ b/src/util/virpci.h
@@ -212,4 +212,7 @@ int virPCIDeviceGetLinkCapSta(virPCIDevicePtr dev,
                               unsigned int *cap_width,
                               unsigned int *sta_speed,
                               unsigned int *sta_width);
+
+void virPCIEDeviceInfoFree(virPCIEDeviceInfoPtr dev);
+
 #endif /* __VIR_PCI_H__ */
-- 
1.9.3




More information about the libvir-list mailing list