summaryrefslogtreecommitdiff
path: root/mali_kbase/mali_kbase_mem.c
diff options
context:
space:
mode:
authorKevin Park <Youngeun.Park@arm.com>2023-12-08 17:01:50 +0000
committerRenato Grottesi <otaner@google.com>2023-12-11 12:57:25 +0000
commit2226bae46b7a606e97a9ced0e91d7209cd04758c (patch)
treec5d287e0fd9699c37b4c42a40ece494c848f5b5a /mali_kbase/mali_kbase_mem.c
parentcab5dbbee97ee9e3baa41d00372363a2f53196e0 (diff)
downloadgpu-2226bae46b7a606e97a9ced0e91d7209cd04758c.tar.gz
Fix deadlock BTW user thread and page fault worker
MIDCET-4882,GPUCORE-40989 Break deadlock BTW user thread and page fault worker This commit adds a RW semaphore 1> to prevent MMU operations during P.Mode entrance and 2> to break the deadlock on 'kctx reg_lock' between user thread and page-fault worker thread. Bug: 301064831 Signed-off-by: Renato Grottesi <otaner@google.com> Test: manual run of the use case from the ticket Provenance: https://code.ipdelivery.arm.com/c/GPU/mali-ddk/+/6221 Change-Id: I692f8fafc558a6a45b5ca4210aa3f66c2617553f
Diffstat (limited to 'mali_kbase/mali_kbase_mem.c')
-rw-r--r--mali_kbase/mali_kbase_mem.c37
1 files changed, 25 insertions, 12 deletions
diff --git a/mali_kbase/mali_kbase_mem.c b/mali_kbase/mali_kbase_mem.c
index c07d520..9de0893 100644
--- a/mali_kbase/mali_kbase_mem.c
+++ b/mali_kbase/mali_kbase_mem.c
@@ -2293,7 +2293,7 @@ int kbase_mem_free(struct kbase_context *kctx, u64 gpu_addr)
__func__);
return -EINVAL;
}
- kbase_gpu_vm_lock(kctx);
+ kbase_gpu_vm_lock_with_pmode_sync(kctx);
if (gpu_addr >= BASE_MEM_COOKIE_BASE &&
gpu_addr < BASE_MEM_FIRST_FREE_ADDRESS) {
@@ -2333,7 +2333,7 @@ int kbase_mem_free(struct kbase_context *kctx, u64 gpu_addr)
}
out_unlock:
- kbase_gpu_vm_unlock(kctx);
+ kbase_gpu_vm_unlock_with_pmode_sync(kctx);
return err;
}
@@ -3478,17 +3478,31 @@ void kbase_gpu_vm_lock(struct kbase_context *kctx)
KBASE_DEBUG_ASSERT(kctx != NULL);
mutex_lock(&kctx->reg_lock);
}
-
KBASE_EXPORT_TEST_API(kbase_gpu_vm_lock);
+void kbase_gpu_vm_lock_with_pmode_sync(struct kbase_context *kctx)
+{
+#if MALI_USE_CSF
+ down_read(&kctx->kbdev->csf.pmode_sync_sem);
+#endif
+ kbase_gpu_vm_lock(kctx);
+}
+
void kbase_gpu_vm_unlock(struct kbase_context *kctx)
{
KBASE_DEBUG_ASSERT(kctx != NULL);
mutex_unlock(&kctx->reg_lock);
}
-
KBASE_EXPORT_TEST_API(kbase_gpu_vm_unlock);
+void kbase_gpu_vm_unlock_with_pmode_sync(struct kbase_context *kctx)
+{
+ kbase_gpu_vm_unlock(kctx);
+#if MALI_USE_CSF
+ up_read(&kctx->kbdev->csf.pmode_sync_sem);
+#endif
+}
+
#if IS_ENABLED(CONFIG_DEBUG_FS)
struct kbase_jit_debugfs_data {
int (*func)(struct kbase_jit_debugfs_data *data);
@@ -4360,7 +4374,7 @@ struct kbase_va_region *kbase_jit_allocate(struct kbase_context *kctx,
}
}
- kbase_gpu_vm_lock(kctx);
+ kbase_gpu_vm_lock_with_pmode_sync(kctx);
mutex_lock(&kctx->jit_evict_lock);
/*
@@ -4442,7 +4456,7 @@ struct kbase_va_region *kbase_jit_allocate(struct kbase_context *kctx,
kbase_jit_done_phys_increase(kctx, needed_pages);
#endif /* MALI_JIT_PRESSURE_LIMIT_BASE */
- kbase_gpu_vm_unlock(kctx);
+ kbase_gpu_vm_unlock_with_pmode_sync(kctx);
if (ret < 0) {
/*
@@ -4507,7 +4521,7 @@ struct kbase_va_region *kbase_jit_allocate(struct kbase_context *kctx,
#endif /* MALI_JIT_PRESSURE_LIMIT_BASE */
mutex_unlock(&kctx->jit_evict_lock);
- kbase_gpu_vm_unlock(kctx);
+ kbase_gpu_vm_unlock_with_pmode_sync(kctx);
reg = kbase_mem_alloc(kctx, info->va_pages, info->commit_pages, info->extension,
&flags, &gpu_addr, mmu_sync_info);
@@ -4609,9 +4623,9 @@ void kbase_jit_free(struct kbase_context *kctx, struct kbase_va_region *reg)
u64 delta = old_pages - new_size;
if (delta) {
- mutex_lock(&kctx->reg_lock);
+ kbase_gpu_vm_lock_with_pmode_sync(kctx);
kbase_mem_shrink(kctx, reg, old_pages - delta);
- mutex_unlock(&kctx->reg_lock);
+ kbase_gpu_vm_unlock_with_pmode_sync(kctx);
}
}
@@ -4718,8 +4732,7 @@ void kbase_jit_term(struct kbase_context *kctx)
struct kbase_va_region *walker;
/* Free all allocations for this context */
-
- kbase_gpu_vm_lock(kctx);
+ kbase_gpu_vm_lock_with_pmode_sync(kctx);
mutex_lock(&kctx->jit_evict_lock);
/* Free all allocations from the pool */
while (!list_empty(&kctx->jit_pool_head)) {
@@ -4762,7 +4775,7 @@ void kbase_jit_term(struct kbase_context *kctx)
WARN_ON(kctx->jit_phys_pages_to_be_allocated);
#endif
mutex_unlock(&kctx->jit_evict_lock);
- kbase_gpu_vm_unlock(kctx);
+ kbase_gpu_vm_unlock_with_pmode_sync(kctx);
/*
* Flush the freeing of allocations whose backing has been freed