Commit bb1d7f15 authored by Jesse.Zhang's avatar Jesse.Zhang Committed by Alex Deucher
Browse files

drm/amdgpu: Switch user queues to use preempt/restore for eviction



This patch modifies the user queue management to use preempt/restore
operations instead of full map/unmap for queue eviction scenarios where
applicable. The changes include:

1. Introduces new helper functions:
   - amdgpu_userqueue_preempt_helper()
   - amdgpu_userqueue_restore_helper()

2. Updates queue state management to track PREEMPTED state

3. Modifies eviction handling to use preempt instead of unmap:
   - amdgpu_userq_evict_all() now uses preempt_helper
   - amdgpu_userq_restore_all() now uses restore_helper

The preempt/restore approach provides better performance during queue
eviction by avoiding the overhead of full queue teardown and setup.
Full map/unmap operations are still used for initial setup/teardown
and system suspend scenarios.

v2: rename amdgpu_userqueue_restore_helper/amdgpu_userqueue_preempt_helper to
amdgpu_userq_restore_helper/amdgpu_userq_preempt_helper for consistency. (Alex)

v3: amdgpu_userq_stop_sched_for_enforce_isolation() and
amdgpu_userq_start_sched_for_enforce_isolation() should use preempt and restore (Alex)

Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarJesse Zhang <Jesse.Zhang@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 5cefcbb3
Loading
Loading
Loading
Loading
+48 −5
Original line number Diff line number Diff line
@@ -77,7 +77,7 @@ int amdgpu_userq_input_va_validate(struct amdgpu_vm *vm, u64 addr,
}

static int
amdgpu_userq_unmap_helper(struct amdgpu_userq_mgr *uq_mgr,
amdgpu_userq_preempt_helper(struct amdgpu_userq_mgr *uq_mgr,
			  struct amdgpu_usermode_queue *queue)
{
	struct amdgpu_device *adev = uq_mgr->adev;
@@ -86,6 +86,49 @@ amdgpu_userq_unmap_helper(struct amdgpu_userq_mgr *uq_mgr,
	int r = 0;

	if (queue->state == AMDGPU_USERQ_STATE_MAPPED) {
		r = userq_funcs->preempt(uq_mgr, queue);
		if (r) {
			queue->state = AMDGPU_USERQ_STATE_HUNG;
		} else {
			queue->state = AMDGPU_USERQ_STATE_PREEMPTED;
		}
	}

	return r;
}

static int
amdgpu_userq_restore_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_PREEMPTED) {
		r = userq_funcs->restore(uq_mgr, queue);
		if (r) {
			queue->state = AMDGPU_USERQ_STATE_HUNG;
		} else {
			queue->state = AMDGPU_USERQ_STATE_MAPPED;
		}
	}

	return r;
}

static int
amdgpu_userq_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) ||
		(queue->state == AMDGPU_USERQ_STATE_PREEMPTED)) {
		r = userq_funcs->unmap(uq_mgr, queue);
		if (r)
			queue->state = AMDGPU_USERQ_STATE_HUNG;
@@ -653,7 +696,7 @@ amdgpu_userq_restore_all(struct amdgpu_userq_mgr *uq_mgr)

	/* Resume all the queues for this process */
	idr_for_each_entry(&uq_mgr->userq_idr, queue, queue_id) {
		r = amdgpu_userq_map_helper(uq_mgr, queue);
		r = amdgpu_userq_restore_helper(uq_mgr, queue);
		if (r)
			ret = r;
	}
@@ -810,7 +853,7 @@ amdgpu_userq_evict_all(struct amdgpu_userq_mgr *uq_mgr)

	/* Try to unmap all the queues in this process ctx */
	idr_for_each_entry(&uq_mgr->userq_idr, queue, queue_id) {
		r = amdgpu_userq_unmap_helper(uq_mgr, queue);
		r = amdgpu_userq_preempt_helper(uq_mgr, queue);
		if (r)
			ret = r;
	}
@@ -995,7 +1038,7 @@ 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)) {
				r = amdgpu_userq_unmap_helper(uqm, queue);
				r = amdgpu_userq_preempt_helper(uqm, queue);
				if (r)
					ret = r;
			}
@@ -1029,7 +1072,7 @@ 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)) {
				r = amdgpu_userq_map_helper(uqm, queue);
				r = amdgpu_userq_restore_helper(uqm, queue);
				if (r)
					ret = r;
			}