From 9614251dcd1ddd10d7c646b1131243531e817e1d Mon Sep 17 00:00:00 2001 From: Kamal Agrawal Date: Mon, 8 Feb 2021 10:03:28 +0530 Subject: [PATCH] msm: kgsl: Remove sysfs entries after releasing memory Consider a scenario when device is in OOM situation. Assume a process is doing sysfs operation, grabs kernfs_mutex and wants to allocate memory. LMKD tries to kill processes but kgsl processes will be blocked waiting for kernfs_mutex in sysfs_remove_file. kgsl_process_private_close > kgsl_process_uninit_sysfs > sysfs_remove_file KGSL won't free up memory as it is done after sysfs removal leading to a livelock. Fix it by releasing memory before removing sysfs entries. Change-Id: I99640d7a653faffa671d5b035abb78e9473da12e Signed-off-by: Kamal Agrawal --- drivers/gpu/msm/kgsl.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index 38b238639e16..b02eb6110e64 100644 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -983,11 +983,14 @@ static void kgsl_process_private_close(struct kgsl_device_private *dev_priv, * directories and garbage collect any outstanding resources */ - kgsl_process_uninit_sysfs(private); + process_release_memory(private); /* Release all syncsource objects from process private */ kgsl_syncsource_process_release_syncsources(private); + debugfs_remove_recursive(private->debug_root); + kgsl_process_uninit_sysfs(private); + /* When using global pagetables, do not detach global pagetable */ if (private->pagetable->name != KGSL_MMU_GLOBAL_PT) kgsl_mmu_detach_pagetable(private->pagetable); @@ -997,15 +1000,8 @@ static void kgsl_process_private_close(struct kgsl_device_private *dev_priv, list_del(&private->list); write_unlock(&kgsl_driver.proclist_lock); - debugfs_remove_recursive(private->debug_root); - - /* - * Unlock the mutex before releasing the memory - this prevents a - * deadlock with the IOMMU mutex if a page fault occurs. - */ mutex_unlock(&kgsl_driver.process_mutex); - process_release_memory(private); kgsl_process_private_put(private); }