[PATCH 2/8] rearrange rt_spin_lock_slowlock sleeping code

From: Gregory Haskins
Date: Mon May 19 2008 - 13:40:43 EST


The current logic makes rather coarse adjustments to current->state since
it is planning on sleeping anyway. We want to eventually move to an
adaptive (e.g. optional sleep) algorithm, so we tighten the scope of the
adjustments to bracket the schedule(). This should yield correct behavior
with or without the adaptive features that are added later in the series.
We add it here as a separate patch for greater review clarity on smaller
changes.

Thanks to Steven Rostedt for suggesting a cleanup to remove an extra
update_current(RUNNING_MUTEX) left over from the early days of
instrumentation.

Signed-off-by: Gregory Haskins <ghaskins@xxxxxxxxxx>
---

kernel/rtmutex.c | 17 ++++++++++++-----
1 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/kernel/rtmutex.c b/kernel/rtmutex.c
index 0d3f76f..223557f 100644
--- a/kernel/rtmutex.c
+++ b/kernel/rtmutex.c
@@ -666,6 +666,14 @@ rt_spin_lock_fastunlock(struct rt_mutex *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;
+}
+
/*
* Slow path lock function spin_lock style: this variant is very
* careful not to miss any non-lock wakeups.
@@ -705,7 +713,7 @@ rt_spin_lock_slowlock(struct rt_mutex *lock)
* saved_state accordingly. If we did not get a real wakeup
* then we return with the saved state.
*/
- saved_state = xchg(&current->state, TASK_UNINTERRUPTIBLE);
+ saved_state = current->state;

for (;;) {
unsigned long saved_flags;
@@ -737,14 +745,13 @@ rt_spin_lock_slowlock(struct rt_mutex *lock)

debug_rt_mutex_print_deadlock(&waiter);

- schedule_rt_mutex(lock);
+ update_current(TASK_UNINTERRUPTIBLE, &saved_state);
+ if (waiter.task)
+ schedule_rt_mutex(lock);

spin_lock_irqsave(&lock->wait_lock, flags);
current->flags |= saved_flags;
current->lock_depth = saved_lock_depth;
- state = xchg(&current->state, TASK_UNINTERRUPTIBLE);
- if (unlikely(state == TASK_RUNNING))
- saved_state = TASK_RUNNING;
}

state = xchg(&current->state, saved_state);

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/