diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2016-07-04 08:08:31 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2016-07-04 08:18:19 +0100 |
commit | 67d97da34917fb0b21af4c0942a6e03b4b10c094 (patch) | |
tree | d35d2ffbc0b6bb13277cb5c29d13e2c1b419bf09 /drivers/gpu/drm/i915/i915_irq.c | |
parent | 841149909abb4cf9038ba0a12f3bec711f3ce09b (diff) | |
download | lwn-67d97da34917fb0b21af4c0942a6e03b4b10c094.tar.gz lwn-67d97da34917fb0b21af4c0942a6e03b4b10c094.zip |
drm/i915: Only start retire worker when idle
The retire worker is a low frequency task that makes sure we retire
outstanding requests if userspace is being lax. We only need to start it
once as it remains active until the GPU is idle, so do a cheap test
before the more expensive queue_work(). A consequence of this is that we
need correct locking in the worker to make the hot path of request
submission cheap. To keep the symmetry and keep hangcheck strictly bound
by the GPU's wakelock, we move the cancel_sync(hangcheck) to the idle
worker before dropping the wakelock.
v2: Guard against RCU fouling the breadcrumbs bottom-half whilst we kick
the waiter.
v3: Remove the wakeref assertion squelching (now we hold a wakeref for
the hangcheck, any rpm error there is genuine).
v4: To prevent excess work when retiring requests, we split the busy
flag into two, a boolean to denote whether we hold the wakeref and a
bitmask of active engines.
v5: Reorder cancelling hangcheck upon idling to avoid a race where we
might cancel a hangcheck after being preempted by a new task
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
References: https://bugs.freedesktop.org/show_bug.cgi?id=88437
Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1467616119-4093-1-git-send-email-chris@chris-wilson.co.uk
Diffstat (limited to 'drivers/gpu/drm/i915/i915_irq.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_irq.c | 15 |
1 files changed, 3 insertions, 12 deletions
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 53d4c8088f28..80d162acda1b 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -3103,12 +3103,8 @@ static void i915_hangcheck_elapsed(struct work_struct *work) if (!i915.enable_hangcheck) return; - /* - * The hangcheck work is synced during runtime suspend, we don't - * require a wakeref. TODO: instead of disabling the asserts make - * sure that we hold a reference when this work is running. - */ - DISABLE_RPM_WAKEREF_ASSERTS(dev_priv); + if (!lockless_dereference(dev_priv->gt.awake)) + return; /* As enabling the GPU requires fairly extensive mmio access, * periodically arm the mmio checker to see if we are triggering @@ -3216,17 +3212,12 @@ static void i915_hangcheck_elapsed(struct work_struct *work) } } - if (rings_hung) { + if (rings_hung) i915_handle_error(dev_priv, rings_hung, "Engine(s) hung"); - goto out; - } /* Reset timer in case GPU hangs without another request being added */ if (busy_count) i915_queue_hangcheck(dev_priv); - -out: - ENABLE_RPM_WAKEREF_ASSERTS(dev_priv); } static void ibx_irq_reset(struct drm_device *dev) |