Commit ae303004 authored by Chris Wilson's avatar Chris Wilson
Browse files

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
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -277,7 +277,8 @@ active_instance(struct i915_active *ref, struct intel_timeline *tl)
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,
+7 −3
Original line number Diff line number Diff line
@@ -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,