diff options
Diffstat (limited to 'kernel/locking/mutex.c')
-rw-r--r-- | kernel/locking/mutex.c | 94 |
1 files changed, 32 insertions, 62 deletions
diff --git a/kernel/locking/mutex.c b/kernel/locking/mutex.c index 4dd6e4c219de..14fe72cc8ce7 100644 --- a/kernel/locking/mutex.c +++ b/kernel/locking/mutex.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/spinlock.h> | 25 | #include <linux/spinlock.h> |
26 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
27 | #include <linux/debug_locks.h> | 27 | #include <linux/debug_locks.h> |
28 | #include "mcs_spinlock.h" | ||
28 | 29 | ||
29 | /* | 30 | /* |
30 | * In the DEBUG case we are using the "NULL fastpath" for mutexes, | 31 | * In the DEBUG case we are using the "NULL fastpath" for mutexes, |
@@ -33,6 +34,13 @@ | |||
33 | #ifdef CONFIG_DEBUG_MUTEXES | 34 | #ifdef CONFIG_DEBUG_MUTEXES |
34 | # include "mutex-debug.h" | 35 | # include "mutex-debug.h" |
35 | # include <asm-generic/mutex-null.h> | 36 | # include <asm-generic/mutex-null.h> |
37 | /* | ||
38 | * Must be 0 for the debug case so we do not do the unlock outside of the | ||
39 | * wait_lock region. debug_mutex_unlock() will do the actual unlock in this | ||
40 | * case. | ||
41 | */ | ||
42 | # undef __mutex_slowpath_needs_to_unlock | ||
43 | # define __mutex_slowpath_needs_to_unlock() 0 | ||
36 | #else | 44 | #else |
37 | # include "mutex.h" | 45 | # include "mutex.h" |
38 | # include <asm/mutex.h> | 46 | # include <asm/mutex.h> |
@@ -52,7 +60,7 @@ __mutex_init(struct mutex *lock, const char *name, struct lock_class_key *key) | |||
52 | INIT_LIST_HEAD(&lock->wait_list); | 60 | INIT_LIST_HEAD(&lock->wait_list); |
53 | mutex_clear_owner(lock); | 61 | mutex_clear_owner(lock); |
54 | #ifdef CONFIG_MUTEX_SPIN_ON_OWNER | 62 | #ifdef CONFIG_MUTEX_SPIN_ON_OWNER |
55 | lock->spin_mlock = NULL; | 63 | lock->osq = NULL; |
56 | #endif | 64 | #endif |
57 | 65 | ||
58 | debug_mutex_init(lock, name, key); | 66 | debug_mutex_init(lock, name, key); |
@@ -111,54 +119,7 @@ EXPORT_SYMBOL(mutex_lock); | |||
111 | * more or less simultaneously, the spinners need to acquire a MCS lock | 119 | * more or less simultaneously, the spinners need to acquire a MCS lock |
112 | * first before spinning on the owner field. | 120 | * first before spinning on the owner field. |
113 | * | 121 | * |
114 | * We don't inline mspin_lock() so that perf can correctly account for the | ||
115 | * time spent in this lock function. | ||
116 | */ | 122 | */ |
117 | struct mspin_node { | ||
118 | struct mspin_node *next ; | ||
119 | int locked; /* 1 if lock acquired */ | ||
120 | }; | ||
121 | #define MLOCK(mutex) ((struct mspin_node **)&((mutex)->spin_mlock)) | ||
122 | |||
123 | static noinline | ||
124 | void mspin_lock(struct mspin_node **lock, struct mspin_node *node) | ||
125 | { | ||
126 | struct mspin_node *prev; | ||
127 | |||
128 | /* Init node */ | ||
129 | node->locked = 0; | ||
130 | node->next = NULL; | ||
131 | |||
132 | prev = xchg(lock, node); | ||
133 | if (likely(prev == NULL)) { | ||
134 | /* Lock acquired */ | ||
135 | node->locked = 1; | ||
136 | return; | ||
137 | } | ||
138 | ACCESS_ONCE(prev->next) = node; | ||
139 | smp_wmb(); | ||
140 | /* Wait until the lock holder passes the lock down */ | ||
141 | while (!ACCESS_ONCE(node->locked)) | ||
142 | arch_mutex_cpu_relax(); | ||
143 | } | ||
144 | |||
145 | static void mspin_unlock(struct mspin_node **lock, struct mspin_node *node) | ||
146 | { | ||
147 | struct mspin_node *next = ACCESS_ONCE(node->next); | ||
148 | |||
149 | if (likely(!next)) { | ||
150 | /* | ||
151 | * Release the lock by setting it to NULL | ||
152 | */ | ||
153 | if (cmpxchg(lock, node, NULL) == node) | ||
154 | return; | ||
155 | /* Wait until the next pointer is set */ | ||
156 | while (!(next = ACCESS_ONCE(node->next))) | ||
157 | arch_mutex_cpu_relax(); | ||
158 | } | ||
159 | ACCESS_ONCE(next->locked) = 1; | ||
160 | smp_wmb(); | ||
161 | } | ||
162 | 123 | ||
163 | /* | 124 | /* |
164 | * Mutex spinning code migrated from kernel/sched/core.c | 125 | * Mutex spinning code migrated from kernel/sched/core.c |
@@ -212,6 +173,9 @@ static inline int mutex_can_spin_on_owner(struct mutex *lock) | |||
212 | struct task_struct *owner; | 173 | struct task_struct *owner; |
213 | int retval = 1; | 174 | int retval = 1; |
214 | 175 | ||
176 | if (need_resched()) | ||
177 | return 0; | ||
178 | |||
215 | rcu_read_lock(); | 179 | rcu_read_lock(); |
216 | owner = ACCESS_ONCE(lock->owner); | 180 | owner = ACCESS_ONCE(lock->owner); |
217 | if (owner) | 181 | if (owner) |
@@ -446,9 +410,11 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass, | |||
446 | if (!mutex_can_spin_on_owner(lock)) | 410 | if (!mutex_can_spin_on_owner(lock)) |
447 | goto slowpath; | 411 | goto slowpath; |
448 | 412 | ||
413 | if (!osq_lock(&lock->osq)) | ||
414 | goto slowpath; | ||
415 | |||
449 | for (;;) { | 416 | for (;;) { |
450 | struct task_struct *owner; | 417 | struct task_struct *owner; |
451 | struct mspin_node node; | ||
452 | 418 | ||
453 | if (use_ww_ctx && ww_ctx->acquired > 0) { | 419 | if (use_ww_ctx && ww_ctx->acquired > 0) { |
454 | struct ww_mutex *ww; | 420 | struct ww_mutex *ww; |
@@ -463,19 +429,16 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass, | |||
463 | * performed the optimistic spinning cannot be done. | 429 | * performed the optimistic spinning cannot be done. |
464 | */ | 430 | */ |
465 | if (ACCESS_ONCE(ww->ctx)) | 431 | if (ACCESS_ONCE(ww->ctx)) |
466 | goto slowpath; | 432 | break; |
467 | } | 433 | } |
468 | 434 | ||
469 | /* | 435 | /* |
470 | * If there's an owner, wait for it to either | 436 | * If there's an owner, wait for it to either |
471 | * release the lock or go to sleep. | 437 | * release the lock or go to sleep. |
472 | */ | 438 | */ |
473 | mspin_lock(MLOCK(lock), &node); | ||
474 | owner = ACCESS_ONCE(lock->owner); | 439 | owner = ACCESS_ONCE(lock->owner); |
475 | if (owner && !mutex_spin_on_owner(lock, owner)) { | 440 | if (owner && !mutex_spin_on_owner(lock, owner)) |
476 | mspin_unlock(MLOCK(lock), &node); | 441 | break; |
477 | goto slowpath; | ||
478 | } | ||
479 | 442 | ||
480 | if ((atomic_read(&lock->count) == 1) && | 443 | if ((atomic_read(&lock->count) == 1) && |
481 | (atomic_cmpxchg(&lock->count, 1, 0) == 1)) { | 444 | (atomic_cmpxchg(&lock->count, 1, 0) == 1)) { |
@@ -488,11 +451,10 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass, | |||
488 | } | 451 | } |
489 | 452 | ||
490 | mutex_set_owner(lock); | 453 | mutex_set_owner(lock); |
491 | mspin_unlock(MLOCK(lock), &node); | 454 | osq_unlock(&lock->osq); |
492 | preempt_enable(); | 455 | preempt_enable(); |
493 | return 0; | 456 | return 0; |
494 | } | 457 | } |
495 | mspin_unlock(MLOCK(lock), &node); | ||
496 | 458 | ||
497 | /* | 459 | /* |
498 | * When there's no owner, we might have preempted between the | 460 | * When there's no owner, we might have preempted between the |
@@ -501,7 +463,7 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass, | |||
501 | * the owner complete. | 463 | * the owner complete. |
502 | */ | 464 | */ |
503 | if (!owner && (need_resched() || rt_task(task))) | 465 | if (!owner && (need_resched() || rt_task(task))) |
504 | goto slowpath; | 466 | break; |
505 | 467 | ||
506 | /* | 468 | /* |
507 | * The cpu_relax() call is a compiler barrier which forces | 469 | * The cpu_relax() call is a compiler barrier which forces |
@@ -511,7 +473,15 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass, | |||
511 | */ | 473 | */ |
512 | arch_mutex_cpu_relax(); | 474 | arch_mutex_cpu_relax(); |
513 | } | 475 | } |
476 | osq_unlock(&lock->osq); | ||
514 | slowpath: | 477 | slowpath: |
478 | /* | ||
479 | * If we fell out of the spin path because of need_resched(), | ||
480 | * reschedule now, before we try-lock the mutex. This avoids getting | ||
481 | * scheduled out right after we obtained the mutex. | ||
482 | */ | ||
483 | if (need_resched()) | ||
484 | schedule_preempt_disabled(); | ||
515 | #endif | 485 | #endif |
516 | spin_lock_mutex(&lock->wait_lock, flags); | 486 | spin_lock_mutex(&lock->wait_lock, flags); |
517 | 487 | ||
@@ -717,10 +687,6 @@ __mutex_unlock_common_slowpath(atomic_t *lock_count, int nested) | |||
717 | struct mutex *lock = container_of(lock_count, struct mutex, count); | 687 | struct mutex *lock = container_of(lock_count, struct mutex, count); |
718 | unsigned long flags; | 688 | unsigned long flags; |
719 | 689 | ||
720 | spin_lock_mutex(&lock->wait_lock, flags); | ||
721 | mutex_release(&lock->dep_map, nested, _RET_IP_); | ||
722 | debug_mutex_unlock(lock); | ||
723 | |||
724 | /* | 690 | /* |
725 | * some architectures leave the lock unlocked in the fastpath failure | 691 | * some architectures leave the lock unlocked in the fastpath failure |
726 | * case, others need to leave it locked. In the later case we have to | 692 | * case, others need to leave it locked. In the later case we have to |
@@ -729,6 +695,10 @@ __mutex_unlock_common_slowpath(atomic_t *lock_count, int nested) | |||
729 | if (__mutex_slowpath_needs_to_unlock()) | 695 | if (__mutex_slowpath_needs_to_unlock()) |
730 | atomic_set(&lock->count, 1); | 696 | atomic_set(&lock->count, 1); |
731 | 697 | ||
698 | spin_lock_mutex(&lock->wait_lock, flags); | ||
699 | mutex_release(&lock->dep_map, nested, _RET_IP_); | ||
700 | debug_mutex_unlock(lock); | ||
701 | |||
732 | if (!list_empty(&lock->wait_list)) { | 702 | if (!list_empty(&lock->wait_list)) { |
733 | /* get the first entry from the wait-list: */ | 703 | /* get the first entry from the wait-list: */ |
734 | struct mutex_waiter *waiter = | 704 | struct mutex_waiter *waiter = |