summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd Frederick <tfred@google.com>2023-08-12 21:02:15 +0000
committerTodd Frederick <tfred@google.com>2023-08-13 20:42:16 +0000
commiteaa359f757545f9f1624b46e981954bdc910d71e (patch)
tree31c7a31fcb96ff1e935640c404e0db5089c3d35e
parent21e02ada5775657df72ba99e93c7fe57421eb228 (diff)
downloadexynos-android-exynos-r11-4.19-rvc-wear-jr3-qpr2-dr.tar.gz
Bug: 294574473 Bug: 295041809 Change-Id: I26f71a29059a689e80de6a895bf3e5d83e77f5fd Signed-off-by: Todd Frederick <tfred@google.com>
-rw-r--r--drivers/gpu/arm/t72x/r29p0/mali_kbase_context.c32
-rw-r--r--drivers/gpu/arm/t72x/r29p0/mali_kbase_defs.h15
-rw-r--r--drivers/gpu/arm/t72x/r29p0/mali_kbase_mem_linux.c65
3 files changed, 33 insertions, 79 deletions
diff --git a/drivers/gpu/arm/t72x/r29p0/mali_kbase_context.c b/drivers/gpu/arm/t72x/r29p0/mali_kbase_context.c
index 195914a8cf99..b51922179b0e 100644
--- a/drivers/gpu/arm/t72x/r29p0/mali_kbase_context.c
+++ b/drivers/gpu/arm/t72x/r29p0/mali_kbase_context.c
@@ -72,22 +72,28 @@ kbase_create_context(struct kbase_device *kbdev, bool is_compat,
atomic_set(&kctx->setup_complete, 0);
atomic_set(&kctx->setup_in_progress, 0);
- spin_lock_init(&kctx->mm_update_lock);
kctx->process_mm = NULL;
atomic_set(&kctx->nonmapped_pages, 0);
kctx->slots_pullable = 0;
kctx->tgid = current->tgid;
kctx->pid = current->pid;
-
- rcu_read_lock();
- pid_struct = find_get_pid(kctx->tgid);
- task = pid_task(pid_struct, PIDTYPE_PID);
- get_task_struct(task);
- kctx->task = task;
- put_pid(pid_struct);
- rcu_read_unlock();
-
+ /* Check if this is a Userspace created context */
+ if (likely(kctx->filp)) {
+ rcu_read_lock();
+ pid_struct = find_get_pid(kctx->tgid);
+ task = pid_task(pid_struct, PIDTYPE_PID);
+ get_task_struct(task);
+ kctx->task = task;
+ put_pid(pid_struct);
+ rcu_read_unlock();
+ /* This merely takes a reference on the mm_struct and not on the
+ * address space and so won't block the freeing of address space
+ * on process exit.
+ */
+ mmgrab(current->mm);
+ kctx->process_mm = current->mm;
+ }
err = kbase_mem_pool_init(&kctx->mem_pool,
kbdev->mem_pool_max_size_default,
@@ -345,8 +351,10 @@ void kbase_destroy_context(struct kbase_context *kctx)
kctx->ctx_need_qos = false;
}
-
- put_task_struct(kctx->task);
+ if (likely(kctx->filp)) {
+ mmdrop(kctx->process_mm);
+ put_task_struct(kctx->task);
+ }
vfree(kctx);
/* MALI_SEC_INTEGRATION */
diff --git a/drivers/gpu/arm/t72x/r29p0/mali_kbase_defs.h b/drivers/gpu/arm/t72x/r29p0/mali_kbase_defs.h
index 528a0425f427..640fd5636ee1 100644
--- a/drivers/gpu/arm/t72x/r29p0/mali_kbase_defs.h
+++ b/drivers/gpu/arm/t72x/r29p0/mali_kbase_defs.h
@@ -1974,7 +1974,11 @@ struct kbase_reg_zone {
* @process_mm: Pointer to the memory descriptor of the process which
* created the context. Used for accounting the physical
* pages used for GPU allocations, done for the context,
- * to the memory consumed by the process.
+ * to the memory consumed by the process. A reference is
+ * taken on this descriptor for the Userspace created
+ * contexts so that Kbase can safely access it to update
+ * the memory usage counters. The reference is dropped on
+ * context termination.
* @gpu_va_end: End address of the GPU va space (in 4KB page units)
* @jit_va: Indicates if a JIT_VA zone has been created.
* @timeline: Object tracking the number of atoms currently in flight for
@@ -2138,14 +2142,7 @@ struct kbase_context {
atomic_t refcount;
- /* NOTE:
- *
- * Flags are in jctx.sched_info.ctx.flags
- * Mutable flags *must* be accessed under jctx.sched_info.ctx.jsctx_mutex
- *
- * All other flags must be added there */
- spinlock_t mm_update_lock;
- struct mm_struct __rcu *process_mm;
+ struct mm_struct *process_mm;
u64 gpu_va_end;
bool jit_va;
diff --git a/drivers/gpu/arm/t72x/r29p0/mali_kbase_mem_linux.c b/drivers/gpu/arm/t72x/r29p0/mali_kbase_mem_linux.c
index 7cdf510eed9a..2d40764df241 100644
--- a/drivers/gpu/arm/t72x/r29p0/mali_kbase_mem_linux.c
+++ b/drivers/gpu/arm/t72x/r29p0/mali_kbase_mem_linux.c
@@ -2502,73 +2502,25 @@ KBASE_EXPORT_TEST_API(kbase_vunmap);
void kbasep_os_process_page_usage_update(struct kbase_context *kctx, int pages)
{
- struct mm_struct *mm;
+ struct mm_struct *mm = kctx->process_mm;
- rcu_read_lock();
- mm = rcu_dereference(kctx->process_mm);
- if (mm) {
- atomic_add(pages, &kctx->nonmapped_pages);
-#ifdef SPLIT_RSS_COUNTING
- add_mm_counter(mm, MM_FILEPAGES, pages);
-#else
- spin_lock(&mm->page_table_lock);
- add_mm_counter(mm, MM_FILEPAGES, pages);
- spin_unlock(&mm->page_table_lock);
-#endif
- }
- rcu_read_unlock();
-}
-
-static void kbasep_os_process_page_usage_drain(struct kbase_context *kctx)
-{
- int pages;
- struct mm_struct *mm;
-
- spin_lock(&kctx->mm_update_lock);
- mm = rcu_dereference_protected(kctx->process_mm, lockdep_is_held(&kctx->mm_update_lock));
- if (!mm) {
- spin_unlock(&kctx->mm_update_lock);
+ if (unlikely(!mm)) {
return;
}
-
- rcu_assign_pointer(kctx->process_mm, NULL);
- spin_unlock(&kctx->mm_update_lock);
- synchronize_rcu();
-
- pages = atomic_xchg(&kctx->nonmapped_pages, 0);
+ atomic_add(pages, &kctx->nonmapped_pages);
#ifdef SPLIT_RSS_COUNTING
- add_mm_counter(mm, MM_FILEPAGES, -pages);
+ add_mm_counter(mm, MM_FILEPAGES, pages);
#else
spin_lock(&mm->page_table_lock);
- add_mm_counter(mm, MM_FILEPAGES, -pages);
+ add_mm_counter(mm, MM_FILEPAGES, pages);
spin_unlock(&mm->page_table_lock);
#endif
}
-static void kbase_special_vm_close(struct vm_area_struct *vma)
-{
- struct kbase_context *kctx;
-
- kctx = vma->vm_private_data;
- kbasep_os_process_page_usage_drain(kctx);
-}
-
-static const struct vm_operations_struct kbase_vm_special_ops = {
- .close = kbase_special_vm_close,
-};
-
static int kbase_tracking_page_setup(struct kbase_context *kctx, struct vm_area_struct *vma)
{
- /* check that this is the only tracking page */
- spin_lock(&kctx->mm_update_lock);
- if (rcu_dereference_protected(kctx->process_mm, lockdep_is_held(&kctx->mm_update_lock))) {
- spin_unlock(&kctx->mm_update_lock);
- return -EFAULT;
- }
-
- rcu_assign_pointer(kctx->process_mm, current->mm);
-
- spin_unlock(&kctx->mm_update_lock);
+ if (vma_pages(vma) != 1)
+ return -EINVAL;
/* no real access */
vma->vm_flags &= ~(VM_READ | VM_MAYREAD | VM_WRITE | VM_MAYWRITE | VM_EXEC | VM_MAYEXEC);
@@ -2577,9 +2529,6 @@ static int kbase_tracking_page_setup(struct kbase_context *kctx, struct vm_area_
#else
vma->vm_flags |= VM_DONTCOPY | VM_DONTEXPAND | VM_RESERVED | VM_IO;
#endif
- vma->vm_ops = &kbase_vm_special_ops;
- vma->vm_private_data = kctx;
-
return 0;
}