drm/amdgpu: wait for VM to become idle during flush
authorChristian König <christian.koenig@amd.com>
Thu, 10 Jan 2019 15:48:23 +0000 (16:48 +0100)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 19 Mar 2019 20:36:58 +0000 (15:36 -0500)
Make sure that not only the entities are flush, but that
we also wait for the HW to finish all processing.

Signed-off-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Chunming Zhou <david1.zhou@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h

index b7289f7096442603a94fed1583095e09974dded4..a28a3d722ba29926aedc1c847f9c950d86373224 100644 (file)
@@ -558,13 +558,12 @@ void amdgpu_ctx_mgr_init(struct amdgpu_ctx_mgr *mgr)
        idr_init(&mgr->ctx_handles);
 }
 
-void amdgpu_ctx_mgr_entity_flush(struct amdgpu_ctx_mgr *mgr)
+long amdgpu_ctx_mgr_entity_flush(struct amdgpu_ctx_mgr *mgr, long timeout)
 {
        unsigned num_entities = amdgput_ctx_total_num_entities();
        struct amdgpu_ctx *ctx;
        struct idr *idp;
        uint32_t id, i;
-       long max_wait = MAX_WAIT_SCHED_ENTITY_Q_EMPTY;
 
        idp = &mgr->ctx_handles;
 
@@ -574,10 +573,11 @@ void amdgpu_ctx_mgr_entity_flush(struct amdgpu_ctx_mgr *mgr)
                        struct drm_sched_entity *entity;
 
                        entity = &ctx->entities[0][i].entity;
-                       max_wait = drm_sched_entity_flush(entity, max_wait);
+                       timeout = drm_sched_entity_flush(entity, timeout);
                }
        }
        mutex_unlock(&mgr->lock);
+       return timeout;
 }
 
 void amdgpu_ctx_mgr_entity_fini(struct amdgpu_ctx_mgr *mgr)
index 8e561daa64cb311ba3cb7fdda90f6ca1dd2c8f3e..5f1b54c9bcdb730ede45d17f9ab644e7c42215fa 100644 (file)
@@ -84,7 +84,7 @@ int amdgpu_ctx_wait_prev_fence(struct amdgpu_ctx *ctx,
 
 void amdgpu_ctx_mgr_init(struct amdgpu_ctx_mgr *mgr);
 void amdgpu_ctx_mgr_entity_fini(struct amdgpu_ctx_mgr *mgr);
-void amdgpu_ctx_mgr_entity_flush(struct amdgpu_ctx_mgr *mgr);
+long amdgpu_ctx_mgr_entity_flush(struct amdgpu_ctx_mgr *mgr, long timeout);
 void amdgpu_ctx_mgr_fini(struct amdgpu_ctx_mgr *mgr);
 
 #endif
index 6c87785db26c61cc94406bd6c71069bb6e82dda1..ee678925e610f1e5ff5fb8791ce041d8a8bdb38a 100644 (file)
@@ -1176,13 +1176,14 @@ static int amdgpu_flush(struct file *f, fl_owner_t id)
 {
        struct drm_file *file_priv = f->private_data;
        struct amdgpu_fpriv *fpriv = file_priv->driver_priv;
+       long timeout = MAX_WAIT_SCHED_ENTITY_Q_EMPTY;
 
-       amdgpu_ctx_mgr_entity_flush(&fpriv->ctx_mgr);
+       timeout = amdgpu_ctx_mgr_entity_flush(&fpriv->ctx_mgr, timeout);
+       timeout = amdgpu_vm_wait_idle(&fpriv->vm, timeout);
 
-       return 0;
+       return timeout >= 0 ? 0 : timeout;
 }
 
-
 static const struct file_operations amdgpu_driver_kms_fops = {
        .owner = THIS_MODULE,
        .open = drm_open,
index a45ca5d2cfe9f64c2adf0b71697e8a51b180eba3..8603c85985b5b46bd5771f3a18b0e2c360babcbf 100644 (file)
@@ -2977,6 +2977,18 @@ void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint32_t min_vm_size,
                 adev->vm_manager.fragment_size);
 }
 
+/**
+ * amdgpu_vm_wait_idle - wait for the VM to become idle
+ *
+ * @vm: VM object to wait for
+ * @timeout: timeout to wait for VM to become idle
+ */
+long amdgpu_vm_wait_idle(struct amdgpu_vm *vm, long timeout)
+{
+       return reservation_object_wait_timeout_rcu(vm->root.base.bo->tbo.resv,
+                                                  true, true, timeout);
+}
+
 /**
  * amdgpu_vm_init - initialize a vm instance
  *
index a1a62e3cb6e42d67fbc0da16569b54c33a2fb40a..f5c25c0ae367f26863a59d9395225a0cb82a45a4 100644 (file)
@@ -281,6 +281,8 @@ struct amdgpu_vm_manager {
 
 void amdgpu_vm_manager_init(struct amdgpu_device *adev);
 void amdgpu_vm_manager_fini(struct amdgpu_device *adev);
+
+long amdgpu_vm_wait_idle(struct amdgpu_vm *vm, long timeout);
 int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
                   int vm_context, unsigned int pasid);
 int amdgpu_vm_make_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm, unsigned int pasid);