Skip to content

Commit

Permalink
drm/i915/execlists: Flush tasklet directly from reset-finish
Browse files Browse the repository at this point in the history
On finishing the reset, the intention is to restart the GPU before we
relinquish the forcewake taken to handle the reset - the goal being the
GPU reloads a context before it is allowed to sleep. For this purpose,
we used tasklet_flush() which although it accomplished the goal of
restarting the GPU, carried with it a sting in its tail: it cleared the
TASKLET_STATE_SCHED bit. This meant that if another CPU queued a new
request to this engine, we would clear the flag and later attempt to
requeue the tasklet on the local CPU, breaking the per-cpu softirq
lists.

Remove the dangerous tasklet_kill() and just run the tasklet func
directly as we know it is safe to do so (the tasklets are internally
locked to allow mixed usage from direct submission).

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Cc: Mika Kuoppala <mika.kuoppala@intel.com>
Cc: Michel Thierry <michel.thierry@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Reviewed-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180828152702.27536-1-chris@chris-wilson.co.uk
  • Loading branch information
Chris Wilson committed Aug 29, 2018
1 parent d8c5d29 commit 9e4fa01
Show file tree
Hide file tree
Showing 2 changed files with 6 additions and 17 deletions.
6 changes: 0 additions & 6 deletions drivers/gpu/drm/i915/i915_gem.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,6 @@ static inline void __tasklet_disable_sync_once(struct tasklet_struct *t)
tasklet_unlock_wait(t);
}

static inline void __tasklet_enable_sync_once(struct tasklet_struct *t)
{
if (atomic_dec_return(&t->count) == 0)
tasklet_kill(t);
}

static inline bool __tasklet_is_enabled(const struct tasklet_struct *t)
{
return !atomic_read(&t->count);
Expand Down
17 changes: 6 additions & 11 deletions drivers/gpu/drm/i915/intel_lrc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1962,21 +1962,16 @@ static void execlists_reset_finish(struct intel_engine_cs *engine)
{
struct intel_engine_execlists * const execlists = &engine->execlists;

/* After a GPU reset, we may have requests to replay */
if (!RB_EMPTY_ROOT(&execlists->queue.rb_root))
tasklet_schedule(&execlists->tasklet);

/*
* Flush the tasklet while we still have the forcewake to be sure
* that it is not allowed to sleep before we restart and reload a
* context.
* After a GPU reset, we may have requests to replay. Do so now while
* we still have the forcewake to be sure that the GPU is not allowed
* to sleep before we restart and reload a context.
*
* As before (with execlists_reset_prepare) we rely on the caller
* serialising multiple attempts to reset so that we know that we
* are the only one manipulating tasklet state.
*/
__tasklet_enable_sync_once(&execlists->tasklet);
if (!RB_EMPTY_ROOT(&execlists->queue.rb_root))
execlists->tasklet.func(execlists->tasklet.data);

tasklet_enable(&execlists->tasklet);
GEM_TRACE("%s: depth->%d\n", engine->name,
atomic_read(&execlists->tasklet.count));
}
Expand Down

0 comments on commit 9e4fa01

Please sign in to comment.