| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * RT-Mutexes: simple blocking mutual exclusion locks with PI support |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 8 | 9 | * Copyright (C) 2005 Kihon Technologies Inc., Steven Rostedt |
|---|
| 9 | 10 | * Copyright (C) 2006 Esben Nielsen |
|---|
| 10 | 11 | * |
|---|
| 11 | | - * See Documentation/locking/rt-mutex-design.txt for details. |
|---|
| 12 | + * See Documentation/locking/rt-mutex-design.rst for details. |
|---|
| 12 | 13 | */ |
|---|
| 13 | 14 | #include <linux/spinlock.h> |
|---|
| 14 | 15 | #include <linux/export.h> |
|---|
| .. | .. |
|---|
| 18 | 19 | #include <linux/sched/wake_q.h> |
|---|
| 19 | 20 | #include <linux/sched/debug.h> |
|---|
| 20 | 21 | #include <linux/timer.h> |
|---|
| 22 | +#include <trace/hooks/dtask.h> |
|---|
| 21 | 23 | |
|---|
| 22 | 24 | #include "rtmutex_common.h" |
|---|
| 23 | 25 | |
|---|
| .. | .. |
|---|
| 56 | 58 | if (rt_mutex_has_waiters(lock)) |
|---|
| 57 | 59 | val |= RT_MUTEX_HAS_WAITERS; |
|---|
| 58 | 60 | |
|---|
| 59 | | - lock->owner = (struct task_struct *)val; |
|---|
| 61 | + WRITE_ONCE(lock->owner, (struct task_struct *)val); |
|---|
| 60 | 62 | } |
|---|
| 61 | 63 | |
|---|
| 62 | 64 | static inline void clear_rt_mutex_waiters(struct rt_mutex *lock) |
|---|
| .. | .. |
|---|
| 140 | 142 | * set up. |
|---|
| 141 | 143 | */ |
|---|
| 142 | 144 | #ifndef CONFIG_DEBUG_RT_MUTEXES |
|---|
| 143 | | -# define rt_mutex_cmpxchg_relaxed(l,c,n) (cmpxchg_relaxed(&l->owner, c, n) == c) |
|---|
| 144 | 145 | # define rt_mutex_cmpxchg_acquire(l,c,n) (cmpxchg_acquire(&l->owner, c, n) == c) |
|---|
| 145 | 146 | # define rt_mutex_cmpxchg_release(l,c,n) (cmpxchg_release(&l->owner, c, n) == c) |
|---|
| 146 | 147 | |
|---|
| .. | .. |
|---|
| 201 | 202 | } |
|---|
| 202 | 203 | |
|---|
| 203 | 204 | #else |
|---|
| 204 | | -# define rt_mutex_cmpxchg_relaxed(l,c,n) (0) |
|---|
| 205 | 205 | # define rt_mutex_cmpxchg_acquire(l,c,n) (0) |
|---|
| 206 | 206 | # define rt_mutex_cmpxchg_release(l,c,n) (0) |
|---|
| 207 | 207 | |
|---|
| .. | .. |
|---|
| 627 | 627 | } |
|---|
| 628 | 628 | |
|---|
| 629 | 629 | /* [10] Grab the next task, i.e. owner of @lock */ |
|---|
| 630 | | - task = rt_mutex_owner(lock); |
|---|
| 631 | | - get_task_struct(task); |
|---|
| 630 | + task = get_task_struct(rt_mutex_owner(lock)); |
|---|
| 632 | 631 | raw_spin_lock(&task->pi_lock); |
|---|
| 633 | 632 | |
|---|
| 634 | 633 | /* |
|---|
| .. | .. |
|---|
| 708 | 707 | } |
|---|
| 709 | 708 | |
|---|
| 710 | 709 | /* [10] Grab the next task, i.e. the owner of @lock */ |
|---|
| 711 | | - task = rt_mutex_owner(lock); |
|---|
| 712 | | - get_task_struct(task); |
|---|
| 710 | + task = get_task_struct(rt_mutex_owner(lock)); |
|---|
| 713 | 711 | raw_spin_lock(&task->pi_lock); |
|---|
| 714 | 712 | |
|---|
| 715 | 713 | /* [11] requeue the pi waiters if necessary */ |
|---|
| .. | .. |
|---|
| 1171 | 1169 | { |
|---|
| 1172 | 1170 | int ret = 0; |
|---|
| 1173 | 1171 | |
|---|
| 1172 | + trace_android_vh_rtmutex_wait_start(lock); |
|---|
| 1174 | 1173 | for (;;) { |
|---|
| 1175 | 1174 | /* Try to acquire the lock: */ |
|---|
| 1176 | 1175 | if (try_to_take_rt_mutex(lock, current, waiter)) |
|---|
| .. | .. |
|---|
| 1200 | 1199 | set_current_state(state); |
|---|
| 1201 | 1200 | } |
|---|
| 1202 | 1201 | |
|---|
| 1202 | + trace_android_vh_rtmutex_wait_finish(lock); |
|---|
| 1203 | 1203 | __set_current_state(TASK_RUNNING); |
|---|
| 1204 | 1204 | return ret; |
|---|
| 1205 | 1205 | } |
|---|
| .. | .. |
|---|
| 1441 | 1441 | } |
|---|
| 1442 | 1442 | |
|---|
| 1443 | 1443 | /* |
|---|
| 1444 | | - * Performs the wakeup of the the top-waiter and re-enables preemption. |
|---|
| 1444 | + * Performs the wakeup of the top-waiter and re-enables preemption. |
|---|
| 1445 | 1445 | */ |
|---|
| 1446 | 1446 | void rt_mutex_postunlock(struct wake_q_head *wake_q) |
|---|
| 1447 | 1447 | { |
|---|
| .. | .. |
|---|
| 1471 | 1471 | |
|---|
| 1472 | 1472 | mutex_acquire(&lock->dep_map, subclass, 0, _RET_IP_); |
|---|
| 1473 | 1473 | rt_mutex_fastlock(lock, TASK_UNINTERRUPTIBLE, rt_mutex_slowlock); |
|---|
| 1474 | + trace_android_vh_record_rtmutex_lock_starttime(current, jiffies); |
|---|
| 1474 | 1475 | } |
|---|
| 1475 | 1476 | |
|---|
| 1476 | 1477 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
|---|
| .. | .. |
|---|
| 1485 | 1486 | __rt_mutex_lock(lock, subclass); |
|---|
| 1486 | 1487 | } |
|---|
| 1487 | 1488 | EXPORT_SYMBOL_GPL(rt_mutex_lock_nested); |
|---|
| 1488 | | -#endif |
|---|
| 1489 | 1489 | |
|---|
| 1490 | | -#ifndef CONFIG_DEBUG_LOCK_ALLOC |
|---|
| 1490 | +#else /* !CONFIG_DEBUG_LOCK_ALLOC */ |
|---|
| 1491 | + |
|---|
| 1491 | 1492 | /** |
|---|
| 1492 | 1493 | * rt_mutex_lock - lock a rt_mutex |
|---|
| 1493 | 1494 | * |
|---|
| .. | .. |
|---|
| 1518 | 1519 | mutex_acquire(&lock->dep_map, 0, 0, _RET_IP_); |
|---|
| 1519 | 1520 | ret = rt_mutex_fastlock(lock, TASK_INTERRUPTIBLE, rt_mutex_slowlock); |
|---|
| 1520 | 1521 | if (ret) |
|---|
| 1521 | | - mutex_release(&lock->dep_map, 1, _RET_IP_); |
|---|
| 1522 | + mutex_release(&lock->dep_map, _RET_IP_); |
|---|
| 1523 | + else |
|---|
| 1524 | + trace_android_vh_record_rtmutex_lock_starttime(current, jiffies); |
|---|
| 1522 | 1525 | |
|---|
| 1523 | 1526 | return ret; |
|---|
| 1524 | 1527 | } |
|---|
| .. | .. |
|---|
| 1562 | 1565 | RT_MUTEX_MIN_CHAINWALK, |
|---|
| 1563 | 1566 | rt_mutex_slowlock); |
|---|
| 1564 | 1567 | if (ret) |
|---|
| 1565 | | - mutex_release(&lock->dep_map, 1, _RET_IP_); |
|---|
| 1568 | + mutex_release(&lock->dep_map, _RET_IP_); |
|---|
| 1569 | + else |
|---|
| 1570 | + trace_android_vh_record_rtmutex_lock_starttime(current, jiffies); |
|---|
| 1566 | 1571 | |
|---|
| 1567 | 1572 | return ret; |
|---|
| 1568 | 1573 | } |
|---|
| .. | .. |
|---|
| 1589 | 1594 | ret = rt_mutex_fasttrylock(lock, rt_mutex_slowtrylock); |
|---|
| 1590 | 1595 | if (ret) |
|---|
| 1591 | 1596 | mutex_acquire(&lock->dep_map, 0, 1, _RET_IP_); |
|---|
| 1597 | + else |
|---|
| 1598 | + trace_android_vh_record_rtmutex_lock_starttime(current, jiffies); |
|---|
| 1592 | 1599 | |
|---|
| 1593 | 1600 | return ret; |
|---|
| 1594 | 1601 | } |
|---|
| .. | .. |
|---|
| 1601 | 1608 | */ |
|---|
| 1602 | 1609 | void __sched rt_mutex_unlock(struct rt_mutex *lock) |
|---|
| 1603 | 1610 | { |
|---|
| 1604 | | - mutex_release(&lock->dep_map, 1, _RET_IP_); |
|---|
| 1611 | + mutex_release(&lock->dep_map, _RET_IP_); |
|---|
| 1605 | 1612 | rt_mutex_fastunlock(lock, rt_mutex_slowunlock); |
|---|
| 1613 | + trace_android_vh_record_rtmutex_lock_starttime(current, 0); |
|---|
| 1606 | 1614 | } |
|---|
| 1607 | 1615 | EXPORT_SYMBOL_GPL(rt_mutex_unlock); |
|---|
| 1608 | 1616 | |
|---|
| .. | .. |
|---|
| 1835 | 1843 | * been started. |
|---|
| 1836 | 1844 | * @waiter: the pre-initialized rt_mutex_waiter |
|---|
| 1837 | 1845 | * |
|---|
| 1838 | | - * Wait for the the lock acquisition started on our behalf by |
|---|
| 1846 | + * Wait for the lock acquisition started on our behalf by |
|---|
| 1839 | 1847 | * rt_mutex_start_proxy_lock(). Upon failure, the caller must call |
|---|
| 1840 | 1848 | * rt_mutex_cleanup_proxy_lock(). |
|---|
| 1841 | 1849 | * |
|---|