Skip to content

Commit c014ef6

Browse files
KAGA-KOKOIngo Molnar
authored andcommitted
locking/rtmutex: Add wake_state to rt_mutex_waiter
Regular sleeping locks like mutexes, rtmutexes and rw_semaphores are always entering and leaving a blocking section with task state == TASK_RUNNING. On a non-RT kernel spinlocks and rwlocks never affect the task state, but on RT kernels these locks are converted to rtmutex based 'sleeping' locks. So in case of contention the task goes to block, which requires to carefully preserve the task state, and restore it after acquiring the lock taking regular wakeups for the task into account, which happened while the task was blocked. This state preserving is achieved by having a separate task state for blocking on a RT spin/rwlock and a saved_state field in task_struct along with careful handling of these wakeup scenarios in try_to_wake_up(). To avoid conditionals in the rtmutex code, store the wake state which has to be used for waking a lock waiter in rt_mutex_waiter which allows to handle the regular and RT spin/rwlocks by handing it to wake_up_state(). Signed-off-by: Thomas Gleixner <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Signed-off-by: Ingo Molnar <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 4225410 commit c014ef6

File tree

2 files changed

+10
-1
lines changed

2 files changed

+10
-1
lines changed

kernel/locking/rtmutex.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -692,7 +692,7 @@ static int __sched rt_mutex_adjust_prio_chain(struct task_struct *task,
692692
* to get the lock.
693693
*/
694694
if (prerequeue_top_waiter != rt_mutex_top_waiter(lock))
695-
wake_up_process(rt_mutex_top_waiter(lock)->task);
695+
wake_up_state(waiter->task, waiter->wake_state);
696696
raw_spin_unlock_irq(&lock->wait_lock);
697697
return 0;
698698
}

kernel/locking/rtmutex_common.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
* @pi_tree_entry: pi node to enqueue into the mutex owner waiters tree
2626
* @task: task reference to the blocked task
2727
* @lock: Pointer to the rt_mutex on which the waiter blocks
28+
* @wake_state: Wakeup state to use (TASK_NORMAL or TASK_RTLOCK_WAIT)
2829
* @prio: Priority of the waiter
2930
* @deadline: Deadline of the waiter if applicable
3031
*/
@@ -33,6 +34,7 @@ struct rt_mutex_waiter {
3334
struct rb_node pi_tree_entry;
3435
struct task_struct *task;
3536
struct rt_mutex_base *lock;
37+
unsigned int wake_state;
3638
int prio;
3739
u64 deadline;
3840
};
@@ -158,9 +160,16 @@ static inline void rt_mutex_init_waiter(struct rt_mutex_waiter *waiter)
158160
debug_rt_mutex_init_waiter(waiter);
159161
RB_CLEAR_NODE(&waiter->pi_tree_entry);
160162
RB_CLEAR_NODE(&waiter->tree_entry);
163+
waiter->wake_state = TASK_NORMAL;
161164
waiter->task = NULL;
162165
}
163166

167+
static inline void rtlock_init_rtmutex_waiter(struct rt_mutex_waiter *waiter)
168+
{
169+
rt_mutex_init_waiter(waiter);
170+
waiter->wake_state = TASK_RTLOCK_WAIT;
171+
}
172+
164173
#else /* CONFIG_RT_MUTEXES */
165174
/* Used in rcu/tree_plugin.h */
166175
static inline struct task_struct *rt_mutex_owner(struct rt_mutex_base *lock)

0 commit comments

Comments
 (0)