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

Configure Feed

Select the types of activity you want to include in your feed.

kernel/locking: Add context to ww_mutex_trylock()

i915 will soon gain an eviction path that trylock a whole lot of locks
for eviction, getting dmesg failures like below:

BUG: MAX_LOCK_DEPTH too low!
turning off the locking correctness validator.
depth: 48 max: 48!
48 locks held by i915_selftest/5776:
#0: ffff888101a79240 (&dev->mutex){....}-{3:3}, at: __driver_attach+0x88/0x160
#1: ffffc900009778c0 (reservation_ww_class_acquire){+.+.}-{0:0}, at: i915_vma_pin.constprop.63+0x39/0x1b0 [i915]
#2: ffff88800cf74de8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_vma_pin.constprop.63+0x5f/0x1b0 [i915]
#3: ffff88810c7f9e38 (&vm->mutex/1){+.+.}-{3:3}, at: i915_vma_pin_ww+0x1c4/0x9d0 [i915]
#4: ffff88810bad5768 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
#5: ffff88810bad60e8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
...
#46: ffff88811964d768 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
#47: ffff88811964e0e8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
INFO: lockdep is turned off.

Fixing eviction to nest into ww_class_acquire is a high priority, but
it requires a rework of the entire driver, which can only be done one
step at a time.

As an intermediate solution, add an acquire context to
ww_mutex_trylock, which allows us to do proper nesting annotations on
the trylocks, making the above lockdep splat disappear.

This is also useful in regulator_lock_nested, which may avoid dropping
regulator_nesting_mutex in the uncontended path, so use it there.

TTM may be another user for this, where we could lock a buffer in a
fastpath with list locks held, without dropping all locks we hold.

[peterz: rework actual ww_mutex_trylock() implementations]
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lkml.kernel.org/r/YUBGPdDDjKlxAuXJ@hirez.programming.kicks-ass.net

authored by

Maarten Lankhorst and committed by
Peter Zijlstra
12235da8 6880fa6c

+137 -38
+1 -1
drivers/gpu/drm/drm_modeset_lock.c
··· 248 248 if (ctx->trylock_only) { 249 249 lockdep_assert_held(&ctx->ww_ctx); 250 250 251 - if (!ww_mutex_trylock(&lock->mutex)) 251 + if (!ww_mutex_trylock(&lock->mutex, NULL)) 252 252 return -EBUSY; 253 253 else 254 254 return 0;
+1 -1
drivers/regulator/core.c
··· 145 145 146 146 mutex_lock(&regulator_nesting_mutex); 147 147 148 - if (ww_ctx || !ww_mutex_trylock(&rdev->mutex)) { 148 + if (!ww_mutex_trylock(&rdev->mutex, ww_ctx)) { 149 149 if (rdev->mutex_owner == current) 150 150 rdev->ref_cnt++; 151 151 else
+1 -1
include/linux/dma-resv.h
··· 173 173 */ 174 174 static inline bool __must_check dma_resv_trylock(struct dma_resv *obj) 175 175 { 176 - return ww_mutex_trylock(&obj->lock); 176 + return ww_mutex_trylock(&obj->lock, NULL); 177 177 } 178 178 179 179 /**
+2 -13
include/linux/ww_mutex.h
··· 28 28 #ifndef CONFIG_PREEMPT_RT 29 29 #define WW_MUTEX_BASE mutex 30 30 #define ww_mutex_base_init(l,n,k) __mutex_init(l,n,k) 31 - #define ww_mutex_base_trylock(l) mutex_trylock(l) 32 31 #define ww_mutex_base_is_locked(b) mutex_is_locked((b)) 33 32 #else 34 33 #define WW_MUTEX_BASE rt_mutex 35 34 #define ww_mutex_base_init(l,n,k) __rt_mutex_init(l,n,k) 36 - #define ww_mutex_base_trylock(l) rt_mutex_trylock(l) 37 35 #define ww_mutex_base_is_locked(b) rt_mutex_base_is_locked(&(b)->rtmutex) 38 36 #endif 39 37 ··· 337 339 338 340 extern void ww_mutex_unlock(struct ww_mutex *lock); 339 341 340 - /** 341 - * ww_mutex_trylock - tries to acquire the w/w mutex without acquire context 342 - * @lock: mutex to lock 343 - * 344 - * Trylocks a mutex without acquire context, so no deadlock detection is 345 - * possible. Returns 1 if the mutex has been acquired successfully, 0 otherwise. 346 - */ 347 - static inline int __must_check ww_mutex_trylock(struct ww_mutex *lock) 348 - { 349 - return ww_mutex_base_trylock(&lock->base); 350 - } 342 + extern int __must_check ww_mutex_trylock(struct ww_mutex *lock, 343 + struct ww_acquire_ctx *ctx); 351 344 352 345 /*** 353 346 * ww_mutex_destroy - mark a w/w mutex unusable
+41
kernel/locking/mutex.c
··· 94 94 return owner & MUTEX_FLAGS; 95 95 } 96 96 97 + /* 98 + * Returns: __mutex_owner(lock) on failure or NULL on success. 99 + */ 97 100 static inline struct task_struct *__mutex_trylock_common(struct mutex *lock, bool handoff) 98 101 { 99 102 unsigned long owner, curr = (unsigned long)current; ··· 738 735 { 739 736 return __mutex_lock_common(lock, state, subclass, NULL, ip, ww_ctx, true); 740 737 } 738 + 739 + /** 740 + * ww_mutex_trylock - tries to acquire the w/w mutex with optional acquire context 741 + * @ww: mutex to lock 742 + * @ww_ctx: optional w/w acquire context 743 + * 744 + * Trylocks a mutex with the optional acquire context; no deadlock detection is 745 + * possible. Returns 1 if the mutex has been acquired successfully, 0 otherwise. 746 + * 747 + * Unlike ww_mutex_lock, no deadlock handling is performed. However, if a @ctx is 748 + * specified, -EALREADY handling may happen in calls to ww_mutex_trylock. 749 + * 750 + * A mutex acquired with this function must be released with ww_mutex_unlock. 751 + */ 752 + int ww_mutex_trylock(struct ww_mutex *ww, struct ww_acquire_ctx *ww_ctx) 753 + { 754 + if (!ww_ctx) 755 + return mutex_trylock(&ww->base); 756 + 757 + MUTEX_WARN_ON(ww->base.magic != &ww->base); 758 + 759 + /* 760 + * Reset the wounded flag after a kill. No other process can 761 + * race and wound us here, since they can't have a valid owner 762 + * pointer if we don't have any locks held. 763 + */ 764 + if (ww_ctx->acquired == 0) 765 + ww_ctx->wounded = 0; 766 + 767 + if (__mutex_trylock(&ww->base)) { 768 + ww_mutex_set_context_fastpath(ww, ww_ctx); 769 + mutex_acquire_nest(&ww->base.dep_map, 0, 1, &ww_ctx->dep_map, _RET_IP_); 770 + return 1; 771 + } 772 + 773 + return 0; 774 + } 775 + EXPORT_SYMBOL(ww_mutex_trylock); 741 776 742 777 #ifdef CONFIG_DEBUG_LOCK_ALLOC 743 778 void __sched
+65 -21
kernel/locking/test-ww_mutex.c
··· 16 16 static DEFINE_WD_CLASS(ww_class); 17 17 struct workqueue_struct *wq; 18 18 19 + #ifdef CONFIG_DEBUG_WW_MUTEX_SLOWPATH 20 + #define ww_acquire_init_noinject(a, b) do { \ 21 + ww_acquire_init((a), (b)); \ 22 + (a)->deadlock_inject_countdown = ~0U; \ 23 + } while (0) 24 + #else 25 + #define ww_acquire_init_noinject(a, b) ww_acquire_init((a), (b)) 26 + #endif 27 + 19 28 struct test_mutex { 20 29 struct work_struct work; 21 30 struct ww_mutex mutex; ··· 45 36 wait_for_completion(&mtx->go); 46 37 47 38 if (mtx->flags & TEST_MTX_TRY) { 48 - while (!ww_mutex_trylock(&mtx->mutex)) 39 + while (!ww_mutex_trylock(&mtx->mutex, NULL)) 49 40 cond_resched(); 50 41 } else { 51 42 ww_mutex_lock(&mtx->mutex, NULL); ··· 118 109 return 0; 119 110 } 120 111 121 - static int test_aa(void) 112 + static int test_aa(bool trylock) 122 113 { 123 114 struct ww_mutex mutex; 124 115 struct ww_acquire_ctx ctx; 125 116 int ret; 117 + const char *from = trylock ? "trylock" : "lock"; 126 118 127 119 ww_mutex_init(&mutex, &ww_class); 128 120 ww_acquire_init(&ctx, &ww_class); 129 121 130 - ww_mutex_lock(&mutex, &ctx); 122 + if (!trylock) { 123 + ret = ww_mutex_lock(&mutex, &ctx); 124 + if (ret) { 125 + pr_err("%s: initial lock failed!\n", __func__); 126 + goto out; 127 + } 128 + } else { 129 + if (!ww_mutex_trylock(&mutex, &ctx)) { 130 + pr_err("%s: initial trylock failed!\n", __func__); 131 + goto out; 132 + } 133 + } 131 134 132 - if (ww_mutex_trylock(&mutex)) { 133 - pr_err("%s: trylocked itself!\n", __func__); 135 + if (ww_mutex_trylock(&mutex, NULL)) { 136 + pr_err("%s: trylocked itself without context from %s!\n", __func__, from); 137 + ww_mutex_unlock(&mutex); 138 + ret = -EINVAL; 139 + goto out; 140 + } 141 + 142 + if (ww_mutex_trylock(&mutex, &ctx)) { 143 + pr_err("%s: trylocked itself with context from %s!\n", __func__, from); 134 144 ww_mutex_unlock(&mutex); 135 145 ret = -EINVAL; 136 146 goto out; ··· 157 129 158 130 ret = ww_mutex_lock(&mutex, &ctx); 159 131 if (ret != -EALREADY) { 160 - pr_err("%s: missed deadlock for recursing, ret=%d\n", 161 - __func__, ret); 132 + pr_err("%s: missed deadlock for recursing, ret=%d from %s\n", 133 + __func__, ret, from); 162 134 if (!ret) 163 135 ww_mutex_unlock(&mutex); 164 136 ret = -EINVAL; 165 137 goto out; 166 138 } 167 139 140 + ww_mutex_unlock(&mutex); 168 141 ret = 0; 169 142 out: 170 - ww_mutex_unlock(&mutex); 171 143 ww_acquire_fini(&ctx); 172 144 return ret; 173 145 } ··· 178 150 struct ww_mutex b_mutex; 179 151 struct completion a_ready; 180 152 struct completion b_ready; 181 - bool resolve; 153 + bool resolve, trylock; 182 154 int result; 183 155 }; 184 156 ··· 188 160 struct ww_acquire_ctx ctx; 189 161 int err; 190 162 191 - ww_acquire_init(&ctx, &ww_class); 192 - ww_mutex_lock(&abba->b_mutex, &ctx); 163 + ww_acquire_init_noinject(&ctx, &ww_class); 164 + if (!abba->trylock) 165 + ww_mutex_lock(&abba->b_mutex, &ctx); 166 + else 167 + WARN_ON(!ww_mutex_trylock(&abba->b_mutex, &ctx)); 168 + 169 + WARN_ON(READ_ONCE(abba->b_mutex.ctx) != &ctx); 193 170 194 171 complete(&abba->b_ready); 195 172 wait_for_completion(&abba->a_ready); ··· 214 181 abba->result = err; 215 182 } 216 183 217 - static int test_abba(bool resolve) 184 + static int test_abba(bool trylock, bool resolve) 218 185 { 219 186 struct test_abba abba; 220 187 struct ww_acquire_ctx ctx; ··· 225 192 INIT_WORK_ONSTACK(&abba.work, test_abba_work); 226 193 init_completion(&abba.a_ready); 227 194 init_completion(&abba.b_ready); 195 + abba.trylock = trylock; 228 196 abba.resolve = resolve; 229 197 230 198 schedule_work(&abba.work); 231 199 232 - ww_acquire_init(&ctx, &ww_class); 233 - ww_mutex_lock(&abba.a_mutex, &ctx); 200 + ww_acquire_init_noinject(&ctx, &ww_class); 201 + if (!trylock) 202 + ww_mutex_lock(&abba.a_mutex, &ctx); 203 + else 204 + WARN_ON(!ww_mutex_trylock(&abba.a_mutex, &ctx)); 205 + 206 + WARN_ON(READ_ONCE(abba.a_mutex.ctx) != &ctx); 234 207 235 208 complete(&abba.a_ready); 236 209 wait_for_completion(&abba.b_ready); ··· 288 249 struct ww_acquire_ctx ctx; 289 250 int err, erra = 0; 290 251 291 - ww_acquire_init(&ctx, &ww_class); 252 + ww_acquire_init_noinject(&ctx, &ww_class); 292 253 ww_mutex_lock(&cycle->a_mutex, &ctx); 293 254 294 255 complete(cycle->a_signal); ··· 620 581 static int __init test_ww_mutex_init(void) 621 582 { 622 583 int ncpus = num_online_cpus(); 623 - int ret; 584 + int ret, i; 585 + 586 + printk(KERN_INFO "Beginning ww mutex selftests\n"); 624 587 625 588 wq = alloc_workqueue("test-ww_mutex", WQ_UNBOUND, 0); 626 589 if (!wq) ··· 632 591 if (ret) 633 592 return ret; 634 593 635 - ret = test_aa(); 594 + ret = test_aa(false); 636 595 if (ret) 637 596 return ret; 638 597 639 - ret = test_abba(false); 598 + ret = test_aa(true); 640 599 if (ret) 641 600 return ret; 642 601 643 - ret = test_abba(true); 644 - if (ret) 645 - return ret; 602 + for (i = 0; i < 4; i++) { 603 + ret = test_abba(i & 1, i & 2); 604 + if (ret) 605 + return ret; 606 + } 646 607 647 608 ret = test_cycle(ncpus); 648 609 if (ret) ··· 662 619 if (ret) 663 620 return ret; 664 621 622 + printk(KERN_INFO "All ww mutex selftests passed\n"); 665 623 return 0; 666 624 } 667 625
+25
kernel/locking/ww_rt_mutex.c
··· 9 9 #define WW_RT 10 10 #include "rtmutex.c" 11 11 12 + int ww_mutex_trylock(struct ww_mutex *lock, struct ww_acquire_ctx *ww_ctx) 13 + { 14 + struct rt_mutex *rtm = &lock->base; 15 + 16 + if (!ww_ctx) 17 + return rt_mutex_trylock(rtm); 18 + 19 + /* 20 + * Reset the wounded flag after a kill. No other process can 21 + * race and wound us here, since they can't have a valid owner 22 + * pointer if we don't have any locks held. 23 + */ 24 + if (ww_ctx->acquired == 0) 25 + ww_ctx->wounded = 0; 26 + 27 + if (__rt_mutex_trylock(&rtm->rtmutex)) { 28 + ww_mutex_set_context_fastpath(lock, ww_ctx); 29 + mutex_acquire_nest(&rtm->dep_map, 0, 1, ww_ctx->dep_map, _RET_IP_); 30 + return 1; 31 + } 32 + 33 + return 0; 34 + } 35 + EXPORT_SYMBOL(ww_mutex_trylock); 36 + 12 37 static int __sched 13 38 __ww_rt_mutex_lock(struct ww_mutex *lock, struct ww_acquire_ctx *ww_ctx, 14 39 unsigned int state, unsigned long ip)
+1 -1
lib/locking-selftest.c
··· 258 258 #define WWAF(x) ww_acquire_fini(x) 259 259 260 260 #define WWL(x, c) ww_mutex_lock(x, c) 261 - #define WWT(x) ww_mutex_trylock(x) 261 + #define WWT(x) ww_mutex_trylock(x, NULL) 262 262 #define WWL1(x) ww_mutex_lock(x, NULL) 263 263 #define WWU(x) ww_mutex_unlock(x) 264 264