Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

rtmutex: Confine deadlock logic to futex

The deadlock logic is only required for futexes.

Remove the extra arguments for the public functions and also for the
futex specific ones which get always called with deadlock detection
enabled.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Steven Rostedt <rostedt@goodmis.org>

+40 -42
+2 -4
include/linux/rtmutex.h
··· 90 90 extern void rt_mutex_destroy(struct rt_mutex *lock); 91 91 92 92 extern void rt_mutex_lock(struct rt_mutex *lock); 93 - extern int rt_mutex_lock_interruptible(struct rt_mutex *lock, 94 - int detect_deadlock); 93 + extern int rt_mutex_lock_interruptible(struct rt_mutex *lock); 95 94 extern int rt_mutex_timed_lock(struct rt_mutex *lock, 96 - struct hrtimer_sleeper *timeout, 97 - int detect_deadlock); 95 + struct hrtimer_sleeper *timeout); 98 96 99 97 extern int rt_mutex_trylock(struct rt_mutex *lock); 100 98
+5 -5
kernel/futex.c
··· 1718 1718 this->pi_state = pi_state; 1719 1719 ret = rt_mutex_start_proxy_lock(&pi_state->pi_mutex, 1720 1720 this->rt_waiter, 1721 - this->task, 1); 1721 + this->task); 1722 1722 if (ret == 1) { 1723 1723 /* We got the lock. */ 1724 1724 requeue_pi_wake_futex(this, &key2, hb2); ··· 2337 2337 /* 2338 2338 * Block on the PI mutex: 2339 2339 */ 2340 - if (!trylock) 2341 - ret = rt_mutex_timed_lock(&q.pi_state->pi_mutex, to, 1); 2342 - else { 2340 + if (!trylock) { 2341 + ret = rt_mutex_timed_futex_lock(&q.pi_state->pi_mutex, to); 2342 + } else { 2343 2343 ret = rt_mutex_trylock(&q.pi_state->pi_mutex); 2344 2344 /* Fixup the trylock return value: */ 2345 2345 ret = ret ? 0 : -EWOULDBLOCK; ··· 2669 2669 */ 2670 2670 WARN_ON(!q.pi_state); 2671 2671 pi_mutex = &q.pi_state->pi_mutex; 2672 - ret = rt_mutex_finish_proxy_lock(pi_mutex, to, &rt_waiter, 1); 2672 + ret = rt_mutex_finish_proxy_lock(pi_mutex, to, &rt_waiter); 2673 2673 debug_rt_mutex_free_waiter(&rt_waiter); 2674 2674 2675 2675 spin_lock(q.lock_ptr);
+30 -29
kernel/locking/rtmutex.c
··· 1228 1228 */ 1229 1229 static inline int 1230 1230 rt_mutex_fastlock(struct rt_mutex *lock, int state, 1231 - int detect_deadlock, 1232 1231 int (*slowfn)(struct rt_mutex *lock, int state, 1233 1232 struct hrtimer_sleeper *timeout, 1234 1233 int detect_deadlock)) 1235 1234 { 1236 - if (!detect_deadlock && likely(rt_mutex_cmpxchg(lock, NULL, current))) { 1235 + if (likely(rt_mutex_cmpxchg(lock, NULL, current))) { 1237 1236 rt_mutex_deadlock_account_lock(lock, current); 1238 1237 return 0; 1239 1238 } else 1240 - return slowfn(lock, state, NULL, detect_deadlock); 1239 + return slowfn(lock, state, NULL, 0); 1241 1240 } 1242 1241 1243 1242 static inline int ··· 1283 1284 { 1284 1285 might_sleep(); 1285 1286 1286 - rt_mutex_fastlock(lock, TASK_UNINTERRUPTIBLE, 0, rt_mutex_slowlock); 1287 + rt_mutex_fastlock(lock, TASK_UNINTERRUPTIBLE, rt_mutex_slowlock); 1287 1288 } 1288 1289 EXPORT_SYMBOL_GPL(rt_mutex_lock); 1289 1290 1290 1291 /** 1291 1292 * rt_mutex_lock_interruptible - lock a rt_mutex interruptible 1292 1293 * 1293 - * @lock: the rt_mutex to be locked 1294 - * @detect_deadlock: deadlock detection on/off 1294 + * @lock: the rt_mutex to be locked 1295 1295 * 1296 1296 * Returns: 1297 - * 0 on success 1298 - * -EINTR when interrupted by a signal 1299 - * -EDEADLK when the lock would deadlock (when deadlock detection is on) 1297 + * 0 on success 1298 + * -EINTR when interrupted by a signal 1300 1299 */ 1301 - int __sched rt_mutex_lock_interruptible(struct rt_mutex *lock, 1302 - int detect_deadlock) 1300 + int __sched rt_mutex_lock_interruptible(struct rt_mutex *lock) 1303 1301 { 1304 1302 might_sleep(); 1305 1303 1306 - return rt_mutex_fastlock(lock, TASK_INTERRUPTIBLE, 1307 - detect_deadlock, rt_mutex_slowlock); 1304 + return rt_mutex_fastlock(lock, TASK_INTERRUPTIBLE, rt_mutex_slowlock); 1308 1305 } 1309 1306 EXPORT_SYMBOL_GPL(rt_mutex_lock_interruptible); 1307 + 1308 + /* 1309 + * Futex variant with full deadlock detection. 1310 + */ 1311 + int rt_mutex_timed_futex_lock(struct rt_mutex *lock, 1312 + struct hrtimer_sleeper *timeout) 1313 + { 1314 + might_sleep(); 1315 + 1316 + return rt_mutex_timed_fastlock(lock, TASK_INTERRUPTIBLE, timeout, 1, 1317 + rt_mutex_slowlock); 1318 + } 1310 1319 1311 1320 /** 1312 1321 * rt_mutex_timed_lock - lock a rt_mutex interruptible 1313 1322 * the timeout structure is provided 1314 1323 * by the caller 1315 1324 * 1316 - * @lock: the rt_mutex to be locked 1325 + * @lock: the rt_mutex to be locked 1317 1326 * @timeout: timeout structure or NULL (no timeout) 1318 - * @detect_deadlock: deadlock detection on/off 1319 1327 * 1320 1328 * Returns: 1321 - * 0 on success 1322 - * -EINTR when interrupted by a signal 1329 + * 0 on success 1330 + * -EINTR when interrupted by a signal 1323 1331 * -ETIMEDOUT when the timeout expired 1324 - * -EDEADLK when the lock would deadlock (when deadlock detection is on) 1325 1332 */ 1326 1333 int 1327 - rt_mutex_timed_lock(struct rt_mutex *lock, struct hrtimer_sleeper *timeout, 1328 - int detect_deadlock) 1334 + rt_mutex_timed_lock(struct rt_mutex *lock, struct hrtimer_sleeper *timeout) 1329 1335 { 1330 1336 might_sleep(); 1331 1337 1332 - return rt_mutex_timed_fastlock(lock, TASK_INTERRUPTIBLE, timeout, 1333 - detect_deadlock, rt_mutex_slowlock); 1338 + return rt_mutex_timed_fastlock(lock, TASK_INTERRUPTIBLE, timeout, 0, 1339 + rt_mutex_slowlock); 1334 1340 } 1335 1341 EXPORT_SYMBOL_GPL(rt_mutex_timed_lock); 1336 1342 ··· 1441 1437 * @lock: the rt_mutex to take 1442 1438 * @waiter: the pre-initialized rt_mutex_waiter 1443 1439 * @task: the task to prepare 1444 - * @detect_deadlock: perform deadlock detection (1) or not (0) 1445 1440 * 1446 1441 * Returns: 1447 1442 * 0 - task blocked on lock ··· 1451 1448 */ 1452 1449 int rt_mutex_start_proxy_lock(struct rt_mutex *lock, 1453 1450 struct rt_mutex_waiter *waiter, 1454 - struct task_struct *task, int detect_deadlock) 1451 + struct task_struct *task) 1455 1452 { 1456 1453 int ret; 1457 1454 ··· 1509 1506 * rt_mutex_finish_proxy_lock() - Complete lock acquisition 1510 1507 * @lock: the rt_mutex we were woken on 1511 1508 * @to: the timeout, null if none. hrtimer should already have 1512 - * been started. 1509 + * been started. 1513 1510 * @waiter: the pre-initialized rt_mutex_waiter 1514 - * @detect_deadlock: perform deadlock detection (1) or not (0) 1515 1511 * 1516 1512 * Complete the lock acquisition started our behalf by another thread. 1517 1513 * 1518 1514 * Returns: 1519 1515 * 0 - success 1520 - * <0 - error, one of -EINTR, -ETIMEDOUT, or -EDEADLK 1516 + * <0 - error, one of -EINTR, -ETIMEDOUT 1521 1517 * 1522 1518 * Special API call for PI-futex requeue support 1523 1519 */ 1524 1520 int rt_mutex_finish_proxy_lock(struct rt_mutex *lock, 1525 1521 struct hrtimer_sleeper *to, 1526 - struct rt_mutex_waiter *waiter, 1527 - int detect_deadlock) 1522 + struct rt_mutex_waiter *waiter) 1528 1523 { 1529 1524 int ret; 1530 1525
+3 -4
kernel/locking/rtmutex_common.h
··· 111 111 struct task_struct *proxy_owner); 112 112 extern int rt_mutex_start_proxy_lock(struct rt_mutex *lock, 113 113 struct rt_mutex_waiter *waiter, 114 - struct task_struct *task, 115 - int detect_deadlock); 114 + struct task_struct *task); 116 115 extern int rt_mutex_finish_proxy_lock(struct rt_mutex *lock, 117 116 struct hrtimer_sleeper *to, 118 - struct rt_mutex_waiter *waiter, 119 - int detect_deadlock); 117 + struct rt_mutex_waiter *waiter); 118 + extern int rt_mutex_timed_futex_lock(struct rt_mutex *l, struct hrtimer_sleeper *to); 120 119 121 120 #ifdef CONFIG_DEBUG_RT_MUTEXES 122 121 # include "rtmutex-debug.h"