Skip to content

Commit

Permalink
drm/i915/execlists: Handle copying default context state for atomic r…
Browse files Browse the repository at this point in the history
…eset

We want to be able to reset the GPU from inside a timer callback
(hardirq context). One step requires us to copy the default context
state over to the guilty context, which means we need to plan in advance
to have that object accessible from within an atomic context. The atomic
context prevents us from pinning the object or from peeking into the
shmemfs backing store (all may sleep), so we choose to pin the
default_state into memory when the engine becomes active. This
compromise allows us to swap out the default state when idle, when
required.

References: 5692251 ("drm/i915/lrc: Scrub the GPU state of the guilty hanging request")
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180518090212.5349-2-chris@chris-wilson.co.uk
  • Loading branch information
Chris Wilson committed May 19, 2018
1 parent d6d12ec commit fe0c493
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 11 deletions.
15 changes: 15 additions & 0 deletions drivers/gpu/drm/i915/intel_engine_cs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1091,6 +1091,11 @@ void intel_engines_park(struct drm_i915_private *i915)
if (engine->park)
engine->park(engine);

if (engine->pinned_default_state) {
i915_gem_object_unpin_map(engine->default_state);
engine->pinned_default_state = NULL;
}

i915_gem_batch_pool_fini(&engine->batch_pool);
engine->execlists.no_priolist = false;
}
Expand All @@ -1108,6 +1113,16 @@ void intel_engines_unpark(struct drm_i915_private *i915)
enum intel_engine_id id;

for_each_engine(engine, i915, id) {
void *map;

/* Pin the default state for fast resets from atomic context. */
map = NULL;
if (engine->default_state)
map = i915_gem_object_pin_map(engine->default_state,
I915_MAP_WB);
if (!IS_ERR_OR_NULL(map))
engine->pinned_default_state = map;

if (engine->unpark)
engine->unpark(engine);

Expand Down
15 changes: 4 additions & 11 deletions drivers/gpu/drm/i915/intel_lrc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1965,17 +1965,10 @@ static void execlists_reset(struct intel_engine_cs *engine,
* to recreate its own state.
*/
regs = request->hw_context->lrc_reg_state;
if (engine->default_state) {
void *defaults;

defaults = i915_gem_object_pin_map(engine->default_state,
I915_MAP_WB);
if (!IS_ERR(defaults)) {
memcpy(regs, /* skip restoring the vanilla PPHWSP */
defaults + LRC_STATE_PN * PAGE_SIZE,
engine->context_size - PAGE_SIZE);
i915_gem_object_unpin_map(engine->default_state);
}
if (engine->pinned_default_state) {
memcpy(regs, /* skip restoring the vanilla PPHWSP */
engine->pinned_default_state + LRC_STATE_PN * PAGE_SIZE,
engine->context_size - PAGE_SIZE);
}
execlists_init_reg_state(regs,
request->gem_context, engine, request->ring);
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/i915/intel_ringbuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,7 @@ struct intel_engine_cs {
struct i915_timeline timeline;

struct drm_i915_gem_object *default_state;
void *pinned_default_state;

atomic_t irq_count;
unsigned long irq_posted;
Expand Down

0 comments on commit fe0c493

Please sign in to comment.