Skip to content

Commit

Permalink
drm/i915/gt: Wait for new requests in intel_gt_retire_requests()
Browse files Browse the repository at this point in the history
Our callers fall into two categories, those passing timeout=0 who just
want to flush request retirements and those passing a timeout that need
to wait for submission completion (e.g. intel_gt_wait_for_idle()).
Currently, we only wait for a snapshot of timelines at the start of the
wait (but there was an expectation that new requests would cause timelines
to appear at the end). However, our callers, such as
intel_gt_wait_for_idle() before suspend, do require us to wait for the
power management requests emitted by retirement as well. If we don't,
then it takes an extra second or two for the background worker to flush
the queue and mark the GT as idle.

Fixes: 7e80576 ("drm/i915: Drop struct_mutex from around i915_retire_requests()")
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20191114225736.616885-1-chris@chris-wilson.co.uk
  • Loading branch information
Chris Wilson committed Nov 15, 2019
1 parent e205cee commit 7936a22
Showing 1 changed file with 3 additions and 8 deletions.
11 changes: 3 additions & 8 deletions drivers/gpu/drm/i915/gt/intel_gt_requests.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ long intel_gt_retire_requests_timeout(struct intel_gt *gt, long timeout)
{
struct intel_gt_timelines *timelines = &gt->timelines;
struct intel_timeline *tl, *tn;
unsigned long active_count = 0;
unsigned long flags;
bool interruptible;
LIST_HEAD(free);
Expand All @@ -46,10 +45,8 @@ long intel_gt_retire_requests_timeout(struct intel_gt *gt, long timeout)

spin_lock_irqsave(&timelines->lock, flags);
list_for_each_entry_safe(tl, tn, &timelines->active_list, link) {
if (!mutex_trylock(&tl->mutex)) {
active_count++; /* report busy to caller, try again? */
if (!mutex_trylock(&tl->mutex))
continue;
}

intel_timeline_get(tl);
GEM_BUG_ON(!tl->active_count);
Expand All @@ -74,9 +71,7 @@ long intel_gt_retire_requests_timeout(struct intel_gt *gt, long timeout)

/* Resume iteration after dropping lock */
list_safe_reset_next(tl, tn, link);
if (--tl->active_count)
active_count += !!rcu_access_pointer(tl->last_request.fence);
else
if (!--tl->active_count)
list_del(&tl->link);

mutex_unlock(&tl->mutex);
Expand All @@ -92,7 +87,7 @@ long intel_gt_retire_requests_timeout(struct intel_gt *gt, long timeout)
list_for_each_entry_safe(tl, tn, &free, link)
__intel_timeline_free(&tl->kref);

return active_count ? timeout : 0;
return list_empty(&timelines->active_list) ? 0 : timeout;
}

int intel_gt_wait_for_idle(struct intel_gt *gt, long timeout)
Expand Down

0 comments on commit 7936a22

Please sign in to comment.