From 4402e0d7858450f531f38aa7766233b4b8c8e1bb Mon Sep 17 00:00:00 2001 From: Qiang Yu Date: Mon, 28 May 2018 17:36:59 +0800 Subject: [PATCH 066/146] drm/lima: wait bo fence before bo close We can't bring preclose back, so use this method for user application termination. Signed-off-by: Qiang Yu --- drivers/gpu/drm/lima/lima_drv.c | 9 +-------- drivers/gpu/drm/lima/lima_sched.c | 2 +- drivers/gpu/drm/lima/lima_vm.c | 32 +++++++++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/lima/lima_drv.c b/drivers/gpu/drm/lima/lima_drv.c index 7f2e47da6801..d3ab9f7abb93 100644 --- a/drivers/gpu/drm/lima/lima_drv.c +++ b/drivers/gpu/drm/lima/lima_drv.c @@ -270,17 +270,11 @@ static int lima_drm_driver_open(struct drm_device *dev, struct drm_file *file) return err; } -static void lima_drm_driver_preclose(struct drm_device *dev, struct drm_file *file) -{ - struct lima_drm_priv *priv = file->driver_priv; - - lima_ctx_mgr_fini(&priv->ctx_mgr); -} - static void lima_drm_driver_postclose(struct drm_device *dev, struct drm_file *file) { struct lima_drm_priv *priv = file->driver_priv; + lima_ctx_mgr_fini(&priv->ctx_mgr); lima_vm_put(priv->vm); kfree(priv); } @@ -310,7 +304,6 @@ static const struct file_operations lima_drm_driver_fops = { static struct drm_driver lima_drm_driver = { .driver_features = DRIVER_RENDER | DRIVER_GEM | DRIVER_PRIME, .open = lima_drm_driver_open, - .preclose = lima_drm_driver_preclose, .postclose = lima_drm_driver_postclose, .ioctls = lima_drm_driver_ioctls, .num_ioctls = ARRAY_SIZE(lima_drm_driver_ioctls), diff --git a/drivers/gpu/drm/lima/lima_sched.c b/drivers/gpu/drm/lima/lima_sched.c index 3b5ea2e4674d..89e758718d62 100644 --- a/drivers/gpu/drm/lima/lima_sched.c +++ b/drivers/gpu/drm/lima/lima_sched.c @@ -112,7 +112,7 @@ int lima_sched_task_init(struct lima_sched_task *task, int err; err = drm_sched_job_init(&task->base, context->base.sched, - &context->base, context); + &context->base, vm); if (err) return err; diff --git a/drivers/gpu/drm/lima/lima_vm.c b/drivers/gpu/drm/lima/lima_vm.c index 11eb3c278df2..19a683c2921b 100644 --- a/drivers/gpu/drm/lima/lima_vm.c +++ b/drivers/gpu/drm/lima/lima_vm.c @@ -195,15 +195,47 @@ int lima_vm_bo_add(struct lima_vm *vm, struct lima_bo *bo) return 0; } +/* wait only fence of resv from task using vm */ +static int lima_vm_wait_resv(struct lima_vm *vm, + struct reservation_object *resv) +{ + unsigned nr_fences; + struct dma_fence **fences; + int i; + long err; + + err = reservation_object_get_fences_rcu(resv, NULL, &nr_fences, &fences); + if (err || !nr_fences) + return err; + + for (i = 0; i < nr_fences; i++) { + struct drm_sched_fence *sf = to_drm_sched_fence(fences[i]); + if (sf && sf->owner == vm) + err |= dma_fence_wait(fences[i], false); + dma_fence_put(fences[i]); + } + + kfree(fences); + return err; +} + int lima_vm_bo_del(struct lima_vm *vm, struct lima_bo *bo) { struct lima_bo_va *bo_va; struct lima_bo_va_mapping *mapping, *tmp; + int err; bo_va = lima_vm_bo_find(vm, bo); if (--bo_va->ref_count > 0) return 0; + /* wait bo idle before unmap it from vm in case user + * space application is terminated when bo is busy. + */ + err = lima_vm_wait_resv(vm, bo->tbo.resv); + if (err) + dev_err(vm->dev->dev, "bo del fail to wait (%d)\n", err); + list_for_each_entry_safe(mapping, tmp, &bo_va->mapping, list) { lima_vm_unmap(vm, mapping); } -- 2.17.1