diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2011-06-25 09:21:04 +0200 |
---|---|---|
committer | Clark Williams <williams@redhat.com> | 2012-02-15 10:32:47 -0600 |
commit | 44784ea48f337706836e0a05082265f531f32ff3 (patch) | |
tree | 8293a8dedf9129d310af9ea689239634098cad4b /kernel | |
parent | 2ee05a75c070ce8c1b5577eb8909c762966d278f (diff) |
sched-rt-mutex-wakeup.patch
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/sched.c | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/kernel/sched.c b/kernel/sched.c index 3ff2d0f1fcfe..f101d970ebda 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -2827,8 +2827,25 @@ try_to_wake_up(struct task_struct *p, unsigned int state, int wake_flags) smp_wmb(); raw_spin_lock_irqsave(&p->pi_lock, flags); - if (!(p->state & state)) + if (!(p->state & state)) { + /* + * The task might be running due to a spinlock sleeper + * wakeup. Check the saved state and set it to running + * if the wakeup condition is true. + */ + if (!(wake_flags & WF_LOCK_SLEEPER)) { + if (p->saved_state & state) + p->saved_state = TASK_RUNNING; + } goto out; + } + + /* + * If this is a regular wakeup, then we can unconditionally + * clear the saved state of a "lock sleeper". + */ + if (!(wake_flags & WF_LOCK_SLEEPER)) + p->saved_state = TASK_RUNNING; success = 1; /* we're going to change ->state */ cpu = task_cpu(p); @@ -2900,6 +2917,18 @@ int wake_up_process(struct task_struct *p) } EXPORT_SYMBOL(wake_up_process); +/** + * wake_up_lock_sleeper - Wake up a specific process blocked on a "sleeping lock" + * @p: The process to be woken up. + * + * Same as wake_up_process() above, but wake_flags=WF_LOCK_SLEEPER to indicate + * the nature of the wakeup. + */ +int wake_up_lock_sleeper(struct task_struct *p) +{ + return try_to_wake_up(p, TASK_ALL, WF_LOCK_SLEEPER); +} + int wake_up_state(struct task_struct *p, unsigned int state) { return try_to_wake_up(p, state, 0); |