diff options
Diffstat (limited to 'drivers/gpu/arm/mali/context/mali_kbase_context.c')
-rw-r--r-- | drivers/gpu/arm/mali/context/mali_kbase_context.c | 73 |
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) |