Commit 56753e73 authored by Christian König's avatar Christian König Committed by Alex Deucher

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: default avatarChristian König <christian.koenig@amd.com>
Reviewed-by: default avatarChunming Zhou <david1.zhou@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 3119e7f4
...@@ -558,13 +558,12 @@ void amdgpu_ctx_mgr_init(struct amdgpu_ctx_mgr *mgr) ...@@ -558,13 +558,12 @@ void amdgpu_ctx_mgr_init(struct amdgpu_ctx_mgr *mgr)
idr_init(&mgr->ctx_handles); 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(); unsigned num_entities = amdgput_ctx_total_num_entities();
struct amdgpu_ctx *ctx; struct amdgpu_ctx *ctx;
struct idr *idp; struct idr *idp;
uint32_t id, i; uint32_t id, i;
long max_wait = MAX_WAIT_SCHED_ENTITY_Q_EMPTY;
idp = &mgr->ctx_handles; idp = &mgr->ctx_handles;
...@@ -574,10 +573,11 @@ void amdgpu_ctx_mgr_entity_flush(struct amdgpu_ctx_mgr *mgr) ...@@ -574,10 +573,11 @@ void amdgpu_ctx_mgr_entity_flush(struct amdgpu_ctx_mgr *mgr)
struct drm_sched_entity *entity; struct drm_sched_entity *entity;
entity = &ctx->entities[0][i].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); mutex_unlock(&mgr->lock);
return timeout;
} }
void amdgpu_ctx_mgr_entity_fini(struct amdgpu_ctx_mgr *mgr) void amdgpu_ctx_mgr_entity_fini(struct amdgpu_ctx_mgr *mgr)
......
...@@ -84,7 +84,7 @@ int amdgpu_ctx_wait_prev_fence(struct amdgpu_ctx *ctx, ...@@ -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_init(struct amdgpu_ctx_mgr *mgr);
void amdgpu_ctx_mgr_entity_fini(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); void amdgpu_ctx_mgr_fini(struct amdgpu_ctx_mgr *mgr);
#endif #endif
...@@ -1176,13 +1176,14 @@ static int amdgpu_flush(struct file *f, fl_owner_t id) ...@@ -1176,13 +1176,14 @@ static int amdgpu_flush(struct file *f, fl_owner_t id)
{ {
struct drm_file *file_priv = f->private_data; struct drm_file *file_priv = f->private_data;
struct amdgpu_fpriv *fpriv = file_priv->driver_priv; 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 = { static const struct file_operations amdgpu_driver_kms_fops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.open = drm_open, .open = drm_open,
......
...@@ -2977,6 +2977,18 @@ void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint32_t min_vm_size, ...@@ -2977,6 +2977,18 @@ void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint32_t min_vm_size,
adev->vm_manager.fragment_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 * amdgpu_vm_init - initialize a vm instance
* *
......
...@@ -281,6 +281,8 @@ struct amdgpu_vm_manager { ...@@ -281,6 +281,8 @@ struct amdgpu_vm_manager {
void amdgpu_vm_manager_init(struct amdgpu_device *adev); void amdgpu_vm_manager_init(struct amdgpu_device *adev);
void amdgpu_vm_manager_fini(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 amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
int vm_context, unsigned int pasid); int vm_context, unsigned int pasid);
int amdgpu_vm_make_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm, unsigned int pasid); int amdgpu_vm_make_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm, unsigned int pasid);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment