summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c101
1 files changed, 69 insertions, 32 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
index 17bf2d568ae2..712fd34740a0 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
@@ -44,6 +44,45 @@ u32 amdgpu_userqueue_get_supported_ip_mask(struct amdgpu_device *adev)
return userq_ip_mask;
}
+static int
+amdgpu_userqueue_unmap_helper(struct amdgpu_userq_mgr *uq_mgr,
+ struct amdgpu_usermode_queue *queue)
+{
+ struct amdgpu_device *adev = uq_mgr->adev;
+ const struct amdgpu_userq_funcs *userq_funcs =
+ adev->userq_funcs[queue->queue_type];
+ int r = 0;
+
+ if (queue->state == AMDGPU_USERQ_STATE_MAPPED) {
+ r = userq_funcs->unmap(uq_mgr, queue);
+ if (r)
+ queue->state = AMDGPU_USERQ_STATE_HUNG;
+ else
+ queue->state = AMDGPU_USERQ_STATE_UNMAPPED;
+ }
+ return r;
+}
+
+static int
+amdgpu_userqueue_map_helper(struct amdgpu_userq_mgr *uq_mgr,
+ struct amdgpu_usermode_queue *queue)
+{
+ struct amdgpu_device *adev = uq_mgr->adev;
+ const struct amdgpu_userq_funcs *userq_funcs =
+ adev->userq_funcs[queue->queue_type];
+ int r = 0;
+
+ if (queue->state == AMDGPU_USERQ_STATE_UNMAPPED) {
+ r = userq_funcs->map(uq_mgr, queue);
+ if (r) {
+ queue->state = AMDGPU_USERQ_STATE_HUNG;
+ } else {
+ queue->state = AMDGPU_USERQ_STATE_MAPPED;
+ }
+ }
+ return r;
+}
+
static void
amdgpu_userqueue_cleanup(struct amdgpu_userq_mgr *uq_mgr,
struct amdgpu_usermode_queue *queue,
@@ -79,7 +118,7 @@ amdgpu_userqueue_active(struct amdgpu_userq_mgr *uq_mgr)
mutex_lock(&uq_mgr->userq_mutex);
/* Resume all the queues for this process */
idr_for_each_entry(&uq_mgr->userq_idr, queue, queue_id)
- ret += queue->queue_active;
+ ret += queue->state == AMDGPU_USERQ_STATE_MAPPED;
mutex_unlock(&uq_mgr->userq_mutex);
return ret;
@@ -254,9 +293,8 @@ amdgpu_userqueue_destroy(struct drm_file *filp, int queue_id)
struct amdgpu_fpriv *fpriv = filp->driver_priv;
struct amdgpu_userq_mgr *uq_mgr = &fpriv->userq_mgr;
struct amdgpu_device *adev = uq_mgr->adev;
- const struct amdgpu_userq_funcs *uq_funcs;
struct amdgpu_usermode_queue *queue;
- int r;
+ int r = 0;
cancel_delayed_work(&uq_mgr->resume_work);
mutex_lock(&uq_mgr->userq_mutex);
@@ -267,8 +305,7 @@ amdgpu_userqueue_destroy(struct drm_file *filp, int queue_id)
mutex_unlock(&uq_mgr->userq_mutex);
return -EINVAL;
}
- uq_funcs = adev->userq_funcs[queue->queue_type];
- r = uq_funcs->unmap(uq_mgr, queue);
+ r = amdgpu_userqueue_unmap_helper(uq_mgr, queue);
amdgpu_bo_unpin(queue->db_obj.obj);
amdgpu_bo_unref(&queue->db_obj.obj);
amdgpu_userqueue_cleanup(uq_mgr, queue, queue_id);
@@ -414,7 +451,7 @@ amdgpu_userqueue_create(struct drm_file *filp, union drm_amdgpu_userq *args)
else
skip_map_queue = false;
if (!skip_map_queue) {
- r = uq_funcs->map(uq_mgr, queue);
+ r = amdgpu_userqueue_map_helper(uq_mgr, queue);
if (r) {
mutex_unlock(&adev->userq_mutex);
DRM_ERROR("Failed to map Queue\n");
@@ -489,19 +526,19 @@ static int
amdgpu_userqueue_resume_all(struct amdgpu_userq_mgr *uq_mgr)
{
struct amdgpu_device *adev = uq_mgr->adev;
- const struct amdgpu_userq_funcs *userq_funcs;
struct amdgpu_usermode_queue *queue;
int queue_id;
- int ret = 0;
+ int ret = 0, r;
/* Resume all the queues for this process */
idr_for_each_entry(&uq_mgr->userq_idr, queue, queue_id) {
- userq_funcs = adev->userq_funcs[queue->queue_type];
- ret |= userq_funcs->map(uq_mgr, queue);
+ r = amdgpu_userqueue_map_helper(uq_mgr, queue);
+ if (r)
+ ret = r;
}
if (ret)
- DRM_ERROR("Failed to map all the queues\n");
+ dev_err(adev->dev, "Failed to map all the queues\n");
return ret;
}
@@ -647,19 +684,19 @@ static int
amdgpu_userqueue_suspend_all(struct amdgpu_userq_mgr *uq_mgr)
{
struct amdgpu_device *adev = uq_mgr->adev;
- const struct amdgpu_userq_funcs *userq_funcs;
struct amdgpu_usermode_queue *queue;
int queue_id;
- int ret = 0;
+ int ret = 0, r;
/* Try to unmap all the queues in this process ctx */
idr_for_each_entry(&uq_mgr->userq_idr, queue, queue_id) {
- userq_funcs = adev->userq_funcs[queue->queue_type];
- ret += userq_funcs->unmap(uq_mgr, queue);
+ r = amdgpu_userqueue_unmap_helper(uq_mgr, queue);
+ if (r)
+ ret = r;
}
if (ret)
- DRM_ERROR("Couldn't unmap all the queues\n");
+ dev_err(adev->dev, "Couldn't unmap all the queues\n");
return ret;
}
@@ -760,11 +797,10 @@ void amdgpu_userq_mgr_fini(struct amdgpu_userq_mgr *userq_mgr)
int amdgpu_userq_suspend(struct amdgpu_device *adev)
{
u32 ip_mask = amdgpu_userqueue_get_supported_ip_mask(adev);
- const struct amdgpu_userq_funcs *userq_funcs;
struct amdgpu_usermode_queue *queue;
struct amdgpu_userq_mgr *uqm, *tmp;
int queue_id;
- int ret = 0;
+ int ret = 0, r;
if (!ip_mask)
return 0;
@@ -773,8 +809,9 @@ int amdgpu_userq_suspend(struct amdgpu_device *adev)
list_for_each_entry_safe(uqm, tmp, &adev->userq_mgr_list, list) {
cancel_delayed_work_sync(&uqm->resume_work);
idr_for_each_entry(&uqm->userq_idr, queue, queue_id) {
- userq_funcs = adev->userq_funcs[queue->queue_type];
- ret |= userq_funcs->unmap(uqm, queue);
+ r = amdgpu_userqueue_unmap_helper(uqm, queue);
+ if (r)
+ ret = r;
}
}
mutex_unlock(&adev->userq_mutex);
@@ -784,11 +821,10 @@ int amdgpu_userq_suspend(struct amdgpu_device *adev)
int amdgpu_userq_resume(struct amdgpu_device *adev)
{
u32 ip_mask = amdgpu_userqueue_get_supported_ip_mask(adev);
- const struct amdgpu_userq_funcs *userq_funcs;
struct amdgpu_usermode_queue *queue;
struct amdgpu_userq_mgr *uqm, *tmp;
int queue_id;
- int ret = 0;
+ int ret = 0, r;
if (!ip_mask)
return 0;
@@ -796,8 +832,9 @@ int amdgpu_userq_resume(struct amdgpu_device *adev)
mutex_lock(&adev->userq_mutex);
list_for_each_entry_safe(uqm, tmp, &adev->userq_mgr_list, list) {
idr_for_each_entry(&uqm->userq_idr, queue, queue_id) {
- userq_funcs = adev->userq_funcs[queue->queue_type];
- ret |= userq_funcs->map(uqm, queue);
+ r = amdgpu_userqueue_map_helper(uqm, queue);
+ if (r)
+ ret = r;
}
}
mutex_unlock(&adev->userq_mutex);
@@ -808,11 +845,10 @@ int amdgpu_userq_stop_sched_for_enforce_isolation(struct amdgpu_device *adev,
u32 idx)
{
u32 ip_mask = amdgpu_userqueue_get_supported_ip_mask(adev);
- const struct amdgpu_userq_funcs *userq_funcs;
struct amdgpu_usermode_queue *queue;
struct amdgpu_userq_mgr *uqm, *tmp;
int queue_id;
- int ret = 0;
+ int ret = 0, r;
/* only need to stop gfx/compute */
if (!(ip_mask & ((1 << AMDGPU_HW_IP_GFX) | (1 << AMDGPU_HW_IP_COMPUTE))))
@@ -828,8 +864,9 @@ int amdgpu_userq_stop_sched_for_enforce_isolation(struct amdgpu_device *adev,
if (((queue->queue_type == AMDGPU_HW_IP_GFX) ||
(queue->queue_type == AMDGPU_HW_IP_COMPUTE)) &&
(queue->xcp_id == idx)) {
- userq_funcs = adev->userq_funcs[queue->queue_type];
- ret |= userq_funcs->unmap(uqm, queue);
+ r = amdgpu_userqueue_unmap_helper(uqm, queue);
+ if (r)
+ ret = r;
}
}
}
@@ -841,11 +878,10 @@ int amdgpu_userq_start_sched_for_enforce_isolation(struct amdgpu_device *adev,
u32 idx)
{
u32 ip_mask = amdgpu_userqueue_get_supported_ip_mask(adev);
- const struct amdgpu_userq_funcs *userq_funcs;
struct amdgpu_usermode_queue *queue;
struct amdgpu_userq_mgr *uqm, *tmp;
int queue_id;
- int ret = 0;
+ int ret = 0, r;
/* only need to stop gfx/compute */
if (!(ip_mask & ((1 << AMDGPU_HW_IP_GFX) | (1 << AMDGPU_HW_IP_COMPUTE))))
@@ -860,8 +896,9 @@ int amdgpu_userq_start_sched_for_enforce_isolation(struct amdgpu_device *adev,
if (((queue->queue_type == AMDGPU_HW_IP_GFX) ||
(queue->queue_type == AMDGPU_HW_IP_COMPUTE)) &&
(queue->xcp_id == idx)) {
- userq_funcs = adev->userq_funcs[queue->queue_type];
- ret |= userq_funcs->map(uqm, queue);
+ r = amdgpu_userqueue_map_helper(uqm, queue);
+ if (r)
+ ret = r;
}
}
}