Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amdgpu: wait for VM to become idle during flush

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>

authored by

Christian König and committed by
Alex Deucher
56753e73 3119e7f4

+22 -7
+3 -3
drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
··· 558 558 idr_init(&mgr->ctx_handles); 559 559 } 560 560 561 - void amdgpu_ctx_mgr_entity_flush(struct amdgpu_ctx_mgr *mgr) 561 + long amdgpu_ctx_mgr_entity_flush(struct amdgpu_ctx_mgr *mgr, long timeout) 562 562 { 563 563 unsigned num_entities = amdgput_ctx_total_num_entities(); 564 564 struct amdgpu_ctx *ctx; 565 565 struct idr *idp; 566 566 uint32_t id, i; 567 - long max_wait = MAX_WAIT_SCHED_ENTITY_Q_EMPTY; 568 567 569 568 idp = &mgr->ctx_handles; 570 569 ··· 573 574 struct drm_sched_entity *entity; 574 575 575 576 entity = &ctx->entities[0][i].entity; 576 - max_wait = drm_sched_entity_flush(entity, max_wait); 577 + timeout = drm_sched_entity_flush(entity, timeout); 577 578 } 578 579 } 579 580 mutex_unlock(&mgr->lock); 581 + return timeout; 580 582 } 581 583 582 584 void amdgpu_ctx_mgr_entity_fini(struct amdgpu_ctx_mgr *mgr)
+1 -1
drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h
··· 84 84 85 85 void amdgpu_ctx_mgr_init(struct amdgpu_ctx_mgr *mgr); 86 86 void amdgpu_ctx_mgr_entity_fini(struct amdgpu_ctx_mgr *mgr); 87 - void amdgpu_ctx_mgr_entity_flush(struct amdgpu_ctx_mgr *mgr); 87 + long amdgpu_ctx_mgr_entity_flush(struct amdgpu_ctx_mgr *mgr, long timeout); 88 88 void amdgpu_ctx_mgr_fini(struct amdgpu_ctx_mgr *mgr); 89 89 90 90 #endif
+4 -3
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
··· 1176 1176 { 1177 1177 struct drm_file *file_priv = f->private_data; 1178 1178 struct amdgpu_fpriv *fpriv = file_priv->driver_priv; 1179 + long timeout = MAX_WAIT_SCHED_ENTITY_Q_EMPTY; 1179 1180 1180 - amdgpu_ctx_mgr_entity_flush(&fpriv->ctx_mgr); 1181 + timeout = amdgpu_ctx_mgr_entity_flush(&fpriv->ctx_mgr, timeout); 1182 + timeout = amdgpu_vm_wait_idle(&fpriv->vm, timeout); 1181 1183 1182 - return 0; 1184 + return timeout >= 0 ? 0 : timeout; 1183 1185 } 1184 - 1185 1186 1186 1187 static const struct file_operations amdgpu_driver_kms_fops = { 1187 1188 .owner = THIS_MODULE,
+12
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
··· 2978 2978 } 2979 2979 2980 2980 /** 2981 + * amdgpu_vm_wait_idle - wait for the VM to become idle 2982 + * 2983 + * @vm: VM object to wait for 2984 + * @timeout: timeout to wait for VM to become idle 2985 + */ 2986 + long amdgpu_vm_wait_idle(struct amdgpu_vm *vm, long timeout) 2987 + { 2988 + return reservation_object_wait_timeout_rcu(vm->root.base.bo->tbo.resv, 2989 + true, true, timeout); 2990 + } 2991 + 2992 + /** 2981 2993 * amdgpu_vm_init - initialize a vm instance 2982 2994 * 2983 2995 * @adev: amdgpu_device pointer
+2
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
··· 281 281 282 282 void amdgpu_vm_manager_init(struct amdgpu_device *adev); 283 283 void amdgpu_vm_manager_fini(struct amdgpu_device *adev); 284 + 285 + long amdgpu_vm_wait_idle(struct amdgpu_vm *vm, long timeout); 284 286 int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm, 285 287 int vm_context, unsigned int pasid); 286 288 int amdgpu_vm_make_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm, unsigned int pasid);