[Intel-gfx] [PATCH 06/12] drm/i915/scheduler: Execute requests in order of priorities
Chris Wilson
chris at chris-wilson.co.uk
Thu Nov 3 19:47:39 UTC 2016
On Thu, Nov 03, 2016 at 04:21:25PM +0000, Tvrtko Ursulin wrote:
> >+static void update_priorities(struct i915_priotree *pt, int prio)
> >+{
> >+ struct drm_i915_gem_request *request =
> >+ container_of(pt, struct drm_i915_gem_request, priotree);
> >+ struct intel_engine_cs *engine = request->engine;
> >+ struct i915_dependency *dep;
> >+
> >+ if (prio <= READ_ONCE(pt->priority))
> >+ return;
> >+
> >+ /* Recursively bump all dependent priorities to match the new request */
> >+ list_for_each_entry(dep, &pt->pre_list, pre_link)
> >+ update_priorities(dep->signal, prio);
>
> John got in trouble from recursion in his scheduler, used for the
> same thing AFAIR. Or was it the priority bumping? Either way, it
> could be imperative to avoid it.
static void update_priority(struct i915_priotree *pt, int prio)
{
struct drm_i915_gem_request *request =
container_of(pt, struct drm_i915_gem_request, priotree);
struct intel_engine_cs *engine = request->engine;
spin_lock_irq(&engine->timeline->lock);
if (prio > pt->priority) {
pt->priority = prio;
if (!RB_EMPTY_NODE(&pt->node)) {
rb_erase(&pt->node, &engine->execlist_queue);
if (insert_request(pt, &engine->execlist_queue))
engine->execlist_first = &pt->node;
}
}
spin_unlock_irq(&engine->timeline->lock);
}
static void execlists_schedule(struct drm_i915_gem_request *request, int prio)
{
struct i915_dependency *dep, *p;
LIST_HEAD(dfs);
if (prio <= READ_ONCE(request->priotree.priority))
return;
/* Need BKL in order to use the temporary link inside i915_dependency */
lockdep_assert_held(&request->i915->drm.struct_mutex);
/* Recursively bump all dependent priorities to match the new request */
list_for_each_entry(dep, &request->priotree.pre_list, pre_link)
if (prio > READ_ONCE(dep->signal->priority))
list_add_tail(&dep->dfs_link, &dfs);
list_for_each_entry(dep, &dfs, dfs_link) {
list_for_each_entry(p, &dep->signal->pre_list, pre_link) {
GEM_BUG_ON(p == dep);
if (prio > READ_ONCE(p->signal->priority))
list_move_tail(&p->dfs_link, &dfs);
}
}
/* Fifo and depth-first replacement ensure our deps execute before us */
list_for_each_entry_safe_reverse(dep, p, &dfs, dfs_link) {
update_priority(dep->signal, prio);
INIT_LIST_HEAD(&dep->dfs_link);
}
update_priority(&request->priotree, prio);
/* XXX Do we need to preempt to make room for us and our deps? */
}
Still ugh. I think that we don't chase beyond the priorities we need to
bump is its only saving grace.
-Chris
--
Chris Wilson, Intel Open Source Technology Centre
More information about the Intel-gfx
mailing list