drm/i915: Protect i915_active iterators from the shrinker
If we allocate while iterating the rbtree of active nodes, we may hit the shrinker and so retire the i915_active, reaping the rbtree. Modifying the rbtree as we iterate is not good behaviour, so acquire the i915_active first to keep the tree intact whenever we allocate. Fixes:a42375af0a
("drm/i915: Release the active tracker tree upon idling") Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20190208134704.23039-1-chris@chris-wilson.co.uk Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com> (cherry picked from commit312c4ba1bb
) Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
This commit is contained in:
parent
08f68752ce
commit
df069367f3
|
@ -163,17 +163,25 @@ int i915_active_ref(struct i915_active *ref,
|
|||
struct i915_request *rq)
|
||||
{
|
||||
struct i915_active_request *active;
|
||||
int err = 0;
|
||||
|
||||
/* Prevent reaping in case we malloc/wait while building the tree */
|
||||
i915_active_acquire(ref);
|
||||
|
||||
active = active_instance(ref, timeline);
|
||||
if (IS_ERR(active))
|
||||
return PTR_ERR(active);
|
||||
if (IS_ERR(active)) {
|
||||
err = PTR_ERR(active);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!i915_active_request_isset(active))
|
||||
ref->count++;
|
||||
__i915_active_request_set(active, rq);
|
||||
|
||||
GEM_BUG_ON(!ref->count);
|
||||
return 0;
|
||||
out:
|
||||
i915_active_release(ref);
|
||||
return err;
|
||||
}
|
||||
|
||||
bool i915_active_acquire(struct i915_active *ref)
|
||||
|
@ -223,19 +231,25 @@ int i915_request_await_active_request(struct i915_request *rq,
|
|||
int i915_request_await_active(struct i915_request *rq, struct i915_active *ref)
|
||||
{
|
||||
struct active_node *it, *n;
|
||||
int ret;
|
||||
int err = 0;
|
||||
|
||||
ret = i915_request_await_active_request(rq, &ref->last);
|
||||
if (ret)
|
||||
return ret;
|
||||
/* await allocates and so we need to avoid hitting the shrinker */
|
||||
if (i915_active_acquire(ref))
|
||||
goto out; /* was idle */
|
||||
|
||||
err = i915_request_await_active_request(rq, &ref->last);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
rbtree_postorder_for_each_entry_safe(it, n, &ref->tree, node) {
|
||||
ret = i915_request_await_active_request(rq, &it->base);
|
||||
if (ret)
|
||||
return ret;
|
||||
err = i915_request_await_active_request(rq, &it->base);
|
||||
if (err)
|
||||
goto out;
|
||||
}
|
||||
|
||||
return 0;
|
||||
out:
|
||||
i915_active_release(ref);
|
||||
return err;
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)
|
||||
|
|
Loading…
Reference in New Issue