Commit d5ad85bc authored by Thomas Gleixner's avatar Thomas Gleixner

rtmutex: unify state manipulation

The manipulation of the waiter task state is copied all over the place
with slightly different details. Use one set of functions to reduce
duplicated code and make the handling consistent for all instances.
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent edeb8fe6
...@@ -696,13 +696,6 @@ rt_spin_lock_fastunlock(struct rt_mutex *lock, ...@@ -696,13 +696,6 @@ rt_spin_lock_fastunlock(struct rt_mutex *lock,
slowfn(lock); slowfn(lock);
} }
static inline void
update_current(unsigned long new_state, unsigned long *saved_state)
{
unsigned long state = xchg(&current->state, new_state);
if (unlikely(state == TASK_RUNNING))
*saved_state = TASK_RUNNING;
}
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
static int adaptive_wait(struct rt_mutex_waiter *waiter, static int adaptive_wait(struct rt_mutex_waiter *waiter,
...@@ -733,6 +726,34 @@ static int adaptive_wait(struct rt_mutex_waiter *waiter, ...@@ -733,6 +726,34 @@ static int adaptive_wait(struct rt_mutex_waiter *waiter,
} }
#endif #endif
/*
* The state setting needs to preserve the original state and needs to
* take care of non rtmutex wakeups.
*/
static inline unsigned long
rt_set_current_blocked_state(unsigned long saved_state)
{
unsigned long state;
state = xchg(&current->state, TASK_UNINTERRUPTIBLE);
/*
* Take care of non rtmutex wakeups. rtmutex wakeups
* set the state to TASK_RUNNING_MUTEX.
*/
if (state == TASK_RUNNING)
saved_state = TASK_RUNNING;
return saved_state;
}
static inline void rt_restore_current_state(unsigned long saved_state)
{
unsigned long state = xchg(&current->state, saved_state);
if (state == TASK_RUNNING)
current->state = TASK_RUNNING;
}
/* /*
* Slow path lock function spin_lock style: this variant is very * Slow path lock function spin_lock style: this variant is very
* careful not to miss any non-lock wakeups. * careful not to miss any non-lock wakeups.
...@@ -747,7 +768,7 @@ static void noinline __sched ...@@ -747,7 +768,7 @@ static void noinline __sched
rt_spin_lock_slowlock(struct rt_mutex *lock) rt_spin_lock_slowlock(struct rt_mutex *lock)
{ {
struct rt_mutex_waiter waiter; struct rt_mutex_waiter waiter;
unsigned long saved_state, state, flags; unsigned long saved_state, flags;
struct task_struct *orig_owner; struct task_struct *orig_owner;
int missed = 0; int missed = 0;
...@@ -766,7 +787,9 @@ rt_spin_lock_slowlock(struct rt_mutex *lock) ...@@ -766,7 +787,9 @@ rt_spin_lock_slowlock(struct rt_mutex *lock)
* of the lock sleep/wakeup mechanism. When we get a real * of the lock sleep/wakeup mechanism. When we get a real
* wakeup the task->state is TASK_RUNNING and we change * wakeup the task->state is TASK_RUNNING and we change
* saved_state accordingly. If we did not get a real wakeup * saved_state accordingly. If we did not get a real wakeup
* then we return with the saved state. * then we return with the saved state. We need to be careful
* about original state TASK_INTERRUPTIBLE as well, as we
* could miss a wakeup_interruptible()
*/ */
saved_state = current->state; saved_state = current->state;
...@@ -808,7 +831,8 @@ rt_spin_lock_slowlock(struct rt_mutex *lock) ...@@ -808,7 +831,8 @@ rt_spin_lock_slowlock(struct rt_mutex *lock)
if (adaptive_wait(&waiter, orig_owner)) { if (adaptive_wait(&waiter, orig_owner)) {
put_task_struct(orig_owner); put_task_struct(orig_owner);
update_current(TASK_UNINTERRUPTIBLE, &saved_state);
saved_state = rt_set_current_blocked_state(saved_state);
/* /*
* The xchg() in update_current() is an implicit * The xchg() in update_current() is an implicit
* barrier which we rely upon to ensure current->state * barrier which we rely upon to ensure current->state
...@@ -823,9 +847,7 @@ rt_spin_lock_slowlock(struct rt_mutex *lock) ...@@ -823,9 +847,7 @@ rt_spin_lock_slowlock(struct rt_mutex *lock)
current->lock_depth = saved_lock_depth; current->lock_depth = saved_lock_depth;
} }
state = xchg(&current->state, saved_state); rt_restore_current_state(saved_state);
if (unlikely(state == TASK_RUNNING))
current->state = TASK_RUNNING;
/* /*
* Extremely rare case, if we got woken up by a non-mutex wakeup, * Extremely rare case, if we got woken up by a non-mutex wakeup,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment