aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/arm/mali/context/mali_kbase_context.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/arm/mali/context/mali_kbase_context.c')
-rw-r--r--drivers/gpu/arm/mali/context/mali_kbase_context.c73
1 files changed, 56 insertions, 17 deletions
diff --git a/drivers/gpu/arm/mali/context/mali_kbase_context.c b/drivers/gpu/arm/mali/context/mali_kbase_context.c
index f681b8a466b3c6..8e2eac80864dbd 100644
--- a/drivers/gpu/arm/mali/context/mali_kbase_context.c
+++ b/drivers/gpu/arm/mali/context/mali_kbase_context.c
@@ -22,6 +22,16 @@
/*
* Base kernel context APIs
*/
+#include <linux/version.h>
+#if KERNEL_VERSION(4, 11, 0) <= LINUX_VERSION_CODE
+#include <linux/sched/task.h>
+#endif
+
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+#include <linux/sched/signal.h>
+#else
+#include <linux/sched.h>
+#endif
#include <mali_kbase.h>
#include <gpu/mali_kbase_gpu_regmap.h>
@@ -130,18 +140,47 @@ int kbase_context_common_init(struct kbase_context *kctx)
kbase_disjoint_event(kctx->kbdev);
kctx->process_mm = NULL;
+ kctx->task = NULL;
atomic_set(&kctx->nonmapped_pages, 0);
atomic_set(&kctx->permanent_mapped_pages, 0);
kctx->tgid = current->tgid;
kctx->pid = current->pid;
/* Check if this is a Userspace created context */
- if (likely(kctx->filp)) {
- /* 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);
+ if (likely(kctx->kfile)) {
+ struct pid *pid_struct;
+
+ rcu_read_lock();
+ pid_struct = get_pid(task_tgid(current));
+ if (likely(pid_struct)) {
+ struct task_struct *task = pid_task(pid_struct, PIDTYPE_PID);
+
+ if (likely(task)) {
+ /* Take a reference on the task to avoid slow lookup
+ * later on from the page allocation loop.
+ */
+ get_task_struct(task);
+ kctx->task = task;
+ } else {
+ dev_err(kctx->kbdev->dev,
+ "Failed to get task pointer for %s/%d",
+ current->comm, current->pid);
+ err = -ESRCH;
+ }
+
+ put_pid(pid_struct);
+ } else {
+ dev_err(kctx->kbdev->dev,
+ "Failed to get pid pointer for %s/%d",
+ current->comm, current->pid);
+ err = -ESRCH;
+ }
+ rcu_read_unlock();
+
+ if (unlikely(err))
+ return err;
+
+ kbase_mem_mmgrab();
kctx->process_mm = current->mm;
}
@@ -155,7 +194,6 @@ int kbase_context_common_init(struct kbase_context *kctx)
spin_lock_init(&kctx->waiting_soft_jobs_lock);
INIT_LIST_HEAD(&kctx->waiting_soft_jobs);
- init_waitqueue_head(&kctx->event_queue);
atomic_set(&kctx->event_count, 0);
#if !MALI_USE_CSF
@@ -177,16 +215,17 @@ int kbase_context_common_init(struct kbase_context *kctx)
kctx->id = atomic_add_return(1, &(kctx->kbdev->ctx_num)) - 1;
mutex_lock(&kctx->kbdev->kctx_list_lock);
-
err = kbase_insert_kctx_to_process(kctx);
+ mutex_unlock(&kctx->kbdev->kctx_list_lock);
if (err) {
- dev_err(kctx->kbdev->dev, "(err:%d) failed to insert kctx to kbase_process", err);
- if (likely(kctx->filp))
+ dev_err(kctx->kbdev->dev,
+ "(err:%d) failed to insert kctx to kbase_process", err);
+ if (likely(kctx->kfile)) {
mmdrop(kctx->process_mm);
+ put_task_struct(kctx->task);
+ }
}
- mutex_unlock(&kctx->kbdev->kctx_list_lock);
-
return err;
}
@@ -271,18 +310,18 @@ void kbase_context_common_term(struct kbase_context *kctx)
kbase_remove_kctx_from_process(kctx);
mutex_unlock(&kctx->kbdev->kctx_list_lock);
- if (likely(kctx->filp))
+ if (likely(kctx->kfile)) {
mmdrop(kctx->process_mm);
+ put_task_struct(kctx->task);
+ }
KBASE_KTRACE_ADD(kctx->kbdev, CORE_CTX_DESTROY, kctx, 0u);
}
int kbase_context_mem_pool_group_init(struct kbase_context *kctx)
{
- return kbase_mem_pool_group_init(&kctx->mem_pools,
- kctx->kbdev,
- &kctx->kbdev->mem_pool_defaults,
- &kctx->kbdev->mem_pools);
+ return kbase_mem_pool_group_init(&kctx->mem_pools, kctx->kbdev,
+ &kctx->kbdev->mem_pool_defaults, &kctx->kbdev->mem_pools);
}
void kbase_context_mem_pool_group_term(struct kbase_context *kctx)