Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/i915: Give each sw_fence its own lockclass

Localise the static struct lock_class_key to the caller of
i915_sw_fence_init() so that we create a lock_class instance for each
unique sw_fence rather than all sw_fences sharing the same
lock_class. This eliminate some lockdep false positive when using fences
from within fence callbacks.

For the relatively small number of fences currently in use [2], this adds
160 bytes of unused text/code when lockdep is disabled. This seems
quite high, but fully reducing it via ifdeffery is also quite ugly.
Removing the #fence strings saves 72 bytes with just a single #ifdef.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20161114204105.29171-1-chris@chris-wilson.co.uk

+21 -3
+5 -2
drivers/gpu/drm/i915/i915_sw_fence.c
··· 116 116 WARN_ON(atomic_inc_return(&fence->pending) <= 1); 117 117 } 118 118 119 - void i915_sw_fence_init(struct i915_sw_fence *fence, i915_sw_fence_notify_t fn) 119 + void __i915_sw_fence_init(struct i915_sw_fence *fence, 120 + i915_sw_fence_notify_t fn, 121 + const char *name, 122 + struct lock_class_key *key) 120 123 { 121 124 BUG_ON((unsigned long)fn & ~I915_SW_FENCE_MASK); 122 125 123 - init_waitqueue_head(&fence->wait); 126 + __init_waitqueue_head(&fence->wait, name, key); 124 127 kref_init(&fence->kref); 125 128 atomic_set(&fence->pending, 1); 126 129 fence->flags = (unsigned long)fn;
+16 -1
drivers/gpu/drm/i915/i915_sw_fence.h
··· 40 40 enum i915_sw_fence_notify state); 41 41 #define __i915_sw_fence_call __aligned(4) 42 42 43 - void i915_sw_fence_init(struct i915_sw_fence *fence, i915_sw_fence_notify_t fn); 43 + void __i915_sw_fence_init(struct i915_sw_fence *fence, 44 + i915_sw_fence_notify_t fn, 45 + const char *name, 46 + struct lock_class_key *key); 47 + #ifdef CONFIG_LOCKDEP 48 + #define i915_sw_fence_init(fence, fn) \ 49 + do { \ 50 + static struct lock_class_key __key; \ 51 + \ 52 + __i915_sw_fence_init((fence), (fn), #fence, &__key); \ 53 + } while (0) 54 + #else 55 + #define i915_sw_fence_init(fence, fn) \ 56 + __i915_sw_fence_init((fence), (fn), NULL, NULL) 57 + #endif 58 + 44 59 void i915_sw_fence_commit(struct i915_sw_fence *fence); 45 60 46 61 int i915_sw_fence_await_sw_fence(struct i915_sw_fence *fence,