Skip to content

Commit

Permalink
drm/i915: Skip execlists_dequeue() early if the list is empty
Browse files Browse the repository at this point in the history
Do an early read of the execlists' queue before we take the spinlock and
start checking. This is safe as the first writer to the execlists queue
will cause the tasklet to be run again after a memory barrier.

v2: Keep guc in sync with execlists queue changes
v3: Explain the mb between the tasklet running on one cpu and the
execlist_first update and schedule from a second cpu.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Michał Winiarski <michal.winiarski@intel.com>
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
Reviewed-by: Michał Winiarski <michal.winiarski@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20170317120716.17191-1-chris@chris-wilson.co.uk
  • Loading branch information
Chris Wilson committed Mar 17, 2017
1 parent e637d2c commit 6c943de
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 0 deletions.
12 changes: 12 additions & 0 deletions drivers/gpu/drm/i915/i915_guc_submission.c
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,18 @@ static bool i915_guc_dequeue(struct intel_engine_cs *engine)
struct rb_node *rb;
bool submit = false;

/* After execlist_first is updated, the tasklet will be rescheduled.
*
* If we are currently running (inside the tasklet) and a third
* party queues a request and so updates engine->execlist_first under
* the spinlock (which we have elided), it will atomically set the
* TASKLET_SCHED flag causing the us to be re-executed and pick up
* the change in state (the update to TASKLET_SCHED incurs a memory
* barrier making this cross-cpu checking safe).
*/
if (!READ_ONCE(engine->execlist_first))
return false;

spin_lock_irqsave(&engine->timeline->lock, flags);
rb = engine->execlist_first;
while (rb) {
Expand Down
12 changes: 12 additions & 0 deletions drivers/gpu/drm/i915/intel_lrc.c
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,18 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
struct rb_node *rb;
bool submit = false;

/* After execlist_first is updated, the tasklet will be rescheduled.
*
* If we are currently running (inside the tasklet) and a third
* party queues a request and so updates engine->execlist_first under
* the spinlock (which we have elided), it will atomically set the
* TASKLET_SCHED flag causing the us to be re-executed and pick up
* the change in state (the update to TASKLET_SCHED incurs a memory
* barrier making this cross-cpu checking safe).
*/
if (!READ_ONCE(engine->execlist_first))
return;

last = port->request;
if (last)
/* WaIdleLiteRestore:bdw,skl
Expand Down

0 comments on commit 6c943de

Please sign in to comment.