Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/kernel/locking/ww_mutex.h
25923 views
1
/* SPDX-License-Identifier: GPL-2.0-only */
2
3
#ifndef WW_RT
4
5
#define MUTEX mutex
6
#define MUTEX_WAITER mutex_waiter
7
8
static inline struct mutex_waiter *
9
__ww_waiter_first(struct mutex *lock)
10
{
11
struct mutex_waiter *w;
12
13
w = list_first_entry(&lock->wait_list, struct mutex_waiter, list);
14
if (list_entry_is_head(w, &lock->wait_list, list))
15
return NULL;
16
17
return w;
18
}
19
20
static inline struct mutex_waiter *
21
__ww_waiter_next(struct mutex *lock, struct mutex_waiter *w)
22
{
23
w = list_next_entry(w, list);
24
if (list_entry_is_head(w, &lock->wait_list, list))
25
return NULL;
26
27
return w;
28
}
29
30
static inline struct mutex_waiter *
31
__ww_waiter_prev(struct mutex *lock, struct mutex_waiter *w)
32
{
33
w = list_prev_entry(w, list);
34
if (list_entry_is_head(w, &lock->wait_list, list))
35
return NULL;
36
37
return w;
38
}
39
40
static inline struct mutex_waiter *
41
__ww_waiter_last(struct mutex *lock)
42
{
43
struct mutex_waiter *w;
44
45
w = list_last_entry(&lock->wait_list, struct mutex_waiter, list);
46
if (list_entry_is_head(w, &lock->wait_list, list))
47
return NULL;
48
49
return w;
50
}
51
52
static inline void
53
__ww_waiter_add(struct mutex *lock, struct mutex_waiter *waiter, struct mutex_waiter *pos)
54
{
55
struct list_head *p = &lock->wait_list;
56
if (pos)
57
p = &pos->list;
58
__mutex_add_waiter(lock, waiter, p);
59
}
60
61
static inline struct task_struct *
62
__ww_mutex_owner(struct mutex *lock)
63
{
64
return __mutex_owner(lock);
65
}
66
67
static inline bool
68
__ww_mutex_has_waiters(struct mutex *lock)
69
{
70
return atomic_long_read(&lock->owner) & MUTEX_FLAG_WAITERS;
71
}
72
73
static inline void lock_wait_lock(struct mutex *lock, unsigned long *flags)
74
{
75
raw_spin_lock_irqsave(&lock->wait_lock, *flags);
76
}
77
78
static inline void unlock_wait_lock(struct mutex *lock, unsigned long *flags)
79
{
80
raw_spin_unlock_irqrestore(&lock->wait_lock, *flags);
81
}
82
83
static inline void lockdep_assert_wait_lock_held(struct mutex *lock)
84
{
85
lockdep_assert_held(&lock->wait_lock);
86
}
87
88
#else /* WW_RT */
89
90
#define MUTEX rt_mutex
91
#define MUTEX_WAITER rt_mutex_waiter
92
93
static inline struct rt_mutex_waiter *
94
__ww_waiter_first(struct rt_mutex *lock)
95
{
96
struct rb_node *n = rb_first(&lock->rtmutex.waiters.rb_root);
97
if (!n)
98
return NULL;
99
return rb_entry(n, struct rt_mutex_waiter, tree.entry);
100
}
101
102
static inline struct rt_mutex_waiter *
103
__ww_waiter_next(struct rt_mutex *lock, struct rt_mutex_waiter *w)
104
{
105
struct rb_node *n = rb_next(&w->tree.entry);
106
if (!n)
107
return NULL;
108
return rb_entry(n, struct rt_mutex_waiter, tree.entry);
109
}
110
111
static inline struct rt_mutex_waiter *
112
__ww_waiter_prev(struct rt_mutex *lock, struct rt_mutex_waiter *w)
113
{
114
struct rb_node *n = rb_prev(&w->tree.entry);
115
if (!n)
116
return NULL;
117
return rb_entry(n, struct rt_mutex_waiter, tree.entry);
118
}
119
120
static inline struct rt_mutex_waiter *
121
__ww_waiter_last(struct rt_mutex *lock)
122
{
123
struct rb_node *n = rb_last(&lock->rtmutex.waiters.rb_root);
124
if (!n)
125
return NULL;
126
return rb_entry(n, struct rt_mutex_waiter, tree.entry);
127
}
128
129
static inline void
130
__ww_waiter_add(struct rt_mutex *lock, struct rt_mutex_waiter *waiter, struct rt_mutex_waiter *pos)
131
{
132
/* RT unconditionally adds the waiter first and then removes it on error */
133
}
134
135
static inline struct task_struct *
136
__ww_mutex_owner(struct rt_mutex *lock)
137
{
138
return rt_mutex_owner(&lock->rtmutex);
139
}
140
141
static inline bool
142
__ww_mutex_has_waiters(struct rt_mutex *lock)
143
{
144
return rt_mutex_has_waiters(&lock->rtmutex);
145
}
146
147
static inline void lock_wait_lock(struct rt_mutex *lock, unsigned long *flags)
148
{
149
raw_spin_lock_irqsave(&lock->rtmutex.wait_lock, *flags);
150
}
151
152
static inline void unlock_wait_lock(struct rt_mutex *lock, unsigned long *flags)
153
{
154
raw_spin_unlock_irqrestore(&lock->rtmutex.wait_lock, *flags);
155
}
156
157
static inline void lockdep_assert_wait_lock_held(struct rt_mutex *lock)
158
{
159
lockdep_assert_held(&lock->rtmutex.wait_lock);
160
}
161
162
#endif /* WW_RT */
163
164
/*
165
* Wait-Die:
166
* The newer transactions are killed when:
167
* It (the new transaction) makes a request for a lock being held
168
* by an older transaction.
169
*
170
* Wound-Wait:
171
* The newer transactions are wounded when:
172
* An older transaction makes a request for a lock being held by
173
* the newer transaction.
174
*/
175
176
/*
177
* Associate the ww_mutex @ww with the context @ww_ctx under which we acquired
178
* it.
179
*/
180
static __always_inline void
181
ww_mutex_lock_acquired(struct ww_mutex *ww, struct ww_acquire_ctx *ww_ctx)
182
{
183
#ifdef DEBUG_WW_MUTEXES
184
/*
185
* If this WARN_ON triggers, you used ww_mutex_lock to acquire,
186
* but released with a normal mutex_unlock in this call.
187
*
188
* This should never happen, always use ww_mutex_unlock.
189
*/
190
DEBUG_LOCKS_WARN_ON(ww->ctx);
191
192
/*
193
* Not quite done after calling ww_acquire_done() ?
194
*/
195
DEBUG_LOCKS_WARN_ON(ww_ctx->done_acquire);
196
197
if (ww_ctx->contending_lock) {
198
/*
199
* After -EDEADLK you tried to
200
* acquire a different ww_mutex? Bad!
201
*/
202
DEBUG_LOCKS_WARN_ON(ww_ctx->contending_lock != ww);
203
204
/*
205
* You called ww_mutex_lock after receiving -EDEADLK,
206
* but 'forgot' to unlock everything else first?
207
*/
208
DEBUG_LOCKS_WARN_ON(ww_ctx->acquired > 0);
209
ww_ctx->contending_lock = NULL;
210
}
211
212
/*
213
* Naughty, using a different class will lead to undefined behavior!
214
*/
215
DEBUG_LOCKS_WARN_ON(ww_ctx->ww_class != ww->ww_class);
216
#endif
217
ww_ctx->acquired++;
218
ww->ctx = ww_ctx;
219
}
220
221
/*
222
* Determine if @a is 'less' than @b. IOW, either @a is a lower priority task
223
* or, when of equal priority, a younger transaction than @b.
224
*
225
* Depending on the algorithm, @a will either need to wait for @b, or die.
226
*/
227
static inline bool
228
__ww_ctx_less(struct ww_acquire_ctx *a, struct ww_acquire_ctx *b)
229
{
230
/*
231
* Can only do the RT prio for WW_RT, because task->prio isn't stable due to PI,
232
* so the wait_list ordering will go wobbly. rt_mutex re-queues the waiter and
233
* isn't affected by this.
234
*/
235
#ifdef WW_RT
236
/* kernel prio; less is more */
237
int a_prio = a->task->prio;
238
int b_prio = b->task->prio;
239
240
if (rt_or_dl_prio(a_prio) || rt_or_dl_prio(b_prio)) {
241
242
if (a_prio > b_prio)
243
return true;
244
245
if (a_prio < b_prio)
246
return false;
247
248
/* equal static prio */
249
250
if (dl_prio(a_prio)) {
251
if (dl_time_before(b->task->dl.deadline,
252
a->task->dl.deadline))
253
return true;
254
255
if (dl_time_before(a->task->dl.deadline,
256
b->task->dl.deadline))
257
return false;
258
}
259
260
/* equal prio */
261
}
262
#endif
263
264
/* FIFO order tie break -- bigger is younger */
265
return (signed long)(a->stamp - b->stamp) > 0;
266
}
267
268
/*
269
* Wait-Die; wake a lesser waiter context (when locks held) such that it can
270
* die.
271
*
272
* Among waiters with context, only the first one can have other locks acquired
273
* already (ctx->acquired > 0), because __ww_mutex_add_waiter() and
274
* __ww_mutex_check_kill() wake any but the earliest context.
275
*/
276
static bool
277
__ww_mutex_die(struct MUTEX *lock, struct MUTEX_WAITER *waiter,
278
struct ww_acquire_ctx *ww_ctx, struct wake_q_head *wake_q)
279
{
280
if (!ww_ctx->is_wait_die)
281
return false;
282
283
if (waiter->ww_ctx->acquired > 0 && __ww_ctx_less(waiter->ww_ctx, ww_ctx)) {
284
#ifndef WW_RT
285
debug_mutex_wake_waiter(lock, waiter);
286
#endif
287
/*
288
* When waking up the task to die, be sure to clear the
289
* blocked_on pointer. Otherwise we can see circular
290
* blocked_on relationships that can't resolve.
291
*/
292
__clear_task_blocked_on(waiter->task, lock);
293
wake_q_add(wake_q, waiter->task);
294
}
295
296
return true;
297
}
298
299
/*
300
* Wound-Wait; wound a lesser @hold_ctx if it holds the lock.
301
*
302
* Wound the lock holder if there are waiters with more important transactions
303
* than the lock holders. Even if multiple waiters may wound the lock holder,
304
* it's sufficient that only one does.
305
*/
306
static bool __ww_mutex_wound(struct MUTEX *lock,
307
struct ww_acquire_ctx *ww_ctx,
308
struct ww_acquire_ctx *hold_ctx,
309
struct wake_q_head *wake_q)
310
{
311
struct task_struct *owner = __ww_mutex_owner(lock);
312
313
lockdep_assert_wait_lock_held(lock);
314
315
/*
316
* Possible through __ww_mutex_add_waiter() when we race with
317
* ww_mutex_set_context_fastpath(). In that case we'll get here again
318
* through __ww_mutex_check_waiters().
319
*/
320
if (!hold_ctx)
321
return false;
322
323
/*
324
* Can have !owner because of __mutex_unlock_slowpath(), but if owner,
325
* it cannot go away because we'll have FLAG_WAITERS set and hold
326
* wait_lock.
327
*/
328
if (!owner)
329
return false;
330
331
if (ww_ctx->acquired > 0 && __ww_ctx_less(hold_ctx, ww_ctx)) {
332
hold_ctx->wounded = 1;
333
334
/*
335
* wake_up_process() paired with set_current_state()
336
* inserts sufficient barriers to make sure @owner either sees
337
* it's wounded in __ww_mutex_check_kill() or has a
338
* wakeup pending to re-read the wounded state.
339
*/
340
if (owner != current) {
341
/*
342
* When waking up the task to wound, be sure to clear the
343
* blocked_on pointer. Otherwise we can see circular
344
* blocked_on relationships that can't resolve.
345
*
346
* NOTE: We pass NULL here instead of lock, because we
347
* are waking the mutex owner, who may be currently
348
* blocked on a different mutex.
349
*/
350
__clear_task_blocked_on(owner, NULL);
351
wake_q_add(wake_q, owner);
352
}
353
return true;
354
}
355
356
return false;
357
}
358
359
/*
360
* We just acquired @lock under @ww_ctx, if there are more important contexts
361
* waiting behind us on the wait-list, check if they need to die, or wound us.
362
*
363
* See __ww_mutex_add_waiter() for the list-order construction; basically the
364
* list is ordered by stamp, smallest (oldest) first.
365
*
366
* This relies on never mixing wait-die/wound-wait on the same wait-list;
367
* which is currently ensured by that being a ww_class property.
368
*
369
* The current task must not be on the wait list.
370
*/
371
static void
372
__ww_mutex_check_waiters(struct MUTEX *lock, struct ww_acquire_ctx *ww_ctx,
373
struct wake_q_head *wake_q)
374
{
375
struct MUTEX_WAITER *cur;
376
377
lockdep_assert_wait_lock_held(lock);
378
379
for (cur = __ww_waiter_first(lock); cur;
380
cur = __ww_waiter_next(lock, cur)) {
381
382
if (!cur->ww_ctx)
383
continue;
384
385
if (__ww_mutex_die(lock, cur, ww_ctx, wake_q) ||
386
__ww_mutex_wound(lock, cur->ww_ctx, ww_ctx, wake_q))
387
break;
388
}
389
}
390
391
/*
392
* After acquiring lock with fastpath, where we do not hold wait_lock, set ctx
393
* and wake up any waiters so they can recheck.
394
*/
395
static __always_inline void
396
ww_mutex_set_context_fastpath(struct ww_mutex *lock, struct ww_acquire_ctx *ctx)
397
{
398
DEFINE_WAKE_Q(wake_q);
399
unsigned long flags;
400
401
ww_mutex_lock_acquired(lock, ctx);
402
403
/*
404
* The lock->ctx update should be visible on all cores before
405
* the WAITERS check is done, otherwise contended waiters might be
406
* missed. The contended waiters will either see ww_ctx == NULL
407
* and keep spinning, or it will acquire wait_lock, add itself
408
* to waiter list and sleep.
409
*/
410
smp_mb(); /* See comments above and below. */
411
412
/*
413
* [W] ww->ctx = ctx [W] MUTEX_FLAG_WAITERS
414
* MB MB
415
* [R] MUTEX_FLAG_WAITERS [R] ww->ctx
416
*
417
* The memory barrier above pairs with the memory barrier in
418
* __ww_mutex_add_waiter() and makes sure we either observe ww->ctx
419
* and/or !empty list.
420
*/
421
if (likely(!__ww_mutex_has_waiters(&lock->base)))
422
return;
423
424
/*
425
* Uh oh, we raced in fastpath, check if any of the waiters need to
426
* die or wound us.
427
*/
428
lock_wait_lock(&lock->base, &flags);
429
__ww_mutex_check_waiters(&lock->base, ctx, &wake_q);
430
preempt_disable();
431
unlock_wait_lock(&lock->base, &flags);
432
wake_up_q(&wake_q);
433
preempt_enable();
434
}
435
436
static __always_inline int
437
__ww_mutex_kill(struct MUTEX *lock, struct ww_acquire_ctx *ww_ctx)
438
{
439
if (ww_ctx->acquired > 0) {
440
#ifdef DEBUG_WW_MUTEXES
441
struct ww_mutex *ww;
442
443
ww = container_of(lock, struct ww_mutex, base);
444
DEBUG_LOCKS_WARN_ON(ww_ctx->contending_lock);
445
ww_ctx->contending_lock = ww;
446
#endif
447
return -EDEADLK;
448
}
449
450
return 0;
451
}
452
453
/*
454
* Check the wound condition for the current lock acquire.
455
*
456
* Wound-Wait: If we're wounded, kill ourself.
457
*
458
* Wait-Die: If we're trying to acquire a lock already held by an older
459
* context, kill ourselves.
460
*
461
* Since __ww_mutex_add_waiter() orders the wait-list on stamp, we only have to
462
* look at waiters before us in the wait-list.
463
*/
464
static inline int
465
__ww_mutex_check_kill(struct MUTEX *lock, struct MUTEX_WAITER *waiter,
466
struct ww_acquire_ctx *ctx)
467
{
468
struct ww_mutex *ww = container_of(lock, struct ww_mutex, base);
469
struct ww_acquire_ctx *hold_ctx = READ_ONCE(ww->ctx);
470
struct MUTEX_WAITER *cur;
471
472
if (ctx->acquired == 0)
473
return 0;
474
475
if (!ctx->is_wait_die) {
476
if (ctx->wounded)
477
return __ww_mutex_kill(lock, ctx);
478
479
return 0;
480
}
481
482
if (hold_ctx && __ww_ctx_less(ctx, hold_ctx))
483
return __ww_mutex_kill(lock, ctx);
484
485
/*
486
* If there is a waiter in front of us that has a context, then its
487
* stamp is earlier than ours and we must kill ourself.
488
*/
489
for (cur = __ww_waiter_prev(lock, waiter); cur;
490
cur = __ww_waiter_prev(lock, cur)) {
491
492
if (!cur->ww_ctx)
493
continue;
494
495
return __ww_mutex_kill(lock, ctx);
496
}
497
498
return 0;
499
}
500
501
/*
502
* Add @waiter to the wait-list, keep the wait-list ordered by stamp, smallest
503
* first. Such that older contexts are preferred to acquire the lock over
504
* younger contexts.
505
*
506
* Waiters without context are interspersed in FIFO order.
507
*
508
* Furthermore, for Wait-Die kill ourself immediately when possible (there are
509
* older contexts already waiting) to avoid unnecessary waiting and for
510
* Wound-Wait ensure we wound the owning context when it is younger.
511
*/
512
static inline int
513
__ww_mutex_add_waiter(struct MUTEX_WAITER *waiter,
514
struct MUTEX *lock,
515
struct ww_acquire_ctx *ww_ctx,
516
struct wake_q_head *wake_q)
517
{
518
struct MUTEX_WAITER *cur, *pos = NULL;
519
bool is_wait_die;
520
521
if (!ww_ctx) {
522
__ww_waiter_add(lock, waiter, NULL);
523
return 0;
524
}
525
526
is_wait_die = ww_ctx->is_wait_die;
527
528
/*
529
* Add the waiter before the first waiter with a higher stamp.
530
* Waiters without a context are skipped to avoid starving
531
* them. Wait-Die waiters may die here. Wound-Wait waiters
532
* never die here, but they are sorted in stamp order and
533
* may wound the lock holder.
534
*/
535
for (cur = __ww_waiter_last(lock); cur;
536
cur = __ww_waiter_prev(lock, cur)) {
537
538
if (!cur->ww_ctx)
539
continue;
540
541
if (__ww_ctx_less(ww_ctx, cur->ww_ctx)) {
542
/*
543
* Wait-Die: if we find an older context waiting, there
544
* is no point in queueing behind it, as we'd have to
545
* die the moment it would acquire the lock.
546
*/
547
if (is_wait_die) {
548
int ret = __ww_mutex_kill(lock, ww_ctx);
549
550
if (ret)
551
return ret;
552
}
553
554
break;
555
}
556
557
pos = cur;
558
559
/* Wait-Die: ensure younger waiters die. */
560
__ww_mutex_die(lock, cur, ww_ctx, wake_q);
561
}
562
563
__ww_waiter_add(lock, waiter, pos);
564
565
/*
566
* Wound-Wait: if we're blocking on a mutex owned by a younger context,
567
* wound that such that we might proceed.
568
*/
569
if (!is_wait_die) {
570
struct ww_mutex *ww = container_of(lock, struct ww_mutex, base);
571
572
/*
573
* See ww_mutex_set_context_fastpath(). Orders setting
574
* MUTEX_FLAG_WAITERS vs the ww->ctx load,
575
* such that either we or the fastpath will wound @ww->ctx.
576
*/
577
smp_mb();
578
__ww_mutex_wound(lock, ww_ctx, ww->ctx, wake_q);
579
}
580
581
return 0;
582
}
583
584
static inline void __ww_mutex_unlock(struct ww_mutex *lock)
585
{
586
if (lock->ctx) {
587
#ifdef DEBUG_WW_MUTEXES
588
DEBUG_LOCKS_WARN_ON(!lock->ctx->acquired);
589
#endif
590
if (lock->ctx->acquired > 0)
591
lock->ctx->acquired--;
592
lock->ctx = NULL;
593
}
594
}
595
596