Summary: DRM: Fix memory leaks in PCI consistent memory handling Recent changes to PCI consistent memory management introduced memory leaks: drm_pci_alloc() was allocating a drm_dma_handle_t structure, but drm_pci_free() was not freeing it. This patch fixes these leaks. Signed-off-by: Sergey Vlasov --- drm/linux-core/drm_pci.c.alt-drm_pci-leaks 2005-05-21 19:10:39 +0400 +++ drm/linux-core/drm_pci.c 2005-05-21 20:03:17 +0400 @@ -122,10 +122,12 @@ drm_dma_handle_t *drm_pci_alloc(drm_devi EXPORT_SYMBOL(drm_pci_alloc); /** - * \brief Free a PCI consistent memory block. + * \brief Free a PCI consistent memory block without freeing its descriptor. + * + * This function is for internal use in the Linux-specific DRM core code. */ void -drm_pci_free(drm_device_t * dev, drm_dma_handle_t *dmah) +__drm_pci_free(drm_device_t * dev, drm_dma_handle_t *dmah) { #if 0 unsigned long addr; @@ -169,6 +171,16 @@ drm_pci_free(drm_device_t * dev, drm_dma #endif } + +/** + * \brief Free a PCI consistent memory block. + */ +void +drm_pci_free(drm_device_t * dev, drm_dma_handle_t *dmah) +{ + __drm_pci_free(dev, dmah); + kfree(dmah); +} EXPORT_SYMBOL(drm_pci_free); /*@}*/ --- drm/linux-core/drm_vm.c.alt-drm_pci-leaks 2005-05-21 17:19:49 +0400 +++ drm/linux-core/drm_vm.c 2005-05-21 20:08:10 +0400 @@ -242,7 +242,7 @@ void drm_vm_shm_close(struct vm_area_str dmah.vaddr = map->handle; dmah.busaddr = map->offset; dmah.size = map->size; - drm_pci_free(dev, &dmah); + __drm_pci_free(dev, &dmah); break; } drm_free(map, sizeof(*map), DRM_MEM_MAPS); --- drm/linux-core/drm_bufs.c.alt-drm_pci-leaks 2005-05-21 17:19:49 +0400 +++ drm/linux-core/drm_bufs.c 2005-05-21 20:06:57 +0400 @@ -269,6 +269,7 @@ int drm_addmap(struct inode *inode, stru } map->handle = dmah->vaddr; map->offset = (unsigned long)dmah->busaddr; + kfree(dmah); break; } default: @@ -380,7 +381,7 @@ int drm_rmmap(struct inode *inode, struc dmah.vaddr = map->handle; dmah.busaddr = map->offset; dmah.size = map->size; - drm_pci_free(dev, &dmah); + __drm_pci_free(dev, &dmah); break; } drm_free(map, sizeof(*map), DRM_MEM_MAPS); --- drm/linux-core/drm_drv.c.alt-drm_pci-leaks 2005-05-21 17:19:49 +0400 +++ drm/linux-core/drm_drv.c 2005-05-21 20:07:47 +0400 @@ -235,7 +235,7 @@ int drm_takedown(drm_device_t * dev) dmah.vaddr = map->handle; dmah.busaddr = map->offset; dmah.size = map->size; - drm_pci_free(dev, &dmah); + __drm_pci_free(dev, &dmah); break; } drm_free(map, sizeof(*map), DRM_MEM_MAPS); --- drm/linux-core/drmP.h.alt-drm_pci-leaks 2005-05-21 17:19:49 +0400 +++ drm/linux-core/drmP.h 2005-05-21 20:03:17 +0400 @@ -967,6 +967,7 @@ extern int drm_ati_pcigart_cleanup(drm_d extern drm_dma_handle_t *drm_pci_alloc(drm_device_t * dev, size_t size, size_t align, dma_addr_t maxaddr); +extern void __drm_pci_free(drm_device_t * dev, drm_dma_handle_t *dmah); extern void drm_pci_free(drm_device_t * dev, drm_dma_handle_t *dmah); /* sysfs support (drm_sysfs.c) */