Commit b97060a9 authored by Matthew Brost's avatar Matthew Brost Committed by John Harrison
Browse files

drm/i915/guc: Update intel_gt_wait_for_idle to work with GuC



When running the GuC the GPU can't be considered idle if the GuC still
has contexts pinned. As such, a call has been added in
intel_gt_wait_for_idle to idle the UC and in turn the GuC by waiting for
the number of unpinned contexts to go to zero.

v2: rtimeout -> remaining_timeout
v3: Drop unnecessary includes, guc_submission_busy_loop ->
guc_submission_send_busy_loop, drop negatie timeout trick, move a
refactor of guc_context_unpin to earlier path (John H)
v4: Add stddef.h back into intel_gt_requests.h, sort circuit idle
function if not in GuC submission mode

Cc: John Harrison <john.c.harrison@intel.com>
Signed-off-by: default avatarMatthew Brost <matthew.brost@intel.com>
Reviewed-by: default avatarJohn Harrison <John.C.Harrison@Intel.com>
Signed-off-by: default avatarJohn Harrison <John.C.Harrison@Intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210721215101.139794-16-matthew.brost@intel.com
parent f4eb1f3f
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -645,7 +645,8 @@ mmap_offset_attach(struct drm_i915_gem_object *obj,
		goto insert;

	/* Attempt to reap some mmap space from dead objects */
	err = intel_gt_retire_requests_timeout(&i915->gt, MAX_SCHEDULE_TIMEOUT);
	err = intel_gt_retire_requests_timeout(&i915->gt, MAX_SCHEDULE_TIMEOUT,
					       NULL);
	if (err)
		goto err;

+19 −0
Original line number Diff line number Diff line
@@ -585,6 +585,25 @@ static void __intel_gt_disable(struct intel_gt *gt)
	GEM_BUG_ON(intel_gt_pm_is_awake(gt));
}

int intel_gt_wait_for_idle(struct intel_gt *gt, long timeout)
{
	long remaining_timeout;

	/* If the device is asleep, we have no requests outstanding */
	if (!intel_gt_pm_is_awake(gt))
		return 0;

	while ((timeout = intel_gt_retire_requests_timeout(gt, timeout,
							   &remaining_timeout)) > 0) {
		cond_resched();
		if (signal_pending(current))
			return -EINTR;
	}

	return timeout ? timeout : intel_uc_wait_for_idle(&gt->uc,
							  remaining_timeout);
}

int intel_gt_init(struct intel_gt *gt)
{
	int err;
+2 −0
Original line number Diff line number Diff line
@@ -48,6 +48,8 @@ void intel_gt_driver_release(struct intel_gt *gt);

void intel_gt_driver_late_release(struct intel_gt *gt);

int intel_gt_wait_for_idle(struct intel_gt *gt, long timeout);

void intel_gt_check_and_clear_faults(struct intel_gt *gt);
void intel_gt_clear_error_registers(struct intel_gt *gt,
				    intel_engine_mask_t engine_mask);
+5 −16
Original line number Diff line number Diff line
@@ -130,7 +130,8 @@ void intel_engine_fini_retire(struct intel_engine_cs *engine)
	GEM_BUG_ON(engine->retire);
}

long intel_gt_retire_requests_timeout(struct intel_gt *gt, long timeout)
long intel_gt_retire_requests_timeout(struct intel_gt *gt, long timeout,
				      long *remaining_timeout)
{
	struct intel_gt_timelines *timelines = &gt->timelines;
	struct intel_timeline *tl, *tn;
@@ -195,22 +196,10 @@ out_active: spin_lock(&timelines->lock);
	if (flush_submission(gt, timeout)) /* Wait, there's more! */
		active_count++;

	return active_count ? timeout : 0;
}

int intel_gt_wait_for_idle(struct intel_gt *gt, long timeout)
{
	/* If the device is asleep, we have no requests outstanding */
	if (!intel_gt_pm_is_awake(gt))
		return 0;

	while ((timeout = intel_gt_retire_requests_timeout(gt, timeout)) > 0) {
		cond_resched();
		if (signal_pending(current))
			return -EINTR;
	}
	if (remaining_timeout)
		*remaining_timeout = timeout;

	return timeout;
	return active_count ? timeout : 0;
}

static void retire_work_handler(struct work_struct *work)
+5 −4
Original line number Diff line number Diff line
@@ -6,14 +6,17 @@
#ifndef INTEL_GT_REQUESTS_H
#define INTEL_GT_REQUESTS_H

#include <stddef.h>

struct intel_engine_cs;
struct intel_gt;
struct intel_timeline;

long intel_gt_retire_requests_timeout(struct intel_gt *gt, long timeout);
long intel_gt_retire_requests_timeout(struct intel_gt *gt, long timeout,
				      long *remaining_timeout);
static inline void intel_gt_retire_requests(struct intel_gt *gt)
{
	intel_gt_retire_requests_timeout(gt, 0);
	intel_gt_retire_requests_timeout(gt, 0, NULL);
}

void intel_engine_init_retire(struct intel_engine_cs *engine);
@@ -21,8 +24,6 @@ void intel_engine_add_retire(struct intel_engine_cs *engine,
			     struct intel_timeline *tl);
void intel_engine_fini_retire(struct intel_engine_cs *engine);

int intel_gt_wait_for_idle(struct intel_gt *gt, long timeout);

void intel_gt_init_requests(struct intel_gt *gt);
void intel_gt_park_requests(struct intel_gt *gt);
void intel_gt_unpark_requests(struct intel_gt *gt);
Loading