aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/futex.c
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2016-01-13 05:25:38 -0500
committerThomas Gleixner <tglx@linutronix.de>2016-01-26 05:08:35 -0500
commitb4abf91047cf054f203dcfac97e1038388826937 (patch)
treea018e1a33d72f3c8f154db82acad5b70858417ba /kernel/futex.c
parent92e963f50fc74041b5e9e744c330dca48e04f08d (diff)
rtmutex: Make wait_lock irq safe
Sasha reported a lockdep splat about a potential deadlock between RCU boosting rtmutex and the posix timer it_lock. CPU0 CPU1 rtmutex_lock(&rcu->rt_mutex) spin_lock(&rcu->rt_mutex.wait_lock) local_irq_disable() spin_lock(&timer->it_lock) spin_lock(&rcu->mutex.wait_lock) --> Interrupt spin_lock(&timer->it_lock) This is caused by the following code sequence on CPU1 rcu_read_lock() x = lookup(); if (x) spin_lock_irqsave(&x->it_lock); rcu_read_unlock(); return x; We could fix that in the posix timer code by keeping rcu read locked across the spinlocked and irq disabled section, but the above sequence is common and there is no reason not to support it. Taking rt_mutex.wait_lock irq safe prevents the deadlock. Reported-by: Sasha Levin <sasha.levin@oracle.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Paul McKenney <paulmck@linux.vnet.ibm.com>
Diffstat (limited to 'kernel/futex.c')
-rw-r--r--kernel/futex.c18
1 files changed, 9 insertions, 9 deletions
diff --git a/kernel/futex.c b/kernel/futex.c
index 0773f2b23b10..5d6ce6413ef1 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -1191,7 +1191,7 @@ static int wake_futex_pi(u32 __user *uaddr, u32 uval, struct futex_q *this,
1191 if (pi_state->owner != current) 1191 if (pi_state->owner != current)
1192 return -EINVAL; 1192 return -EINVAL;
1193 1193
1194 raw_spin_lock(&pi_state->pi_mutex.wait_lock); 1194 raw_spin_lock_irq(&pi_state->pi_mutex.wait_lock);
1195 new_owner = rt_mutex_next_owner(&pi_state->pi_mutex); 1195 new_owner = rt_mutex_next_owner(&pi_state->pi_mutex);
1196 1196
1197 /* 1197 /*
@@ -1217,22 +1217,22 @@ static int wake_futex_pi(u32 __user *uaddr, u32 uval, struct futex_q *this,
1217 else if (curval != uval) 1217 else if (curval != uval)
1218 ret = -EINVAL; 1218 ret = -EINVAL;
1219 if (ret) { 1219 if (ret) {
1220 raw_spin_unlock(&pi_state->pi_mutex.wait_lock); 1220 raw_spin_unlock_irq(&pi_state->pi_mutex.wait_lock);
1221 return ret; 1221 return ret;
1222 } 1222 }
1223 1223
1224 raw_spin_lock_irq(&pi_state->owner->pi_lock); 1224 raw_spin_lock(&pi_state->owner->pi_lock);
1225 WARN_ON(list_empty(&pi_state->list)); 1225 WARN_ON(list_empty(&pi_state->list));
1226 list_del_init(&pi_state->list); 1226 list_del_init(&pi_state->list);
1227 raw_spin_unlock_irq(&pi_state->owner->pi_lock); 1227 raw_spin_unlock(&pi_state->owner->pi_lock);
1228 1228
1229 raw_spin_lock_irq(&new_owner->pi_lock); 1229 raw_spin_lock(&new_owner->pi_lock);
1230 WARN_ON(!list_empty(&pi_state->list)); 1230 WARN_ON(!list_empty(&pi_state->list));
1231 list_add(&pi_state->list, &new_owner->pi_state_list); 1231 list_add(&pi_state->list, &new_owner->pi_state_list);
1232 pi_state->owner = new_owner; 1232 pi_state->owner = new_owner;
1233 raw_spin_unlock_irq(&new_owner->pi_lock); 1233 raw_spin_unlock(&new_owner->pi_lock);
1234 1234
1235 raw_spin_unlock(&pi_state->pi_mutex.wait_lock); 1235 raw_spin_unlock_irq(&pi_state->pi_mutex.wait_lock);
1236 1236
1237 deboost = rt_mutex_futex_unlock(&pi_state->pi_mutex, &wake_q); 1237 deboost = rt_mutex_futex_unlock(&pi_state->pi_mutex, &wake_q);
1238 1238
@@ -2127,11 +2127,11 @@ static int fixup_owner(u32 __user *uaddr, struct futex_q *q, int locked)
2127 * we returned due to timeout or signal without taking the 2127 * we returned due to timeout or signal without taking the
2128 * rt_mutex. Too late. 2128 * rt_mutex. Too late.
2129 */ 2129 */
2130 raw_spin_lock(&q->pi_state->pi_mutex.wait_lock); 2130 raw_spin_lock_irq(&q->pi_state->pi_mutex.wait_lock);
2131 owner = rt_mutex_owner(&q->pi_state->pi_mutex); 2131 owner = rt_mutex_owner(&q->pi_state->pi_mutex);
2132 if (!owner) 2132 if (!owner)
2133 owner = rt_mutex_next_owner(&q->pi_state->pi_mutex); 2133 owner = rt_mutex_next_owner(&q->pi_state->pi_mutex);
2134 raw_spin_unlock(&q->pi_state->pi_mutex.wait_lock); 2134 raw_spin_unlock_irq(&q->pi_state->pi_mutex.wait_lock);
2135 ret = fixup_pi_state_owner(uaddr, q, owner); 2135 ret = fixup_pi_state_owner(uaddr, q, owner);
2136 goto out; 2136 goto out;
2137 } 2137 }