Commit ae303004 authored by Chris Wilson's avatar Chris Wilson

drm/i915: Specialise i915_active.work lock classes

Similar to for i915_active.mutex, we require each class of i915_active
to have distinct lockdep chains as some, but by no means all,
i915_active are used within the shrinker and so have much more severe
usage constraints. By using a lockclass local to i915_active_init() all
i915_active workers have the same lock class, and we may generate false
positives when waiting for the i915_active. If we push the lockclass
into the caller, each class of i915_active will have distinct lockdep
chains.
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Acked-by: default avatarTvrtko Ursulin <tvrtko.ursulin@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20191202140133.2444217-1-chris@chris-wilson.co.uk
parent 7d0aa0db
...@@ -277,7 +277,8 @@ active_instance(struct i915_active *ref, struct intel_timeline *tl) ...@@ -277,7 +277,8 @@ active_instance(struct i915_active *ref, struct intel_timeline *tl)
void __i915_active_init(struct i915_active *ref, void __i915_active_init(struct i915_active *ref,
int (*active)(struct i915_active *ref), int (*active)(struct i915_active *ref),
void (*retire)(struct i915_active *ref), void (*retire)(struct i915_active *ref),
struct lock_class_key *key) struct lock_class_key *mkey,
struct lock_class_key *wkey)
{ {
unsigned long bits; unsigned long bits;
...@@ -295,9 +296,12 @@ void __i915_active_init(struct i915_active *ref, ...@@ -295,9 +296,12 @@ void __i915_active_init(struct i915_active *ref,
init_llist_head(&ref->preallocated_barriers); init_llist_head(&ref->preallocated_barriers);
atomic_set(&ref->count, 0); atomic_set(&ref->count, 0);
__mutex_init(&ref->mutex, "i915_active", key); __mutex_init(&ref->mutex, "i915_active", mkey);
__i915_active_fence_init(&ref->excl, NULL, excl_retire); __i915_active_fence_init(&ref->excl, NULL, excl_retire);
INIT_WORK(&ref->work, active_work); INIT_WORK(&ref->work, active_work);
#if IS_ENABLED(CONFIG_LOCKDEP)
lockdep_init_map(&ref->work.lockdep_map, "i915_active.work", wkey, 0);
#endif
} }
static bool ____active_del_barrier(struct i915_active *ref, static bool ____active_del_barrier(struct i915_active *ref,
......
...@@ -152,11 +152,15 @@ i915_active_fence_isset(const struct i915_active_fence *active) ...@@ -152,11 +152,15 @@ i915_active_fence_isset(const struct i915_active_fence *active)
void __i915_active_init(struct i915_active *ref, void __i915_active_init(struct i915_active *ref,
int (*active)(struct i915_active *ref), int (*active)(struct i915_active *ref),
void (*retire)(struct i915_active *ref), void (*retire)(struct i915_active *ref),
struct lock_class_key *key); struct lock_class_key *mkey,
struct lock_class_key *wkey);
/* Specialise each class of i915_active to avoid impossible lockdep cycles. */
#define i915_active_init(ref, active, retire) do { \ #define i915_active_init(ref, active, retire) do { \
static struct lock_class_key __key; \ static struct lock_class_key __mkey; \
static struct lock_class_key __wkey; \
\ \
__i915_active_init(ref, active, retire, &__key); \ __i915_active_init(ref, active, retire, &__mkey, &__wkey); \
} while (0) } while (0)
int i915_active_ref(struct i915_active *ref, int i915_active_ref(struct i915_active *ref,
......
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