Commit e28860ae authored by Chris Wilson's avatar Chris Wilson Committed by Joonas Lahtinen

drm/i915: Make the stale cached active node available for any timeline

Rather than require the next timeline after idling to match the MRU
before idling, reset the index on the node and allow it to match the
first request. However, this requires cmpxchg(u64) and so is not trivial
on 32b, so for compatibility we just fallback to keeping the cached node
pointing to the MRU timeline.
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: default avatarThomas Hellström <thomas.hellstrom@intel.com>
Reviewed-by: default avatarTvrtko Ursulin <tvrtko.ursulin@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200731085015.32368-5-chris@chris-wilson.co.ukSigned-off-by: default avatarRodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: default avatarJoonas Lahtinen <joonas.lahtinen@linux.intel.com>
parent 99a7f4da
...@@ -157,6 +157,10 @@ __active_retire(struct i915_active *ref) ...@@ -157,6 +157,10 @@ __active_retire(struct i915_active *ref)
rb_link_node(&ref->cache->node, NULL, &ref->tree.rb_node); rb_link_node(&ref->cache->node, NULL, &ref->tree.rb_node);
rb_insert_color(&ref->cache->node, &ref->tree); rb_insert_color(&ref->cache->node, &ref->tree);
GEM_BUG_ON(ref->tree.rb_node != &ref->cache->node); GEM_BUG_ON(ref->tree.rb_node != &ref->cache->node);
/* Make the cached node available for reuse with any timeline */
if (IS_ENABLED(CONFIG_64BIT))
ref->cache->timeline = 0; /* needs cmpxchg(u64) */
} }
spin_unlock_irqrestore(&ref->tree_lock, flags); spin_unlock_irqrestore(&ref->tree_lock, flags);
...@@ -235,6 +239,8 @@ static struct active_node *__active_lookup(struct i915_active *ref, u64 idx) ...@@ -235,6 +239,8 @@ static struct active_node *__active_lookup(struct i915_active *ref, u64 idx)
{ {
struct active_node *it; struct active_node *it;
GEM_BUG_ON(idx == 0); /* 0 is the unordered timeline, rsvd for cache */
/* /*
* We track the most recently used timeline to skip a rbtree search * We track the most recently used timeline to skip a rbtree search
* for the common case, under typical loads we never need the rbtree * for the common case, under typical loads we never need the rbtree
...@@ -243,8 +249,28 @@ static struct active_node *__active_lookup(struct i915_active *ref, u64 idx) ...@@ -243,8 +249,28 @@ static struct active_node *__active_lookup(struct i915_active *ref, u64 idx)
* current timeline. * current timeline.
*/ */
it = READ_ONCE(ref->cache); it = READ_ONCE(ref->cache);
if (it && it->timeline == idx) if (it) {
u64 cached = READ_ONCE(it->timeline);
/* Once claimed, this slot will only belong to this idx */
if (cached == idx)
return it;
#ifdef CONFIG_64BIT /* for cmpxchg(u64) */
/*
* An unclaimed cache [.timeline=0] can only be claimed once.
*
* If the value is already non-zero, some other thread has
* claimed the cache and we know that is does not match our
* idx. If, and only if, the timeline is currently zero is it
* worth competing to claim it atomically for ourselves (for
* only the winner of that race will cmpxchg return the old
* value of 0).
*/
if (!cached && !cmpxchg(&it->timeline, 0, idx))
return it; return it;
#endif
}
BUILD_BUG_ON(offsetof(typeof(*it), node)); BUILD_BUG_ON(offsetof(typeof(*it), node));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment