From: Brendan King Brendan.King@imgtec.com
Free the memory used to hold the results of firmware image processing when the module is unloaded.
Fix the related issue of the same memory being leaked if processing of the firmware image fails during module load.
Ensure all firmware GEM objects are destroyed if firmware image processing fails.
Fixes memory leaks on powervr module unload detected by Kmemleak:
unreferenced object 0xffff000042e20000 (size 94208): comm "modprobe", pid 470, jiffies 4295277154 hex dump (first 32 bytes): 02 ae 7f ed bf 45 84 00 3c 5b 1f ed 9f 45 45 05 .....E..<[...EE. d5 4f 5d 14 6c 00 3d 23 30 d0 3a 4a 66 0e 48 c8 .O].l.=#0.:Jf.H. backtrace (crc dd329dec): kmemleak_alloc+0x30/0x40 ___kmalloc_large_node+0x140/0x188 __kmalloc_large_node_noprof+0x2c/0x13c __kmalloc_noprof+0x48/0x4c0 pvr_fw_init+0xaa4/0x1f50 [powervr]
unreferenced object 0xffff000042d20000 (size 20480): comm "modprobe", pid 470, jiffies 4295277154 hex dump (first 32 bytes): 00 00 00 00 00 00 00 00 09 00 00 00 0b 00 00 00 ................ 00 00 00 00 00 00 00 00 07 00 00 00 08 00 00 00 ................ backtrace (crc 395b02e3): kmemleak_alloc+0x30/0x40 ___kmalloc_large_node+0x140/0x188 __kmalloc_large_node_noprof+0x2c/0x13c __kmalloc_noprof+0x48/0x4c0 pvr_fw_init+0xb0c/0x1f50 [powervr]
Cc: stable@vger.kernel.org Fixes: cc1aeedb98ad ("drm/imagination: Implement firmware infrastructure and META FW support") Signed-off-by: Brendan King brendan.king@imgtec.com --- drivers/gpu/drm/imagination/pvr_fw.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/imagination/pvr_fw.c b/drivers/gpu/drm/imagination/pvr_fw.c index 3debc9870a82ae7de9b2dc173df84c466c137bb3..d09c4c68411627714c14dee5ed4e61b07baca1ba 100644 --- a/drivers/gpu/drm/imagination/pvr_fw.c +++ b/drivers/gpu/drm/imagination/pvr_fw.c @@ -732,7 +732,7 @@ pvr_fw_process(struct pvr_device *pvr_dev) fw_mem->core_data, fw_mem->core_code_alloc_size);
if (err) - goto err_free_fw_core_data_obj; + goto err_free_kdata;
memcpy(fw_code_ptr, fw_mem->code, fw_mem->code_alloc_size); memcpy(fw_data_ptr, fw_mem->data, fw_mem->data_alloc_size); @@ -742,10 +742,14 @@ pvr_fw_process(struct pvr_device *pvr_dev) memcpy(fw_core_data_ptr, fw_mem->core_data, fw_mem->core_data_alloc_size);
/* We're finished with the firmware section memory on the CPU, unmap. */ - if (fw_core_data_ptr) + if (fw_core_data_ptr) { pvr_fw_object_vunmap(fw_mem->core_data_obj); - if (fw_core_code_ptr) + fw_core_data_ptr = NULL; + } + if (fw_core_code_ptr) { pvr_fw_object_vunmap(fw_mem->core_code_obj); + fw_core_code_ptr = NULL; + } pvr_fw_object_vunmap(fw_mem->data_obj); fw_data_ptr = NULL; pvr_fw_object_vunmap(fw_mem->code_obj); @@ -753,7 +757,7 @@ pvr_fw_process(struct pvr_device *pvr_dev)
err = pvr_fw_create_fwif_connection_ctl(pvr_dev); if (err) - goto err_free_fw_core_data_obj; + goto err_free_kdata;
return 0;
@@ -763,13 +767,16 @@ pvr_fw_process(struct pvr_device *pvr_dev) kfree(fw_mem->data); kfree(fw_mem->code);
-err_free_fw_core_data_obj: if (fw_core_data_ptr) - pvr_fw_object_unmap_and_destroy(fw_mem->core_data_obj); + pvr_fw_object_vunmap(fw_mem->core_data_obj); + if (fw_mem->core_data_obj) + pvr_fw_object_destroy(fw_mem->core_data_obj);
err_free_fw_core_code_obj: if (fw_core_code_ptr) - pvr_fw_object_unmap_and_destroy(fw_mem->core_code_obj); + pvr_fw_object_vunmap(fw_mem->core_code_obj); + if (fw_mem->core_code_obj) + pvr_fw_object_destroy(fw_mem->core_code_obj);
err_free_fw_data_obj: if (fw_data_ptr) @@ -836,6 +843,12 @@ pvr_fw_cleanup(struct pvr_device *pvr_dev) struct pvr_fw_mem *fw_mem = &pvr_dev->fw_dev.mem;
pvr_fw_fini_fwif_connection_ctl(pvr_dev); + + kfree(fw_mem->core_data); + kfree(fw_mem->core_code); + kfree(fw_mem->data); + kfree(fw_mem->code); + if (fw_mem->core_code_obj) pvr_fw_object_destroy(fw_mem->core_code_obj); if (fw_mem->core_data_obj)
--- base-commit: 96c85e428ebaeacd2c640eba075479ab92072ccd change-id: 20250318-ddkopsrc-1339-firmware-related-memory-leak-on-module-unload-c18a9a4fd0db
Best regards,
On 18/03/2025 14:55, Brendan King via B4 Relay wrote:
From: Brendan King Brendan.King@imgtec.com
Free the memory used to hold the results of firmware image processing when the module is unloaded.
Fix the related issue of the same memory being leaked if processing of the firmware image fails during module load.
Ensure all firmware GEM objects are destroyed if firmware image processing fails.
Fixes memory leaks on powervr module unload detected by Kmemleak:
unreferenced object 0xffff000042e20000 (size 94208): comm "modprobe", pid 470, jiffies 4295277154 hex dump (first 32 bytes): 02 ae 7f ed bf 45 84 00 3c 5b 1f ed 9f 45 45 05 .....E..<[...EE. d5 4f 5d 14 6c 00 3d 23 30 d0 3a 4a 66 0e 48 c8 .O].l.=#0.:Jf.H. backtrace (crc dd329dec): kmemleak_alloc+0x30/0x40 ___kmalloc_large_node+0x140/0x188 __kmalloc_large_node_noprof+0x2c/0x13c __kmalloc_noprof+0x48/0x4c0 pvr_fw_init+0xaa4/0x1f50 [powervr]
unreferenced object 0xffff000042d20000 (size 20480): comm "modprobe", pid 470, jiffies 4295277154 hex dump (first 32 bytes): 00 00 00 00 00 00 00 00 09 00 00 00 0b 00 00 00 ................ 00 00 00 00 00 00 00 00 07 00 00 00 08 00 00 00 ................ backtrace (crc 395b02e3): kmemleak_alloc+0x30/0x40 ___kmalloc_large_node+0x140/0x188 __kmalloc_large_node_noprof+0x2c/0x13c __kmalloc_noprof+0x48/0x4c0 pvr_fw_init+0xb0c/0x1f50 [powervr]
Cc: stable@vger.kernel.org Fixes: cc1aeedb98ad ("drm/imagination: Implement firmware infrastructure and META FW support") Signed-off-by: Brendan King brendan.king@imgtec.com
Reviewed-by: Matt Coster matt.coster@imgtec.com
I'll apply this to drm-misc-fixes tomorrow if there are no objections.
drivers/gpu/drm/imagination/pvr_fw.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/imagination/pvr_fw.c b/drivers/gpu/drm/imagination/pvr_fw.c index 3debc9870a82ae7de9b2dc173df84c466c137bb3..d09c4c68411627714c14dee5ed4e61b07baca1ba 100644 --- a/drivers/gpu/drm/imagination/pvr_fw.c +++ b/drivers/gpu/drm/imagination/pvr_fw.c @@ -732,7 +732,7 @@ pvr_fw_process(struct pvr_device *pvr_dev) fw_mem->core_data, fw_mem->core_code_alloc_size); if (err)
goto err_free_fw_core_data_obj;
goto err_free_kdata;
memcpy(fw_code_ptr, fw_mem->code, fw_mem->code_alloc_size); memcpy(fw_data_ptr, fw_mem->data, fw_mem->data_alloc_size); @@ -742,10 +742,14 @@ pvr_fw_process(struct pvr_device *pvr_dev) memcpy(fw_core_data_ptr, fw_mem->core_data, fw_mem->core_data_alloc_size); /* We're finished with the firmware section memory on the CPU, unmap. */
- if (fw_core_data_ptr)
- if (fw_core_data_ptr) { pvr_fw_object_vunmap(fw_mem->core_data_obj);
- if (fw_core_code_ptr)
fw_core_data_ptr = NULL;
- }
- if (fw_core_code_ptr) { pvr_fw_object_vunmap(fw_mem->core_code_obj);
fw_core_code_ptr = NULL;
- } pvr_fw_object_vunmap(fw_mem->data_obj); fw_data_ptr = NULL; pvr_fw_object_vunmap(fw_mem->code_obj);
@@ -753,7 +757,7 @@ pvr_fw_process(struct pvr_device *pvr_dev) err = pvr_fw_create_fwif_connection_ctl(pvr_dev); if (err)
goto err_free_fw_core_data_obj;
goto err_free_kdata;
return 0; @@ -763,13 +767,16 @@ pvr_fw_process(struct pvr_device *pvr_dev) kfree(fw_mem->data); kfree(fw_mem->code); -err_free_fw_core_data_obj: if (fw_core_data_ptr)
pvr_fw_object_unmap_and_destroy(fw_mem->core_data_obj);
pvr_fw_object_vunmap(fw_mem->core_data_obj);
- if (fw_mem->core_data_obj)
pvr_fw_object_destroy(fw_mem->core_data_obj);
err_free_fw_core_code_obj: if (fw_core_code_ptr)
pvr_fw_object_unmap_and_destroy(fw_mem->core_code_obj);
pvr_fw_object_vunmap(fw_mem->core_code_obj);
- if (fw_mem->core_code_obj)
pvr_fw_object_destroy(fw_mem->core_code_obj);
err_free_fw_data_obj: if (fw_data_ptr) @@ -836,6 +843,12 @@ pvr_fw_cleanup(struct pvr_device *pvr_dev) struct pvr_fw_mem *fw_mem = &pvr_dev->fw_dev.mem; pvr_fw_fini_fwif_connection_ctl(pvr_dev);
- kfree(fw_mem->core_data);
- kfree(fw_mem->core_code);
- kfree(fw_mem->data);
- kfree(fw_mem->code);
- if (fw_mem->core_code_obj) pvr_fw_object_destroy(fw_mem->core_code_obj); if (fw_mem->core_data_obj)
base-commit: 96c85e428ebaeacd2c640eba075479ab92072ccd change-id: 20250318-ddkopsrc-1339-firmware-related-memory-leak-on-module-unload-c18a9a4fd0db
Best regards,
On Tue, 18 Mar 2025 14:55:55 +0000, Brendan King wrote:
Free the memory used to hold the results of firmware image processing when the module is unloaded.
Fix the related issue of the same memory being leaked if processing of the firmware image fails during module load.
Ensure all firmware GEM objects are destroyed if firmware image processing fails.
[...]
Applied, thanks!
[1/1] drm/imagination: fix firmware memory leaks commit: a5b230e7f3a55bd8bd8d012eec75a4b7baa671d5
Best regards,
linux-stable-mirror@lists.linaro.org