linux_ww_mutex.c revision 1.12 1 /* $NetBSD: linux_ww_mutex.c,v 1.12 2021/12/24 15:25:03 riastradh Exp $ */
2
3 /*-
4 * Copyright (c) 2014 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Taylor R. Campbell.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: linux_ww_mutex.c,v 1.12 2021/12/24 15:25:03 riastradh Exp $");
34
35 #include <sys/types.h>
36 #include <sys/atomic.h>
37 #include <sys/condvar.h>
38 #include <sys/lockdebug.h>
39 #include <sys/lwp.h>
40 #include <sys/mutex.h>
41 #include <sys/rbtree.h>
42
43 #include <linux/ww_mutex.h>
44 #include <linux/errno.h>
45
46 #define WW_WANTLOCK(WW) \
47 LOCKDEBUG_WANTLOCK((WW)->wwm_debug, (WW), \
48 (uintptr_t)__builtin_return_address(0), 0)
49 #define WW_LOCKED(WW) \
50 LOCKDEBUG_LOCKED((WW)->wwm_debug, (WW), NULL, \
51 (uintptr_t)__builtin_return_address(0), 0)
52 #define WW_UNLOCKED(WW) \
53 LOCKDEBUG_UNLOCKED((WW)->wwm_debug, (WW), \
54 (uintptr_t)__builtin_return_address(0), 0)
55
56 static int
57 ww_acquire_ctx_compare(void *cookie __unused, const void *va, const void *vb)
58 {
59 const struct ww_acquire_ctx *const ctx_a = va;
60 const struct ww_acquire_ctx *const ctx_b = vb;
61
62 if (ctx_a->wwx_ticket < ctx_b->wwx_ticket)
63 return -1;
64 if (ctx_a->wwx_ticket > ctx_b->wwx_ticket)
65 return -1;
66 return 0;
67 }
68
69 static int
70 ww_acquire_ctx_compare_key(void *cookie __unused, const void *vn,
71 const void *vk)
72 {
73 const struct ww_acquire_ctx *const ctx = vn;
74 const uint64_t *const ticketp = vk, ticket = *ticketp;
75
76 if (ctx->wwx_ticket < ticket)
77 return -1;
78 if (ctx->wwx_ticket > ticket)
79 return -1;
80 return 0;
81 }
82
83 static const rb_tree_ops_t ww_acquire_ctx_rb_ops = {
84 .rbto_compare_nodes = &ww_acquire_ctx_compare,
85 .rbto_compare_key = &ww_acquire_ctx_compare_key,
86 .rbto_node_offset = offsetof(struct ww_acquire_ctx, wwx_rb_node),
87 .rbto_context = NULL,
88 };
89
90 void
91 ww_acquire_init(struct ww_acquire_ctx *ctx, struct ww_class *class)
92 {
93
94 ctx->wwx_class = class;
95 ctx->wwx_owner = curlwp;
96 ctx->wwx_ticket = atomic64_inc_return(&class->wwc_ticket);
97 ctx->wwx_acquired = 0;
98 ctx->wwx_acquire_done = false;
99 }
100
101 void
102 ww_acquire_done(struct ww_acquire_ctx *ctx)
103 {
104
105 KASSERTMSG((ctx->wwx_owner == curlwp),
106 "ctx %p owned by %p, not self (%p)", ctx, ctx->wwx_owner, curlwp);
107
108 ctx->wwx_acquire_done = true;
109 }
110
111 void
112 ww_acquire_fini(struct ww_acquire_ctx *ctx)
113 {
114
115 KASSERTMSG((ctx->wwx_owner == curlwp),
116 "ctx %p owned by %p, not self (%p)", ctx, ctx->wwx_owner, curlwp);
117 KASSERTMSG((ctx->wwx_acquired == 0), "ctx %p still holds %u locks",
118 ctx, ctx->wwx_acquired);
119
120 ctx->wwx_acquired = ~0U; /* Fail if called again. */
121 ctx->wwx_owner = NULL;
122 }
123
124 #ifdef LOCKDEBUG
125 static void
126 ww_dump(const volatile void *cookie, lockop_printer_t pr)
127 {
128 const volatile struct ww_mutex *mutex = cookie;
129
130 pr("%-13s: ", "state");
131 switch (mutex->wwm_state) {
132 case WW_UNLOCKED:
133 pr("unlocked\n");
134 break;
135 case WW_OWNED:
136 pr("owned by lwp\n");
137 pr("%-13s: %p\n", "owner", mutex->wwm_u.owner);
138 pr("%-13s: %s\n", "waiters",
139 cv_has_waiters((void *)(intptr_t)&mutex->wwm_cv)
140 ? "yes" : "no");
141 break;
142 case WW_CTX:
143 pr("owned via ctx\n");
144 pr("%-13s: %p\n", "context", mutex->wwm_u.ctx);
145 pr("%-13s: %p\n", "lwp",
146 mutex->wwm_u.ctx->wwx_owner);
147 pr("%-13s: %s\n", "waiters",
148 cv_has_waiters((void *)(intptr_t)&mutex->wwm_cv)
149 ? "yes" : "no");
150 break;
151 case WW_WANTOWN:
152 pr("owned via ctx\n");
153 pr("%-13s: %p\n", "context", mutex->wwm_u.ctx);
154 pr("%-13s: %p\n", "lwp",
155 mutex->wwm_u.ctx->wwx_owner);
156 pr("%-13s: %s\n", "waiters", "yes (noctx)");
157 break;
158 default:
159 pr("unknown\n");
160 break;
161 }
162 }
163
164 static lockops_t ww_lockops = {
165 .lo_name = "Wait/wound mutex",
166 .lo_type = LOCKOPS_SLEEP,
167 .lo_dump = ww_dump,
168 };
169 #endif
170
171 /*
172 * ww_mutex_init(mutex, class)
173 *
174 * Initialize mutex in the given class. Must precede any other
175 * ww_mutex_* operations. After done, mutex must be destroyed
176 * with ww_mutex_destroy.
177 */
178 void
179 ww_mutex_init(struct ww_mutex *mutex, struct ww_class *class)
180 {
181
182 /*
183 * XXX Apparently Linux takes these with spin locks held. That
184 * strikes me as a bad idea, but so it is...
185 */
186 mutex_init(&mutex->wwm_lock, MUTEX_DEFAULT, IPL_VM);
187 mutex->wwm_state = WW_UNLOCKED;
188 mutex->wwm_class = class;
189 rb_tree_init(&mutex->wwm_waiters, &ww_acquire_ctx_rb_ops);
190 cv_init(&mutex->wwm_cv, "linuxwwm");
191 #ifdef LOCKDEBUG
192 mutex->wwm_debug = LOCKDEBUG_ALLOC(mutex, &ww_lockops,
193 (uintptr_t)__builtin_return_address(0));
194 #endif
195 }
196
197 /*
198 * ww_mutex_destroy(mutex)
199 *
200 * Destroy mutex initialized by ww_mutex_init. Caller must not be
201 * with any other ww_mutex_* operations except after
202 * reinitializing with ww_mutex_init.
203 */
204 void
205 ww_mutex_destroy(struct ww_mutex *mutex)
206 {
207
208 KASSERT(mutex->wwm_state == WW_UNLOCKED);
209
210 #ifdef LOCKDEBUG
211 LOCKDEBUG_FREE(mutex->wwm_debug, mutex);
212 #endif
213 cv_destroy(&mutex->wwm_cv);
214 #if 0
215 rb_tree_destroy(&mutex->wwm_waiters, &ww_acquire_ctx_rb_ops);
216 #endif
217 KASSERT(mutex->wwm_state == WW_UNLOCKED);
218 mutex_destroy(&mutex->wwm_lock);
219 }
220
221 /*
222 * ww_mutex_is_locked(mutex)
223 *
224 * True if anyone holds mutex locked at the moment, false if not.
225 * Answer is stale as soon returned unless mutex is held by
226 * caller.
227 *
228 * XXX WARNING: This returns true if it is locked by ANYONE. Does
229 * not mean `Do I hold this lock?' (answering which really
230 * requires an acquire context).
231 */
232 bool
233 ww_mutex_is_locked(struct ww_mutex *mutex)
234 {
235 int locked;
236
237 mutex_enter(&mutex->wwm_lock);
238 switch (mutex->wwm_state) {
239 case WW_UNLOCKED:
240 locked = false;
241 break;
242 case WW_OWNED:
243 case WW_CTX:
244 case WW_WANTOWN:
245 locked = true;
246 break;
247 default:
248 panic("wait/wound mutex %p in bad state: %d", mutex,
249 (int)mutex->wwm_state);
250 }
251 mutex_exit(&mutex->wwm_lock);
252
253 return locked;
254 }
255
256 /*
257 * ww_mutex_state_wait(mutex, state)
258 *
259 * Wait for mutex, which must be in the given state, to transition
260 * to another state. Uninterruptible; never fails.
261 *
262 * Caller must hold mutex's internal lock.
263 *
264 * May sleep.
265 *
266 * Internal subroutine.
267 */
268 static void
269 ww_mutex_state_wait(struct ww_mutex *mutex, enum ww_mutex_state state)
270 {
271
272 KASSERT(mutex_owned(&mutex->wwm_lock));
273 KASSERT(mutex->wwm_state == state);
274 do cv_wait(&mutex->wwm_cv, &mutex->wwm_lock);
275 while (mutex->wwm_state == state);
276 }
277
278 /*
279 * ww_mutex_state_wait_sig(mutex, state)
280 *
281 * Wait for mutex, which must be in the given state, to transition
282 * to another state, or fail if interrupted by a signal. Return 0
283 * on success, -EINTR if interrupted by a signal.
284 *
285 * Caller must hold mutex's internal lock.
286 *
287 * May sleep.
288 *
289 * Internal subroutine.
290 */
291 static int
292 ww_mutex_state_wait_sig(struct ww_mutex *mutex, enum ww_mutex_state state)
293 {
294 int ret;
295
296 KASSERT(mutex_owned(&mutex->wwm_lock));
297 KASSERT(mutex->wwm_state == state);
298 do {
299 /* XXX errno NetBSD->Linux */
300 ret = -cv_wait_sig(&mutex->wwm_cv, &mutex->wwm_lock);
301 if (ret) {
302 KASSERTMSG((ret == -EINTR || ret == -ERESTART),
303 "ret=%d", ret);
304 ret = -EINTR;
305 break;
306 }
307 } while (mutex->wwm_state == state);
308
309 KASSERTMSG((ret == 0 || ret == -EINTR), "ret=%d", ret);
310 return ret;
311 }
312
313 /*
314 * ww_mutex_lock_wait(mutex, ctx)
315 *
316 * With mutex locked and in the WW_CTX or WW_WANTOWN state, owned
317 * by another thread with an acquire context, wait to acquire
318 * mutex. While waiting, record ctx in the tree of waiters. Does
319 * not update the mutex state otherwise.
320 *
321 * Caller must not already hold mutex. Caller must hold mutex's
322 * internal lock. Uninterruptible; never fails.
323 *
324 * May sleep.
325 *
326 * Internal subroutine.
327 */
328 static void
329 ww_mutex_lock_wait(struct ww_mutex *mutex, struct ww_acquire_ctx *ctx)
330 {
331 struct ww_acquire_ctx *collision __diagused;
332
333 KASSERT(mutex_owned(&mutex->wwm_lock));
334
335 KASSERT((mutex->wwm_state == WW_CTX) ||
336 (mutex->wwm_state == WW_WANTOWN));
337 KASSERT(mutex->wwm_u.ctx != ctx);
338 KASSERTMSG((ctx->wwx_class == mutex->wwm_u.ctx->wwx_class),
339 "ww mutex class mismatch: %p != %p",
340 ctx->wwx_class, mutex->wwm_u.ctx->wwx_class);
341 KASSERTMSG((mutex->wwm_u.ctx->wwx_ticket != ctx->wwx_ticket),
342 "ticket number reused: %"PRId64" (%p) %"PRId64" (%p)",
343 ctx->wwx_ticket, ctx,
344 mutex->wwm_u.ctx->wwx_ticket, mutex->wwm_u.ctx);
345
346 collision = rb_tree_insert_node(&mutex->wwm_waiters, ctx);
347 KASSERTMSG((collision == ctx),
348 "ticket number reused: %"PRId64" (%p) %"PRId64" (%p)",
349 ctx->wwx_ticket, ctx, collision->wwx_ticket, collision);
350
351 do cv_wait(&mutex->wwm_cv, &mutex->wwm_lock);
352 while (!(((mutex->wwm_state == WW_CTX) ||
353 (mutex->wwm_state == WW_WANTOWN)) &&
354 (mutex->wwm_u.ctx == ctx)));
355
356 rb_tree_remove_node(&mutex->wwm_waiters, ctx);
357 }
358
359 /*
360 * ww_mutex_lock_wait_sig(mutex, ctx)
361 *
362 * With mutex locked and in the WW_CTX or WW_WANTOWN state, owned
363 * by another thread with an acquire context, wait to acquire
364 * mutex and return 0, or return -EINTR if interrupted by a
365 * signal. While waiting, record ctx in the tree of waiters.
366 * Does not update the mutex state otherwise.
367 *
368 * Caller must not already hold mutex. Caller must hold mutex's
369 * internal lock.
370 *
371 * May sleep.
372 *
373 * Internal subroutine.
374 */
375 static int
376 ww_mutex_lock_wait_sig(struct ww_mutex *mutex, struct ww_acquire_ctx *ctx)
377 {
378 struct ww_acquire_ctx *collision __diagused;
379 int ret;
380
381 KASSERT(mutex_owned(&mutex->wwm_lock));
382
383 KASSERT((mutex->wwm_state == WW_CTX) ||
384 (mutex->wwm_state == WW_WANTOWN));
385 KASSERT(mutex->wwm_u.ctx != ctx);
386 KASSERTMSG((ctx->wwx_class == mutex->wwm_u.ctx->wwx_class),
387 "ww mutex class mismatch: %p != %p",
388 ctx->wwx_class, mutex->wwm_u.ctx->wwx_class);
389 KASSERTMSG((mutex->wwm_u.ctx->wwx_ticket != ctx->wwx_ticket),
390 "ticket number reused: %"PRId64" (%p) %"PRId64" (%p)",
391 ctx->wwx_ticket, ctx,
392 mutex->wwm_u.ctx->wwx_ticket, mutex->wwm_u.ctx);
393
394 collision = rb_tree_insert_node(&mutex->wwm_waiters, ctx);
395 KASSERTMSG((collision == ctx),
396 "ticket number reused: %"PRId64" (%p) %"PRId64" (%p)",
397 ctx->wwx_ticket, ctx, collision->wwx_ticket, collision);
398
399 do {
400 /* XXX errno NetBSD->Linux */
401 ret = -cv_wait_sig(&mutex->wwm_cv, &mutex->wwm_lock);
402 if (ret) {
403 KASSERTMSG((ret == -EINTR || ret == -ERESTART),
404 "ret=%d", ret);
405 ret = -EINTR;
406 goto out;
407 }
408 } while (!(((mutex->wwm_state == WW_CTX) ||
409 (mutex->wwm_state == WW_WANTOWN)) &&
410 (mutex->wwm_u.ctx == ctx)));
411
412 out: rb_tree_remove_node(&mutex->wwm_waiters, ctx);
413 KASSERTMSG((ret == 0 || ret == -EINTR), "ret=%d", ret);
414 return ret;
415 }
416
417 /*
418 * ww_mutex_lock_noctx(mutex)
419 *
420 * Acquire mutex without an acquire context. Caller must not
421 * already hold the mutex. Uninterruptible; never fails.
422 *
423 * May sleep.
424 *
425 * Internal subroutine, implementing ww_mutex_lock(..., NULL).
426 */
427 static void
428 ww_mutex_lock_noctx(struct ww_mutex *mutex)
429 {
430
431 mutex_enter(&mutex->wwm_lock);
432 retry: switch (mutex->wwm_state) {
433 case WW_UNLOCKED:
434 mutex->wwm_state = WW_OWNED;
435 mutex->wwm_u.owner = curlwp;
436 break;
437 case WW_OWNED:
438 KASSERTMSG((mutex->wwm_u.owner != curlwp),
439 "locking %p against myself: %p", mutex, curlwp);
440 ww_mutex_state_wait(mutex, WW_OWNED);
441 goto retry;
442 case WW_CTX:
443 KASSERT(mutex->wwm_u.ctx != NULL);
444 mutex->wwm_state = WW_WANTOWN;
445 /* FALLTHROUGH */
446 case WW_WANTOWN:
447 KASSERTMSG((mutex->wwm_u.ctx->wwx_owner != curlwp),
448 "locking %p against myself: %p", mutex, curlwp);
449 ww_mutex_state_wait(mutex, WW_WANTOWN);
450 goto retry;
451 default:
452 panic("wait/wound mutex %p in bad state: %d",
453 mutex, (int)mutex->wwm_state);
454 }
455 KASSERT(mutex->wwm_state == WW_OWNED);
456 KASSERT(mutex->wwm_u.owner == curlwp);
457 WW_LOCKED(mutex);
458 mutex_exit(&mutex->wwm_lock);
459 }
460
461 /*
462 * ww_mutex_lock_noctx_sig(mutex)
463 *
464 * Acquire mutex without an acquire context and return 0, or fail
465 * and return -EINTR if interrupted by a signal. Caller must not
466 * already hold the mutex.
467 *
468 * May sleep.
469 *
470 * Internal subroutine, implementing
471 * ww_mutex_lock_interruptible(..., NULL).
472 */
473 static int
474 ww_mutex_lock_noctx_sig(struct ww_mutex *mutex)
475 {
476 int ret;
477
478 mutex_enter(&mutex->wwm_lock);
479 retry: switch (mutex->wwm_state) {
480 case WW_UNLOCKED:
481 mutex->wwm_state = WW_OWNED;
482 mutex->wwm_u.owner = curlwp;
483 break;
484 case WW_OWNED:
485 KASSERTMSG((mutex->wwm_u.owner != curlwp),
486 "locking %p against myself: %p", mutex, curlwp);
487 ret = ww_mutex_state_wait_sig(mutex, WW_OWNED);
488 if (ret) {
489 KASSERTMSG(ret == -EINTR, "ret=%d", ret);
490 goto out;
491 }
492 goto retry;
493 case WW_CTX:
494 KASSERT(mutex->wwm_u.ctx != NULL);
495 mutex->wwm_state = WW_WANTOWN;
496 /* FALLTHROUGH */
497 case WW_WANTOWN:
498 KASSERTMSG((mutex->wwm_u.ctx->wwx_owner != curlwp),
499 "locking %p against myself: %p", mutex, curlwp);
500 ret = ww_mutex_state_wait_sig(mutex, WW_WANTOWN);
501 if (ret) {
502 KASSERTMSG(ret == -EINTR, "ret=%d", ret);
503 goto out;
504 }
505 goto retry;
506 default:
507 panic("wait/wound mutex %p in bad state: %d",
508 mutex, (int)mutex->wwm_state);
509 }
510 KASSERT(mutex->wwm_state == WW_OWNED);
511 KASSERT(mutex->wwm_u.owner == curlwp);
512 WW_LOCKED(mutex);
513 ret = 0;
514 out: mutex_exit(&mutex->wwm_lock);
515 KASSERTMSG((ret == 0 || ret == -EINTR), "ret=%d", ret);
516 return ret;
517 }
518
519 /*
520 * ww_mutex_lock(mutex, ctx)
521 *
522 * Lock the mutex and return 0, or fail if impossible.
523 *
524 * - If ctx is null, caller must not hold mutex, and ww_mutex_lock
525 * always succeeds and returns 0.
526 *
527 * - If ctx is nonnull, then:
528 * . Fail with -EALREADY if caller already holds mutex.
529 * . Fail with -EDEADLK if someone else holds mutex but there is
530 * a cycle.
531 *
532 * May sleep.
533 */
534 int
535 ww_mutex_lock(struct ww_mutex *mutex, struct ww_acquire_ctx *ctx)
536 {
537 int ret;
538
539 /*
540 * We do not WW_WANTLOCK at the beginning because we may
541 * correctly already hold it, if we have a context, in which
542 * case we must return EALREADY to the caller.
543 */
544 ASSERT_SLEEPABLE();
545
546 if (ctx == NULL) {
547 WW_WANTLOCK(mutex);
548 ww_mutex_lock_noctx(mutex);
549 ret = 0;
550 goto out;
551 }
552
553 KASSERTMSG((ctx->wwx_owner == curlwp),
554 "ctx %p owned by %p, not self (%p)", ctx, ctx->wwx_owner, curlwp);
555 KASSERTMSG(!ctx->wwx_acquire_done,
556 "ctx %p done acquiring locks, can't acquire more", ctx);
557 KASSERTMSG((ctx->wwx_acquired != ~0U),
558 "ctx %p finished, can't be used any more", ctx);
559 KASSERTMSG((ctx->wwx_class == mutex->wwm_class),
560 "ctx %p in class %p, mutex %p in class %p",
561 ctx, ctx->wwx_class, mutex, mutex->wwm_class);
562
563 mutex_enter(&mutex->wwm_lock);
564 retry: switch (mutex->wwm_state) {
565 case WW_UNLOCKED:
566 WW_WANTLOCK(mutex);
567 mutex->wwm_state = WW_CTX;
568 mutex->wwm_u.ctx = ctx;
569 goto locked;
570 case WW_OWNED:
571 WW_WANTLOCK(mutex);
572 KASSERTMSG((mutex->wwm_u.owner != curlwp),
573 "locking %p against myself: %p", mutex, curlwp);
574 ww_mutex_state_wait(mutex, WW_OWNED);
575 goto retry;
576 case WW_CTX:
577 break;
578 case WW_WANTOWN:
579 ww_mutex_state_wait(mutex, WW_WANTOWN);
580 goto retry;
581 default:
582 panic("wait/wound mutex %p in bad state: %d",
583 mutex, (int)mutex->wwm_state);
584 }
585
586 KASSERT(mutex->wwm_state == WW_CTX);
587 KASSERT(mutex->wwm_u.ctx != NULL);
588 KASSERT((mutex->wwm_u.ctx == ctx) ||
589 (mutex->wwm_u.ctx->wwx_owner != curlwp));
590
591 if (mutex->wwm_u.ctx == ctx) {
592 /*
593 * We already own it. Yes, this can happen correctly
594 * for objects whose locking order is determined by
595 * userland.
596 */
597 ret = -EALREADY;
598 goto out_unlock;
599 }
600
601 /*
602 * We do not own it. We can safely assert to LOCKDEBUG that we
603 * want it.
604 */
605 WW_WANTLOCK(mutex);
606
607 if (mutex->wwm_u.ctx->wwx_ticket < ctx->wwx_ticket) {
608 /*
609 * Owned by a higher-priority party. Tell the caller
610 * to unlock everything and start over.
611 */
612 KASSERTMSG((ctx->wwx_class == mutex->wwm_u.ctx->wwx_class),
613 "ww mutex class mismatch: %p != %p",
614 ctx->wwx_class, mutex->wwm_u.ctx->wwx_class);
615 ret = -EDEADLK;
616 goto out_unlock;
617 }
618
619 /*
620 * Owned by a lower-priority party. Ask that party to wake us
621 * when it is done or it realizes it needs to back off.
622 */
623 ww_mutex_lock_wait(mutex, ctx);
624
625 locked: KASSERT((mutex->wwm_state == WW_CTX) ||
626 (mutex->wwm_state == WW_WANTOWN));
627 KASSERT(mutex->wwm_u.ctx == ctx);
628 WW_LOCKED(mutex);
629 ctx->wwx_acquired++;
630 ret = 0;
631 out_unlock:
632 mutex_exit(&mutex->wwm_lock);
633 out: KASSERTMSG((ret == 0 || ret == -EALREADY || ret == -EDEADLK),
634 "ret=%d", ret);
635 return ret;
636 }
637
638 /*
639 * ww_mutex_lock_interruptible(mutex, ctx)
640 *
641 * Lock the mutex and return 0, or fail if impossible or
642 * interrupted.
643 *
644 * - If ctx is null, caller must not hold mutex, and ww_mutex_lock
645 * always succeeds and returns 0.
646 *
647 * - If ctx is nonnull, then:
648 * . Fail with -EALREADY if caller already holds mutex.
649 * . Fail with -EDEADLK if someone else holds mutex but there is
650 * a cycle.
651 * . Fail with -EINTR if interrupted by a signal.
652 *
653 * May sleep.
654 */
655 int
656 ww_mutex_lock_interruptible(struct ww_mutex *mutex, struct ww_acquire_ctx *ctx)
657 {
658 int ret;
659
660 /*
661 * We do not WW_WANTLOCK at the beginning because we may
662 * correctly already hold it, if we have a context, in which
663 * case we must return EALREADY to the caller.
664 */
665 ASSERT_SLEEPABLE();
666
667 if (ctx == NULL) {
668 WW_WANTLOCK(mutex);
669 ret = ww_mutex_lock_noctx_sig(mutex);
670 KASSERTMSG((ret == 0 || ret == -EINTR), "ret=%d", ret);
671 goto out;
672 }
673
674 KASSERTMSG((ctx->wwx_owner == curlwp),
675 "ctx %p owned by %p, not self (%p)", ctx, ctx->wwx_owner, curlwp);
676 KASSERTMSG(!ctx->wwx_acquire_done,
677 "ctx %p done acquiring locks, can't acquire more", ctx);
678 KASSERTMSG((ctx->wwx_acquired != ~0U),
679 "ctx %p finished, can't be used any more", ctx);
680 KASSERTMSG((ctx->wwx_class == mutex->wwm_class),
681 "ctx %p in class %p, mutex %p in class %p",
682 ctx, ctx->wwx_class, mutex, mutex->wwm_class);
683
684 mutex_enter(&mutex->wwm_lock);
685 retry: switch (mutex->wwm_state) {
686 case WW_UNLOCKED:
687 WW_WANTLOCK(mutex);
688 mutex->wwm_state = WW_CTX;
689 mutex->wwm_u.ctx = ctx;
690 goto locked;
691 case WW_OWNED:
692 WW_WANTLOCK(mutex);
693 KASSERTMSG((mutex->wwm_u.owner != curlwp),
694 "locking %p against myself: %p", mutex, curlwp);
695 ret = ww_mutex_state_wait_sig(mutex, WW_OWNED);
696 if (ret) {
697 KASSERTMSG(ret == -EINTR, "ret=%d", ret);
698 goto out_unlock;
699 }
700 goto retry;
701 case WW_CTX:
702 break;
703 case WW_WANTOWN:
704 ret = ww_mutex_state_wait_sig(mutex, WW_WANTOWN);
705 if (ret) {
706 KASSERTMSG(ret == -EINTR, "ret=%d", ret);
707 goto out_unlock;
708 }
709 goto retry;
710 default:
711 panic("wait/wound mutex %p in bad state: %d",
712 mutex, (int)mutex->wwm_state);
713 }
714
715 KASSERT(mutex->wwm_state == WW_CTX);
716 KASSERT(mutex->wwm_u.ctx != NULL);
717 KASSERT((mutex->wwm_u.ctx == ctx) ||
718 (mutex->wwm_u.ctx->wwx_owner != curlwp));
719
720 if (mutex->wwm_u.ctx == ctx) {
721 /*
722 * We already own it. Yes, this can happen correctly
723 * for objects whose locking order is determined by
724 * userland.
725 */
726 ret = -EALREADY;
727 goto out_unlock;
728 }
729
730 /*
731 * We do not own it. We can safely assert to LOCKDEBUG that we
732 * want it.
733 */
734 WW_WANTLOCK(mutex);
735
736 if (mutex->wwm_u.ctx->wwx_ticket < ctx->wwx_ticket) {
737 /*
738 * Owned by a higher-priority party. Tell the caller
739 * to unlock everything and start over.
740 */
741 KASSERTMSG((ctx->wwx_class == mutex->wwm_u.ctx->wwx_class),
742 "ww mutex class mismatch: %p != %p",
743 ctx->wwx_class, mutex->wwm_u.ctx->wwx_class);
744 ret = -EDEADLK;
745 goto out_unlock;
746 }
747
748 /*
749 * Owned by a lower-priority party. Ask that party to wake us
750 * when it is done or it realizes it needs to back off.
751 */
752 ret = ww_mutex_lock_wait_sig(mutex, ctx);
753 if (ret) {
754 KASSERTMSG(ret == -EINTR, "ret=%d", ret);
755 goto out_unlock;
756 }
757
758 locked: KASSERT((mutex->wwm_state == WW_CTX) ||
759 (mutex->wwm_state == WW_WANTOWN));
760 KASSERT(mutex->wwm_u.ctx == ctx);
761 WW_LOCKED(mutex);
762 ctx->wwx_acquired++;
763 ret = 0;
764 out_unlock:
765 mutex_exit(&mutex->wwm_lock);
766 out: KASSERTMSG((ret == 0 || ret == -EALREADY || ret == -EDEADLK ||
767 ret == -EINTR), "ret=%d", ret);
768 return ret;
769 }
770
771 /*
772 * ww_mutex_lock_slow(mutex, ctx)
773 *
774 * Slow path: After ww_mutex_lock* has failed with -EDEADLK, and
775 * after the caller has ditched all its locks, wait for the owner
776 * of mutex to relinquish mutex before the caller can start over
777 * acquiring locks again.
778 *
779 * Uninterruptible; never fails.
780 *
781 * May sleep.
782 */
783 void
784 ww_mutex_lock_slow(struct ww_mutex *mutex, struct ww_acquire_ctx *ctx)
785 {
786
787 /* Caller must not try to lock against self here. */
788 WW_WANTLOCK(mutex);
789 ASSERT_SLEEPABLE();
790
791 if (ctx == NULL) {
792 ww_mutex_lock_noctx(mutex);
793 return;
794 }
795
796 KASSERTMSG((ctx->wwx_owner == curlwp),
797 "ctx %p owned by %p, not self (%p)", ctx, ctx->wwx_owner, curlwp);
798 KASSERTMSG(!ctx->wwx_acquire_done,
799 "ctx %p done acquiring locks, can't acquire more", ctx);
800 KASSERTMSG((ctx->wwx_acquired != ~0U),
801 "ctx %p finished, can't be used any more", ctx);
802 KASSERTMSG((ctx->wwx_acquired == 0),
803 "ctx %p still holds %u locks, not allowed in slow path",
804 ctx, ctx->wwx_acquired);
805 KASSERTMSG((ctx->wwx_class == mutex->wwm_class),
806 "ctx %p in class %p, mutex %p in class %p",
807 ctx, ctx->wwx_class, mutex, mutex->wwm_class);
808
809 mutex_enter(&mutex->wwm_lock);
810 retry: switch (mutex->wwm_state) {
811 case WW_UNLOCKED:
812 mutex->wwm_state = WW_CTX;
813 mutex->wwm_u.ctx = ctx;
814 goto locked;
815 case WW_OWNED:
816 KASSERTMSG((mutex->wwm_u.owner != curlwp),
817 "locking %p against myself: %p", mutex, curlwp);
818 ww_mutex_state_wait(mutex, WW_OWNED);
819 goto retry;
820 case WW_CTX:
821 break;
822 case WW_WANTOWN:
823 ww_mutex_state_wait(mutex, WW_WANTOWN);
824 goto retry;
825 default:
826 panic("wait/wound mutex %p in bad state: %d",
827 mutex, (int)mutex->wwm_state);
828 }
829
830 KASSERT(mutex->wwm_state == WW_CTX);
831 KASSERT(mutex->wwm_u.ctx != NULL);
832 KASSERTMSG((mutex->wwm_u.ctx->wwx_owner != curlwp),
833 "locking %p against myself: %p", mutex, curlwp);
834
835 /*
836 * Owned by another party, of any priority. Ask that party to
837 * wake us when it's done.
838 */
839 ww_mutex_lock_wait(mutex, ctx);
840
841 locked: KASSERT((mutex->wwm_state == WW_CTX) ||
842 (mutex->wwm_state == WW_WANTOWN));
843 KASSERT(mutex->wwm_u.ctx == ctx);
844 WW_LOCKED(mutex);
845 ctx->wwx_acquired++;
846 mutex_exit(&mutex->wwm_lock);
847 }
848
849 /*
850 * ww_mutex_lock_slow(mutex, ctx)
851 *
852 * Slow path: After ww_mutex_lock* has failed with -EDEADLK, and
853 * after the caller has ditched all its locks, wait for the owner
854 * of mutex to relinquish mutex before the caller can start over
855 * acquiring locks again, or fail with -EINTR if interrupted by a
856 * signal.
857 *
858 * May sleep.
859 */
860 int
861 ww_mutex_lock_slow_interruptible(struct ww_mutex *mutex,
862 struct ww_acquire_ctx *ctx)
863 {
864 int ret;
865
866 WW_WANTLOCK(mutex);
867 ASSERT_SLEEPABLE();
868
869 if (ctx == NULL) {
870 ret = ww_mutex_lock_noctx_sig(mutex);
871 KASSERTMSG((ret == 0 || ret == -EINTR), "ret=%d", ret);
872 goto out;
873 }
874
875 KASSERTMSG((ctx->wwx_owner == curlwp),
876 "ctx %p owned by %p, not self (%p)", ctx, ctx->wwx_owner, curlwp);
877 KASSERTMSG(!ctx->wwx_acquire_done,
878 "ctx %p done acquiring locks, can't acquire more", ctx);
879 KASSERTMSG((ctx->wwx_acquired != ~0U),
880 "ctx %p finished, can't be used any more", ctx);
881 KASSERTMSG((ctx->wwx_acquired == 0),
882 "ctx %p still holds %u locks, not allowed in slow path",
883 ctx, ctx->wwx_acquired);
884 KASSERTMSG((ctx->wwx_class == mutex->wwm_class),
885 "ctx %p in class %p, mutex %p in class %p",
886 ctx, ctx->wwx_class, mutex, mutex->wwm_class);
887
888 mutex_enter(&mutex->wwm_lock);
889 retry: switch (mutex->wwm_state) {
890 case WW_UNLOCKED:
891 mutex->wwm_state = WW_CTX;
892 mutex->wwm_u.ctx = ctx;
893 goto locked;
894 case WW_OWNED:
895 KASSERTMSG((mutex->wwm_u.owner != curlwp),
896 "locking %p against myself: %p", mutex, curlwp);
897 ret = ww_mutex_state_wait_sig(mutex, WW_OWNED);
898 if (ret) {
899 KASSERTMSG(ret == -EINTR, "ret=%d", ret);
900 goto out_unlock;
901 }
902 goto retry;
903 case WW_CTX:
904 break;
905 case WW_WANTOWN:
906 ret = ww_mutex_state_wait_sig(mutex, WW_WANTOWN);
907 if (ret) {
908 KASSERTMSG(ret == -EINTR, "ret=%d", ret);
909 goto out_unlock;
910 }
911 goto retry;
912 default:
913 panic("wait/wound mutex %p in bad state: %d",
914 mutex, (int)mutex->wwm_state);
915 }
916
917 KASSERT(mutex->wwm_state == WW_CTX);
918 KASSERT(mutex->wwm_u.ctx != NULL);
919 KASSERTMSG((mutex->wwm_u.ctx->wwx_owner != curlwp),
920 "locking %p against myself: %p", mutex, curlwp);
921
922 /*
923 * Owned by another party, of any priority. Ask that party to
924 * wake us when it's done.
925 */
926 ret = ww_mutex_lock_wait_sig(mutex, ctx);
927 if (ret) {
928 KASSERTMSG(ret == -EINTR, "ret=%d", ret);
929 goto out_unlock;
930 }
931
932 locked: KASSERT((mutex->wwm_state == WW_CTX) ||
933 (mutex->wwm_state == WW_WANTOWN));
934 KASSERT(mutex->wwm_u.ctx == ctx);
935 WW_LOCKED(mutex);
936 ctx->wwx_acquired++;
937 ret = 0;
938 out_unlock:
939 mutex_exit(&mutex->wwm_lock);
940 out: KASSERTMSG((ret == 0 || ret == -EINTR), "ret=%d", ret);
941 return ret;
942 }
943
944 /*
945 * ww_mutex_trylock(mutex)
946 *
947 * Tro to acquire mutex and return 1, but if it can't be done
948 * immediately, return 0.
949 */
950 int
951 ww_mutex_trylock(struct ww_mutex *mutex)
952 {
953 int ret;
954
955 mutex_enter(&mutex->wwm_lock);
956 if (mutex->wwm_state == WW_UNLOCKED) {
957 mutex->wwm_state = WW_OWNED;
958 mutex->wwm_u.owner = curlwp;
959 WW_WANTLOCK(mutex);
960 WW_LOCKED(mutex);
961 ret = 1;
962 } else {
963 /*
964 * It is tempting to assert that we do not hold the
965 * mutex here, because trylock when we hold the lock
966 * already generally indicates a bug in the design of
967 * the code. However, it seems that Linux relies on
968 * this deep in ttm buffer reservation logic, so these
969 * assertions are disabled until we find another way to
970 * work around that or fix the bug that leads to it.
971 *
972 * That said: we should not be in the WW_WANTOWN state,
973 * which happens only while we're in the ww mutex logic
974 * waiting to acquire the lock.
975 */
976 #if 0
977 KASSERTMSG(((mutex->wwm_state != WW_OWNED) ||
978 (mutex->wwm_u.owner != curlwp)),
979 "locking %p against myself: %p", mutex, curlwp);
980 KASSERTMSG(((mutex->wwm_state != WW_CTX) ||
981 (mutex->wwm_u.ctx->wwx_owner != curlwp)),
982 "locking %p against myself: %p", mutex, curlwp);
983 #endif
984 KASSERTMSG(((mutex->wwm_state != WW_WANTOWN) ||
985 (mutex->wwm_u.ctx->wwx_owner != curlwp)),
986 "locking %p against myself: %p", mutex, curlwp);
987 ret = 0;
988 }
989 mutex_exit(&mutex->wwm_lock);
990
991 return ret;
992 }
993
994 /*
995 * ww_mutex_unlock_release(mutex)
996 *
997 * Decrement the number of mutexes acquired in the current locking
998 * context of mutex, which must be held by the caller and in
999 * WW_CTX or WW_WANTOWN state, and clear the mutex's reference.
1000 * Caller must hold the internal lock of mutex, and is responsible
1001 * for notifying waiters.
1002 *
1003 * Internal subroutine.
1004 */
1005 static void
1006 ww_mutex_unlock_release(struct ww_mutex *mutex)
1007 {
1008
1009 KASSERT(mutex_owned(&mutex->wwm_lock));
1010 KASSERT((mutex->wwm_state == WW_CTX) ||
1011 (mutex->wwm_state == WW_WANTOWN));
1012 KASSERT(mutex->wwm_u.ctx != NULL);
1013 KASSERTMSG((mutex->wwm_u.ctx->wwx_owner == curlwp),
1014 "ww_mutex %p ctx %p held by %p, not by self (%p)",
1015 mutex, mutex->wwm_u.ctx, mutex->wwm_u.ctx->wwx_owner,
1016 curlwp);
1017 KASSERT(mutex->wwm_u.ctx->wwx_acquired != ~0U);
1018 mutex->wwm_u.ctx->wwx_acquired--;
1019 mutex->wwm_u.ctx = NULL;
1020 }
1021
1022 /*
1023 * ww_mutex_unlock(mutex)
1024 *
1025 * Release mutex and wake the next caller waiting, if any.
1026 */
1027 void
1028 ww_mutex_unlock(struct ww_mutex *mutex)
1029 {
1030 struct ww_acquire_ctx *ctx;
1031
1032 mutex_enter(&mutex->wwm_lock);
1033 KASSERT(mutex->wwm_state != WW_UNLOCKED);
1034 switch (mutex->wwm_state) {
1035 case WW_UNLOCKED:
1036 panic("unlocking unlocked wait/wound mutex: %p", mutex);
1037 case WW_OWNED:
1038 /* Let the context lockers fight over it. */
1039 mutex->wwm_u.owner = NULL;
1040 mutex->wwm_state = WW_UNLOCKED;
1041 break;
1042 case WW_CTX:
1043 ww_mutex_unlock_release(mutex);
1044 /*
1045 * If there are any waiters with contexts, grant the
1046 * lock to the highest-priority one. Otherwise, just
1047 * unlock it.
1048 */
1049 if ((ctx = RB_TREE_MIN(&mutex->wwm_waiters)) != NULL) {
1050 mutex->wwm_state = WW_CTX;
1051 mutex->wwm_u.ctx = ctx;
1052 } else {
1053 mutex->wwm_state = WW_UNLOCKED;
1054 }
1055 break;
1056 case WW_WANTOWN:
1057 ww_mutex_unlock_release(mutex);
1058 /* Let the non-context lockers fight over it. */
1059 mutex->wwm_state = WW_UNLOCKED;
1060 break;
1061 }
1062 WW_UNLOCKED(mutex);
1063 cv_broadcast(&mutex->wwm_cv);
1064 mutex_exit(&mutex->wwm_lock);
1065 }
1066
1067 /*
1068 * ww_mutex_locking_ctx(mutex)
1069 *
1070 * Return the current acquire context of mutex. Answer is stale
1071 * as soon as returned unless mutex is held by caller.
1072 */
1073 struct ww_acquire_ctx *
1074 ww_mutex_locking_ctx(struct ww_mutex *mutex)
1075 {
1076 struct ww_acquire_ctx *ctx;
1077
1078 mutex_enter(&mutex->wwm_lock);
1079 switch (mutex->wwm_state) {
1080 case WW_UNLOCKED:
1081 case WW_OWNED:
1082 ctx = NULL;
1083 break;
1084 case WW_CTX:
1085 case WW_WANTOWN:
1086 ctx = mutex->wwm_u.ctx;
1087 break;
1088 default:
1089 panic("wait/wound mutex %p in bad state: %d",
1090 mutex, (int)mutex->wwm_state);
1091 }
1092 mutex_exit(&mutex->wwm_lock);
1093
1094 return ctx;
1095 }
1096