drm/i915: Specialise i915_active.work lock classes
authorChris Wilson <chris@chris-wilson.co.uk>
Mon, 2 Dec 2019 14:01:32 +0000 (14:01 +0000)
committerChris Wilson <chris@chris-wilson.co.uk>
Mon, 2 Dec 2019 21:57:23 +0000 (21:57 +0000)
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: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20191202140133.2444217-1-chris@chris-wilson.co.uk
drivers/gpu/drm/i915/i915_active.c
drivers/gpu/drm/i915/i915_active.h

index 479195e..e60e449 100644 (file)
@@ -277,7 +277,8 @@ out:
 void __i915_active_init(struct i915_active *ref,
                        int (*active)(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;
 
@@ -295,9 +296,12 @@ void __i915_active_init(struct i915_active *ref,
 
        init_llist_head(&ref->preallocated_barriers);
        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);
        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,
index 3208cc2..b571f67 100644 (file)
@@ -152,11 +152,15 @@ i915_active_fence_isset(const struct i915_active_fence *active)
 void __i915_active_init(struct i915_active *ref,
                        int (*active)(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 {             \
-       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)
 
 int i915_active_ref(struct i915_active *ref,