diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-09 18:24:03 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-09 18:24:03 -0500 |
commit | 8308756f45a12e2ff4f7749c2694fc83cdef0be9 (patch) | |
tree | 618c8f955d22927ebe73d94305d19b37c6ab65c9 | |
parent | 23e8fe2e16587494268510c1bc9f6952f50f0311 (diff) | |
parent | afffc6c1805d98e08e778cddb644a666e78cfcfd (diff) |
Merge branch 'locking-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull core locking updates from Ingo Molnar:
"The main changes are:
- mutex, completions and rtmutex micro-optimizations
- lock debugging fix
- various cleanups in the MCS and the futex code"
* 'locking-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
locking/rtmutex: Optimize setting task running after being blocked
locking/rwsem: Use task->state helpers
sched/completion: Add lock-free checking of the blocking case
sched/completion: Remove unnecessary ->wait.lock serialization when reading completion state
locking/mutex: Explicitly mark task as running after wakeup
futex: Fix argument handling in futex_lock_pi() calls
doc: Fix misnamed FUTEX_CMP_REQUEUE_PI op constants
locking/Documentation: Update code path
softirq/preempt: Add missing current->preempt_disable_ip update
locking/osq: No need for load/acquire when acquire-polling
locking/mcs: Better differentiate between MCS variants
locking/mutex: Introduce ww_mutex_set_context_slowpath()
locking/mutex: Move MCS related comments to proper location
locking/mutex: Checking the stamp is WW only
-rw-r--r-- | Documentation/futex-requeue-pi.txt | 8 | ||||
-rw-r--r-- | Documentation/locking/lockdep-design.txt | 2 | ||||
-rw-r--r-- | include/linux/osq_lock.h | 12 | ||||
-rw-r--r-- | kernel/Kconfig.locks | 4 | ||||
-rw-r--r-- | kernel/futex.c | 6 | ||||
-rw-r--r-- | kernel/locking/Makefile | 3 | ||||
-rw-r--r-- | kernel/locking/mcs_spinlock.h | 16 | ||||
-rw-r--r-- | kernel/locking/mutex.c | 60 | ||||
-rw-r--r-- | kernel/locking/osq_lock.c (renamed from kernel/locking/mcs_spinlock.c) | 9 | ||||
-rw-r--r-- | kernel/locking/rtmutex.c | 7 | ||||
-rw-r--r-- | kernel/locking/rwsem-spinlock.c | 2 | ||||
-rw-r--r-- | kernel/locking/rwsem-xadd.c | 3 | ||||
-rw-r--r-- | kernel/sched/completion.c | 18 | ||||
-rw-r--r-- | kernel/softirq.c | 6 |
14 files changed, 78 insertions, 78 deletions
diff --git a/Documentation/futex-requeue-pi.txt b/Documentation/futex-requeue-pi.txt index 31b16610c416..77b36f59d16b 100644 --- a/Documentation/futex-requeue-pi.txt +++ b/Documentation/futex-requeue-pi.txt | |||
@@ -98,7 +98,7 @@ rt_mutex_start_proxy_lock() and rt_mutex_finish_proxy_lock(), which | |||
98 | allow the requeue code to acquire an uncontended rt_mutex on behalf | 98 | allow the requeue code to acquire an uncontended rt_mutex on behalf |
99 | of the waiter and to enqueue the waiter on a contended rt_mutex. | 99 | of the waiter and to enqueue the waiter on a contended rt_mutex. |
100 | Two new system calls provide the kernel<->user interface to | 100 | Two new system calls provide the kernel<->user interface to |
101 | requeue_pi: FUTEX_WAIT_REQUEUE_PI and FUTEX_REQUEUE_CMP_PI. | 101 | requeue_pi: FUTEX_WAIT_REQUEUE_PI and FUTEX_CMP_REQUEUE_PI. |
102 | 102 | ||
103 | FUTEX_WAIT_REQUEUE_PI is called by the waiter (pthread_cond_wait() | 103 | FUTEX_WAIT_REQUEUE_PI is called by the waiter (pthread_cond_wait() |
104 | and pthread_cond_timedwait()) to block on the initial futex and wait | 104 | and pthread_cond_timedwait()) to block on the initial futex and wait |
@@ -107,7 +107,7 @@ result of a high-speed collision between futex_wait() and | |||
107 | futex_lock_pi(), with some extra logic to check for the additional | 107 | futex_lock_pi(), with some extra logic to check for the additional |
108 | wake-up scenarios. | 108 | wake-up scenarios. |
109 | 109 | ||
110 | FUTEX_REQUEUE_CMP_PI is called by the waker | 110 | FUTEX_CMP_REQUEUE_PI is called by the waker |
111 | (pthread_cond_broadcast() and pthread_cond_signal()) to requeue and | 111 | (pthread_cond_broadcast() and pthread_cond_signal()) to requeue and |
112 | possibly wake the waiting tasks. Internally, this system call is | 112 | possibly wake the waiting tasks. Internally, this system call is |
113 | still handled by futex_requeue (by passing requeue_pi=1). Before | 113 | still handled by futex_requeue (by passing requeue_pi=1). Before |
@@ -120,12 +120,12 @@ task as a waiter on the underlying rt_mutex. It is possible that | |||
120 | the lock can be acquired at this stage as well, if so, the next | 120 | the lock can be acquired at this stage as well, if so, the next |
121 | waiter is woken to finish the acquisition of the lock. | 121 | waiter is woken to finish the acquisition of the lock. |
122 | 122 | ||
123 | FUTEX_REQUEUE_PI accepts nr_wake and nr_requeue as arguments, but | 123 | FUTEX_CMP_REQUEUE_PI accepts nr_wake and nr_requeue as arguments, but |
124 | their sum is all that really matters. futex_requeue() will wake or | 124 | their sum is all that really matters. futex_requeue() will wake or |
125 | requeue up to nr_wake + nr_requeue tasks. It will wake only as many | 125 | requeue up to nr_wake + nr_requeue tasks. It will wake only as many |
126 | tasks as it can acquire the lock for, which in the majority of cases | 126 | tasks as it can acquire the lock for, which in the majority of cases |
127 | should be 0 as good programming practice dictates that the caller of | 127 | should be 0 as good programming practice dictates that the caller of |
128 | either pthread_cond_broadcast() or pthread_cond_signal() acquire the | 128 | either pthread_cond_broadcast() or pthread_cond_signal() acquire the |
129 | mutex prior to making the call. FUTEX_REQUEUE_PI requires that | 129 | mutex prior to making the call. FUTEX_CMP_REQUEUE_PI requires that |
130 | nr_wake=1. nr_requeue should be INT_MAX for broadcast and 0 for | 130 | nr_wake=1. nr_requeue should be INT_MAX for broadcast and 0 for |
131 | signal. | 131 | signal. |
diff --git a/Documentation/locking/lockdep-design.txt b/Documentation/locking/lockdep-design.txt index 5dbc99c04f6e..5001280e9d82 100644 --- a/Documentation/locking/lockdep-design.txt +++ b/Documentation/locking/lockdep-design.txt | |||
@@ -34,7 +34,7 @@ The validator tracks lock-class usage history into 4n + 1 separate state bits: | |||
34 | - 'ever held with STATE enabled' | 34 | - 'ever held with STATE enabled' |
35 | - 'ever held as readlock with STATE enabled' | 35 | - 'ever held as readlock with STATE enabled' |
36 | 36 | ||
37 | Where STATE can be either one of (kernel/lockdep_states.h) | 37 | Where STATE can be either one of (kernel/locking/lockdep_states.h) |
38 | - hardirq | 38 | - hardirq |
39 | - softirq | 39 | - softirq |
40 | - reclaim_fs | 40 | - reclaim_fs |
diff --git a/include/linux/osq_lock.h b/include/linux/osq_lock.h index 90230d5811c5..3a6490e81b28 100644 --- a/include/linux/osq_lock.h +++ b/include/linux/osq_lock.h | |||
@@ -5,8 +5,11 @@ | |||
5 | * An MCS like lock especially tailored for optimistic spinning for sleeping | 5 | * An MCS like lock especially tailored for optimistic spinning for sleeping |
6 | * lock implementations (mutex, rwsem, etc). | 6 | * lock implementations (mutex, rwsem, etc). |
7 | */ | 7 | */ |
8 | 8 | struct optimistic_spin_node { | |
9 | #define OSQ_UNLOCKED_VAL (0) | 9 | struct optimistic_spin_node *next, *prev; |
10 | int locked; /* 1 if lock acquired */ | ||
11 | int cpu; /* encoded CPU # + 1 value */ | ||
12 | }; | ||
10 | 13 | ||
11 | struct optimistic_spin_queue { | 14 | struct optimistic_spin_queue { |
12 | /* | 15 | /* |
@@ -16,6 +19,8 @@ struct optimistic_spin_queue { | |||
16 | atomic_t tail; | 19 | atomic_t tail; |
17 | }; | 20 | }; |
18 | 21 | ||
22 | #define OSQ_UNLOCKED_VAL (0) | ||
23 | |||
19 | /* Init macro and function. */ | 24 | /* Init macro and function. */ |
20 | #define OSQ_LOCK_UNLOCKED { ATOMIC_INIT(OSQ_UNLOCKED_VAL) } | 25 | #define OSQ_LOCK_UNLOCKED { ATOMIC_INIT(OSQ_UNLOCKED_VAL) } |
21 | 26 | ||
@@ -24,4 +29,7 @@ static inline void osq_lock_init(struct optimistic_spin_queue *lock) | |||
24 | atomic_set(&lock->tail, OSQ_UNLOCKED_VAL); | 29 | atomic_set(&lock->tail, OSQ_UNLOCKED_VAL); |
25 | } | 30 | } |
26 | 31 | ||
32 | extern bool osq_lock(struct optimistic_spin_queue *lock); | ||
33 | extern void osq_unlock(struct optimistic_spin_queue *lock); | ||
34 | |||
27 | #endif | 35 | #endif |
diff --git a/kernel/Kconfig.locks b/kernel/Kconfig.locks index 76768ee812b2..08561f1acd13 100644 --- a/kernel/Kconfig.locks +++ b/kernel/Kconfig.locks | |||
@@ -231,6 +231,10 @@ config RWSEM_SPIN_ON_OWNER | |||
231 | def_bool y | 231 | def_bool y |
232 | depends on SMP && RWSEM_XCHGADD_ALGORITHM && ARCH_SUPPORTS_ATOMIC_RMW | 232 | depends on SMP && RWSEM_XCHGADD_ALGORITHM && ARCH_SUPPORTS_ATOMIC_RMW |
233 | 233 | ||
234 | config LOCK_SPIN_ON_OWNER | ||
235 | def_bool y | ||
236 | depends on MUTEX_SPIN_ON_OWNER || RWSEM_SPIN_ON_OWNER | ||
237 | |||
234 | config ARCH_USE_QUEUE_RWLOCK | 238 | config ARCH_USE_QUEUE_RWLOCK |
235 | bool | 239 | bool |
236 | 240 | ||
diff --git a/kernel/futex.c b/kernel/futex.c index 63678b573d61..4eeb63de7e54 100644 --- a/kernel/futex.c +++ b/kernel/futex.c | |||
@@ -2258,7 +2258,7 @@ static long futex_wait_restart(struct restart_block *restart) | |||
2258 | * if there are waiters then it will block, it does PI, etc. (Due to | 2258 | * if there are waiters then it will block, it does PI, etc. (Due to |
2259 | * races the kernel might see a 0 value of the futex too.) | 2259 | * races the kernel might see a 0 value of the futex too.) |
2260 | */ | 2260 | */ |
2261 | static int futex_lock_pi(u32 __user *uaddr, unsigned int flags, int detect, | 2261 | static int futex_lock_pi(u32 __user *uaddr, unsigned int flags, |
2262 | ktime_t *time, int trylock) | 2262 | ktime_t *time, int trylock) |
2263 | { | 2263 | { |
2264 | struct hrtimer_sleeper timeout, *to = NULL; | 2264 | struct hrtimer_sleeper timeout, *to = NULL; |
@@ -2953,11 +2953,11 @@ long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout, | |||
2953 | case FUTEX_WAKE_OP: | 2953 | case FUTEX_WAKE_OP: |
2954 | return futex_wake_op(uaddr, flags, uaddr2, val, val2, val3); | 2954 | return futex_wake_op(uaddr, flags, uaddr2, val, val2, val3); |
2955 | case FUTEX_LOCK_PI: | 2955 | case FUTEX_LOCK_PI: |
2956 | return futex_lock_pi(uaddr, flags, val, timeout, 0); | 2956 | return futex_lock_pi(uaddr, flags, timeout, 0); |
2957 | case FUTEX_UNLOCK_PI: | 2957 | case FUTEX_UNLOCK_PI: |
2958 | return futex_unlock_pi(uaddr, flags); | 2958 | return futex_unlock_pi(uaddr, flags); |
2959 | case FUTEX_TRYLOCK_PI: | 2959 | case FUTEX_TRYLOCK_PI: |
2960 | return futex_lock_pi(uaddr, flags, 0, timeout, 1); | 2960 | return futex_lock_pi(uaddr, flags, NULL, 1); |
2961 | case FUTEX_WAIT_REQUEUE_PI: | 2961 | case FUTEX_WAIT_REQUEUE_PI: |
2962 | val3 = FUTEX_BITSET_MATCH_ANY; | 2962 | val3 = FUTEX_BITSET_MATCH_ANY; |
2963 | return futex_wait_requeue_pi(uaddr, flags, val, timeout, val3, | 2963 | return futex_wait_requeue_pi(uaddr, flags, val, timeout, val3, |
diff --git a/kernel/locking/Makefile b/kernel/locking/Makefile index 8541bfdfd232..4ca8eb151975 100644 --- a/kernel/locking/Makefile +++ b/kernel/locking/Makefile | |||
@@ -1,5 +1,5 @@ | |||
1 | 1 | ||
2 | obj-y += mutex.o semaphore.o rwsem.o mcs_spinlock.o | 2 | obj-y += mutex.o semaphore.o rwsem.o |
3 | 3 | ||
4 | ifdef CONFIG_FUNCTION_TRACER | 4 | ifdef CONFIG_FUNCTION_TRACER |
5 | CFLAGS_REMOVE_lockdep.o = -pg | 5 | CFLAGS_REMOVE_lockdep.o = -pg |
@@ -14,6 +14,7 @@ ifeq ($(CONFIG_PROC_FS),y) | |||
14 | obj-$(CONFIG_LOCKDEP) += lockdep_proc.o | 14 | obj-$(CONFIG_LOCKDEP) += lockdep_proc.o |
15 | endif | 15 | endif |
16 | obj-$(CONFIG_SMP) += spinlock.o | 16 | obj-$(CONFIG_SMP) += spinlock.o |
17 | obj-$(CONFIG_LOCK_SPIN_ON_OWNER) += osq_lock.o | ||
17 | obj-$(CONFIG_SMP) += lglock.o | 18 | obj-$(CONFIG_SMP) += lglock.o |
18 | obj-$(CONFIG_PROVE_LOCKING) += spinlock.o | 19 | obj-$(CONFIG_PROVE_LOCKING) += spinlock.o |
19 | obj-$(CONFIG_RT_MUTEXES) += rtmutex.o | 20 | obj-$(CONFIG_RT_MUTEXES) += rtmutex.o |
diff --git a/kernel/locking/mcs_spinlock.h b/kernel/locking/mcs_spinlock.h index 4d60986fcbee..d1fe2ba5bac9 100644 --- a/kernel/locking/mcs_spinlock.h +++ b/kernel/locking/mcs_spinlock.h | |||
@@ -108,20 +108,4 @@ void mcs_spin_unlock(struct mcs_spinlock **lock, struct mcs_spinlock *node) | |||
108 | arch_mcs_spin_unlock_contended(&next->locked); | 108 | arch_mcs_spin_unlock_contended(&next->locked); |
109 | } | 109 | } |
110 | 110 | ||
111 | /* | ||
112 | * Cancellable version of the MCS lock above. | ||
113 | * | ||
114 | * Intended for adaptive spinning of sleeping locks: | ||
115 | * mutex_lock()/rwsem_down_{read,write}() etc. | ||
116 | */ | ||
117 | |||
118 | struct optimistic_spin_node { | ||
119 | struct optimistic_spin_node *next, *prev; | ||
120 | int locked; /* 1 if lock acquired */ | ||
121 | int cpu; /* encoded CPU # value */ | ||
122 | }; | ||
123 | |||
124 | extern bool osq_lock(struct optimistic_spin_queue *lock); | ||
125 | extern void osq_unlock(struct optimistic_spin_queue *lock); | ||
126 | |||
127 | #endif /* __LINUX_MCS_SPINLOCK_H */ | 111 | #endif /* __LINUX_MCS_SPINLOCK_H */ |
diff --git a/kernel/locking/mutex.c b/kernel/locking/mutex.c index 454195194d4a..57407062e209 100644 --- a/kernel/locking/mutex.c +++ b/kernel/locking/mutex.c | |||
@@ -147,7 +147,7 @@ static __always_inline void ww_mutex_lock_acquired(struct ww_mutex *ww, | |||
147 | } | 147 | } |
148 | 148 | ||
149 | /* | 149 | /* |
150 | * after acquiring lock with fastpath or when we lost out in contested | 150 | * After acquiring lock with fastpath or when we lost out in contested |
151 | * slowpath, set ctx and wake up any waiters so they can recheck. | 151 | * slowpath, set ctx and wake up any waiters so they can recheck. |
152 | * | 152 | * |
153 | * This function is never called when CONFIG_DEBUG_LOCK_ALLOC is set, | 153 | * This function is never called when CONFIG_DEBUG_LOCK_ALLOC is set, |
@@ -191,19 +191,32 @@ ww_mutex_set_context_fastpath(struct ww_mutex *lock, | |||
191 | spin_unlock_mutex(&lock->base.wait_lock, flags); | 191 | spin_unlock_mutex(&lock->base.wait_lock, flags); |
192 | } | 192 | } |
193 | 193 | ||
194 | |||
195 | #ifdef CONFIG_MUTEX_SPIN_ON_OWNER | ||
196 | /* | 194 | /* |
197 | * In order to avoid a stampede of mutex spinners from acquiring the mutex | 195 | * After acquiring lock in the slowpath set ctx and wake up any |
198 | * more or less simultaneously, the spinners need to acquire a MCS lock | 196 | * waiters so they can recheck. |
199 | * first before spinning on the owner field. | ||
200 | * | 197 | * |
198 | * Callers must hold the mutex wait_lock. | ||
201 | */ | 199 | */ |
200 | static __always_inline void | ||
201 | ww_mutex_set_context_slowpath(struct ww_mutex *lock, | ||
202 | struct ww_acquire_ctx *ctx) | ||
203 | { | ||
204 | struct mutex_waiter *cur; | ||
202 | 205 | ||
203 | /* | 206 | ww_mutex_lock_acquired(lock, ctx); |
204 | * Mutex spinning code migrated from kernel/sched/core.c | 207 | lock->ctx = ctx; |
205 | */ | 208 | |
209 | /* | ||
210 | * Give any possible sleeping processes the chance to wake up, | ||
211 | * so they can recheck if they have to back off. | ||
212 | */ | ||
213 | list_for_each_entry(cur, &lock->base.wait_list, list) { | ||
214 | debug_mutex_wake_waiter(&lock->base, cur); | ||
215 | wake_up_process(cur->task); | ||
216 | } | ||
217 | } | ||
206 | 218 | ||
219 | #ifdef CONFIG_MUTEX_SPIN_ON_OWNER | ||
207 | static inline bool owner_running(struct mutex *lock, struct task_struct *owner) | 220 | static inline bool owner_running(struct mutex *lock, struct task_struct *owner) |
208 | { | 221 | { |
209 | if (lock->owner != owner) | 222 | if (lock->owner != owner) |
@@ -307,6 +320,11 @@ static bool mutex_optimistic_spin(struct mutex *lock, | |||
307 | if (!mutex_can_spin_on_owner(lock)) | 320 | if (!mutex_can_spin_on_owner(lock)) |
308 | goto done; | 321 | goto done; |
309 | 322 | ||
323 | /* | ||
324 | * In order to avoid a stampede of mutex spinners trying to | ||
325 | * acquire the mutex all at once, the spinners need to take a | ||
326 | * MCS (queued) lock first before spinning on the owner field. | ||
327 | */ | ||
310 | if (!osq_lock(&lock->osq)) | 328 | if (!osq_lock(&lock->osq)) |
311 | goto done; | 329 | goto done; |
312 | 330 | ||
@@ -469,7 +487,7 @@ void __sched ww_mutex_unlock(struct ww_mutex *lock) | |||
469 | EXPORT_SYMBOL(ww_mutex_unlock); | 487 | EXPORT_SYMBOL(ww_mutex_unlock); |
470 | 488 | ||
471 | static inline int __sched | 489 | static inline int __sched |
472 | __mutex_lock_check_stamp(struct mutex *lock, struct ww_acquire_ctx *ctx) | 490 | __ww_mutex_lock_check_stamp(struct mutex *lock, struct ww_acquire_ctx *ctx) |
473 | { | 491 | { |
474 | struct ww_mutex *ww = container_of(lock, struct ww_mutex, base); | 492 | struct ww_mutex *ww = container_of(lock, struct ww_mutex, base); |
475 | struct ww_acquire_ctx *hold_ctx = ACCESS_ONCE(ww->ctx); | 493 | struct ww_acquire_ctx *hold_ctx = ACCESS_ONCE(ww->ctx); |
@@ -557,7 +575,7 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass, | |||
557 | } | 575 | } |
558 | 576 | ||
559 | if (use_ww_ctx && ww_ctx->acquired > 0) { | 577 | if (use_ww_ctx && ww_ctx->acquired > 0) { |
560 | ret = __mutex_lock_check_stamp(lock, ww_ctx); | 578 | ret = __ww_mutex_lock_check_stamp(lock, ww_ctx); |
561 | if (ret) | 579 | if (ret) |
562 | goto err; | 580 | goto err; |
563 | } | 581 | } |
@@ -569,6 +587,8 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass, | |||
569 | schedule_preempt_disabled(); | 587 | schedule_preempt_disabled(); |
570 | spin_lock_mutex(&lock->wait_lock, flags); | 588 | spin_lock_mutex(&lock->wait_lock, flags); |
571 | } | 589 | } |
590 | __set_task_state(task, TASK_RUNNING); | ||
591 | |||
572 | mutex_remove_waiter(lock, &waiter, current_thread_info()); | 592 | mutex_remove_waiter(lock, &waiter, current_thread_info()); |
573 | /* set it to 0 if there are no waiters left: */ | 593 | /* set it to 0 if there are no waiters left: */ |
574 | if (likely(list_empty(&lock->wait_list))) | 594 | if (likely(list_empty(&lock->wait_list))) |
@@ -582,23 +602,7 @@ skip_wait: | |||
582 | 602 | ||
583 | if (use_ww_ctx) { | 603 | if (use_ww_ctx) { |
584 | struct ww_mutex *ww = container_of(lock, struct ww_mutex, base); | 604 | struct ww_mutex *ww = container_of(lock, struct ww_mutex, base); |
585 | struct mutex_waiter *cur; | 605 | ww_mutex_set_context_slowpath(ww, ww_ctx); |
586 | |||
587 | /* | ||
588 | * This branch gets optimized out for the common case, | ||
589 | * and is only important for ww_mutex_lock. | ||
590 | */ | ||
591 | ww_mutex_lock_acquired(ww, ww_ctx); | ||
592 | ww->ctx = ww_ctx; | ||
593 | |||
594 | /* | ||
595 | * Give any possible sleeping processes the chance to wake up, | ||
596 | * so they can recheck if they have to back off. | ||
597 | */ | ||
598 | list_for_each_entry(cur, &lock->wait_list, list) { | ||
599 | debug_mutex_wake_waiter(lock, cur); | ||
600 | wake_up_process(cur->task); | ||
601 | } | ||
602 | } | 606 | } |
603 | 607 | ||
604 | spin_unlock_mutex(&lock->wait_lock, flags); | 608 | spin_unlock_mutex(&lock->wait_lock, flags); |
diff --git a/kernel/locking/mcs_spinlock.c b/kernel/locking/osq_lock.c index 9887a905a762..c112d00341b0 100644 --- a/kernel/locking/mcs_spinlock.c +++ b/kernel/locking/osq_lock.c | |||
@@ -1,8 +1,6 @@ | |||
1 | #include <linux/percpu.h> | 1 | #include <linux/percpu.h> |
2 | #include <linux/sched.h> | 2 | #include <linux/sched.h> |
3 | #include "mcs_spinlock.h" | 3 | #include <linux/osq_lock.h> |
4 | |||
5 | #ifdef CONFIG_SMP | ||
6 | 4 | ||
7 | /* | 5 | /* |
8 | * An MCS like lock especially tailored for optimistic spinning for sleeping | 6 | * An MCS like lock especially tailored for optimistic spinning for sleeping |
@@ -111,7 +109,7 @@ bool osq_lock(struct optimistic_spin_queue *lock) | |||
111 | * cmpxchg in an attempt to undo our queueing. | 109 | * cmpxchg in an attempt to undo our queueing. |
112 | */ | 110 | */ |
113 | 111 | ||
114 | while (!smp_load_acquire(&node->locked)) { | 112 | while (!ACCESS_ONCE(node->locked)) { |
115 | /* | 113 | /* |
116 | * If we need to reschedule bail... so we can block. | 114 | * If we need to reschedule bail... so we can block. |
117 | */ | 115 | */ |
@@ -203,6 +201,3 @@ void osq_unlock(struct optimistic_spin_queue *lock) | |||
203 | if (next) | 201 | if (next) |
204 | ACCESS_ONCE(next->locked) = 1; | 202 | ACCESS_ONCE(next->locked) = 1; |
205 | } | 203 | } |
206 | |||
207 | #endif | ||
208 | |||
diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c index 7c98873a3077..3059bc2f022d 100644 --- a/kernel/locking/rtmutex.c +++ b/kernel/locking/rtmutex.c | |||
@@ -1130,6 +1130,7 @@ __rt_mutex_slowlock(struct rt_mutex *lock, int state, | |||
1130 | set_current_state(state); | 1130 | set_current_state(state); |
1131 | } | 1131 | } |
1132 | 1132 | ||
1133 | __set_current_state(TASK_RUNNING); | ||
1133 | return ret; | 1134 | return ret; |
1134 | } | 1135 | } |
1135 | 1136 | ||
@@ -1188,10 +1189,9 @@ rt_mutex_slowlock(struct rt_mutex *lock, int state, | |||
1188 | ret = task_blocks_on_rt_mutex(lock, &waiter, current, chwalk); | 1189 | ret = task_blocks_on_rt_mutex(lock, &waiter, current, chwalk); |
1189 | 1190 | ||
1190 | if (likely(!ret)) | 1191 | if (likely(!ret)) |
1192 | /* sleep on the mutex */ | ||
1191 | ret = __rt_mutex_slowlock(lock, state, timeout, &waiter); | 1193 | ret = __rt_mutex_slowlock(lock, state, timeout, &waiter); |
1192 | 1194 | ||
1193 | set_current_state(TASK_RUNNING); | ||
1194 | |||
1195 | if (unlikely(ret)) { | 1195 | if (unlikely(ret)) { |
1196 | remove_waiter(lock, &waiter); | 1196 | remove_waiter(lock, &waiter); |
1197 | rt_mutex_handle_deadlock(ret, chwalk, &waiter); | 1197 | rt_mutex_handle_deadlock(ret, chwalk, &waiter); |
@@ -1626,10 +1626,9 @@ int rt_mutex_finish_proxy_lock(struct rt_mutex *lock, | |||
1626 | 1626 | ||
1627 | set_current_state(TASK_INTERRUPTIBLE); | 1627 | set_current_state(TASK_INTERRUPTIBLE); |
1628 | 1628 | ||
1629 | /* sleep on the mutex */ | ||
1629 | ret = __rt_mutex_slowlock(lock, TASK_INTERRUPTIBLE, to, waiter); | 1630 | ret = __rt_mutex_slowlock(lock, TASK_INTERRUPTIBLE, to, waiter); |
1630 | 1631 | ||
1631 | set_current_state(TASK_RUNNING); | ||
1632 | |||
1633 | if (unlikely(ret)) | 1632 | if (unlikely(ret)) |
1634 | remove_waiter(lock, waiter); | 1633 | remove_waiter(lock, waiter); |
1635 | 1634 | ||
diff --git a/kernel/locking/rwsem-spinlock.c b/kernel/locking/rwsem-spinlock.c index 2c93571162cb..2555ae15ec14 100644 --- a/kernel/locking/rwsem-spinlock.c +++ b/kernel/locking/rwsem-spinlock.c | |||
@@ -154,7 +154,7 @@ void __sched __down_read(struct rw_semaphore *sem) | |||
154 | set_task_state(tsk, TASK_UNINTERRUPTIBLE); | 154 | set_task_state(tsk, TASK_UNINTERRUPTIBLE); |
155 | } | 155 | } |
156 | 156 | ||
157 | tsk->state = TASK_RUNNING; | 157 | __set_task_state(tsk, TASK_RUNNING); |
158 | out: | 158 | out: |
159 | ; | 159 | ; |
160 | } | 160 | } |
diff --git a/kernel/locking/rwsem-xadd.c b/kernel/locking/rwsem-xadd.c index 7628c3fc37ca..2f7cc4076f50 100644 --- a/kernel/locking/rwsem-xadd.c +++ b/kernel/locking/rwsem-xadd.c | |||
@@ -242,8 +242,7 @@ struct rw_semaphore __sched *rwsem_down_read_failed(struct rw_semaphore *sem) | |||
242 | schedule(); | 242 | schedule(); |
243 | } | 243 | } |
244 | 244 | ||
245 | tsk->state = TASK_RUNNING; | 245 | __set_task_state(tsk, TASK_RUNNING); |
246 | |||
247 | return sem; | 246 | return sem; |
248 | } | 247 | } |
249 | EXPORT_SYMBOL(rwsem_down_read_failed); | 248 | EXPORT_SYMBOL(rwsem_down_read_failed); |
diff --git a/kernel/sched/completion.c b/kernel/sched/completion.c index 607f852b4d04..7052d3fd4e7b 100644 --- a/kernel/sched/completion.c +++ b/kernel/sched/completion.c | |||
@@ -268,6 +268,15 @@ bool try_wait_for_completion(struct completion *x) | |||
268 | unsigned long flags; | 268 | unsigned long flags; |
269 | int ret = 1; | 269 | int ret = 1; |
270 | 270 | ||
271 | /* | ||
272 | * Since x->done will need to be locked only | ||
273 | * in the non-blocking case, we check x->done | ||
274 | * first without taking the lock so we can | ||
275 | * return early in the blocking case. | ||
276 | */ | ||
277 | if (!ACCESS_ONCE(x->done)) | ||
278 | return 0; | ||
279 | |||
271 | spin_lock_irqsave(&x->wait.lock, flags); | 280 | spin_lock_irqsave(&x->wait.lock, flags); |
272 | if (!x->done) | 281 | if (!x->done) |
273 | ret = 0; | 282 | ret = 0; |
@@ -288,13 +297,6 @@ EXPORT_SYMBOL(try_wait_for_completion); | |||
288 | */ | 297 | */ |
289 | bool completion_done(struct completion *x) | 298 | bool completion_done(struct completion *x) |
290 | { | 299 | { |
291 | unsigned long flags; | 300 | return !!ACCESS_ONCE(x->done); |
292 | int ret = 1; | ||
293 | |||
294 | spin_lock_irqsave(&x->wait.lock, flags); | ||
295 | if (!x->done) | ||
296 | ret = 0; | ||
297 | spin_unlock_irqrestore(&x->wait.lock, flags); | ||
298 | return ret; | ||
299 | } | 301 | } |
300 | EXPORT_SYMBOL(completion_done); | 302 | EXPORT_SYMBOL(completion_done); |
diff --git a/kernel/softirq.c b/kernel/softirq.c index 8cdb98847c7b..479e4436f787 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c | |||
@@ -114,8 +114,12 @@ void __local_bh_disable_ip(unsigned long ip, unsigned int cnt) | |||
114 | trace_softirqs_off(ip); | 114 | trace_softirqs_off(ip); |
115 | raw_local_irq_restore(flags); | 115 | raw_local_irq_restore(flags); |
116 | 116 | ||
117 | if (preempt_count() == cnt) | 117 | if (preempt_count() == cnt) { |
118 | #ifdef CONFIG_DEBUG_PREEMPT | ||
119 | current->preempt_disable_ip = get_parent_ip(CALLER_ADDR1); | ||
120 | #endif | ||
118 | trace_preempt_off(CALLER_ADDR0, get_parent_ip(CALLER_ADDR1)); | 121 | trace_preempt_off(CALLER_ADDR0, get_parent_ip(CALLER_ADDR1)); |
122 | } | ||
119 | } | 123 | } |
120 | EXPORT_SYMBOL(__local_bh_disable_ip); | 124 | EXPORT_SYMBOL(__local_bh_disable_ip); |
121 | #endif /* CONFIG_TRACE_IRQFLAGS */ | 125 | #endif /* CONFIG_TRACE_IRQFLAGS */ |