From e021311a153c462c3b804a186e29f61ba657d44c Mon Sep 17 00:00:00 2001 From: Wen Congyang Date: Fri, 7 Sep 2012 10:17:48 +1000 Subject: [PATCH] acpi_memhotplug.c: fix memory leak when memory device is unbound from the module acpi_memhotplug We allocate memory to store acpi_memory_info, so we should free it before freeing mem_device. Signed-off-by: Wen Congyang Cc: Len Brown Cc: "Brown, Len" Cc: Yasuaki ISIMATU Cc: David Rientjes Cc: Konrad Rzeszutek Wilk Signed-off-by: Andrew Morton --- drivers/acpi/acpi_memhotplug.c | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c index 24c807f96636..62c2c74b5d9a 100644 --- a/drivers/acpi/acpi_memhotplug.c +++ b/drivers/acpi/acpi_memhotplug.c @@ -125,12 +125,20 @@ acpi_memory_get_resource(struct acpi_resource *resource, void *context) return AE_OK; } +static void +acpi_memory_free_device_resources(struct acpi_memory_device *mem_device) +{ + struct acpi_memory_info *info, *n; + + list_for_each_entry_safe(info, n, &mem_device->res_list, list) + kfree(info); + INIT_LIST_HEAD(&mem_device->res_list); +} + static int acpi_memory_get_device_resources(struct acpi_memory_device *mem_device) { acpi_status status; - struct acpi_memory_info *info, *n; - if (!list_empty(&mem_device->res_list)) return 0; @@ -138,9 +146,7 @@ acpi_memory_get_device_resources(struct acpi_memory_device *mem_device) status = acpi_walk_resources(mem_device->device->handle, METHOD_NAME__CRS, acpi_memory_get_resource, mem_device); if (ACPI_FAILURE(status)) { - list_for_each_entry_safe(info, n, &mem_device->res_list, list) - kfree(info); - INIT_LIST_HEAD(&mem_device->res_list); + acpi_memory_free_device_resources(mem_device); return -EINVAL; } @@ -420,6 +426,15 @@ static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data) return; } +static void acpi_memory_device_free(struct acpi_memory_device *mem_device) +{ + if (!mem_device) + return; + + acpi_memory_free_device_resources(mem_device); + kfree(mem_device); +} + static int acpi_memory_device_add(struct acpi_device *device) { int result; @@ -472,14 +487,10 @@ static int acpi_memory_device_add(struct acpi_device *device) static int acpi_memory_device_remove(struct acpi_device *device, int type) { - struct acpi_memory_device *mem_device = NULL; - - if (!device || !acpi_driver_data(device)) return -EINVAL; - mem_device = acpi_driver_data(device); - kfree(mem_device); + acpi_memory_device_free(acpi_driver_data(device)); return 0; } -- 2.39.5