diff options
author | Kevin Hao <kexin.hao@windriver.com> | 2010-03-02 16:51:58 -0500 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2010-04-27 17:24:39 +0200 |
commit | 923499cb1cf693b1f4e35711a34568864898876a (patch) | |
tree | a415fedd06b70614aa6ea3e1caba5023baa69f9b | |
parent | 1268870be30e4571b0e007c986231c434c3b4912 (diff) | |
download | lwn-923499cb1cf693b1f4e35711a34568864898876a.tar.gz lwn-923499cb1cf693b1f4e35711a34568864898876a.zip |
rtmutex: Preserve TASK_STOPPED state when blocking on a "spin_lock"
When a process handles a SIGSTOP signal, it will set the state to
TASK_STOPPED, acquire tasklist_lock and notifiy the parent of the
status change. But in the rt kernel the process state will change
to TASK_UNINTERRUPTIBLE if it blocks on the tasklist_lock. So if
we send a SIGCONT signal to this process at this time, the SIGCONT
signal just does nothing because this process is not in TASK_STOPPED
state. Of course this is not what we wanted. Preserving the
TASK_STOPPED state when blocking on a "spin_lock" can fix this bug.
Signed-off-by: Kevin Hao <kexin.hao@windriver.com>
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
LKML-Reference: <18e240905fcfd72457930322ee187e7ff9313aec.1267566249.git.paul.gortmaker@windriver.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r-- | kernel/rtmutex.c | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/kernel/rtmutex.c b/kernel/rtmutex.c index 16bfa1c0d948..23dd44372d8b 100644 --- a/kernel/rtmutex.c +++ b/kernel/rtmutex.c @@ -757,8 +757,9 @@ rt_set_current_blocked_state(unsigned long saved_state) * saved_state. Now we can ignore further wakeups as we will * return in state running from our "spin" sleep. */ - if (saved_state == TASK_INTERRUPTIBLE) - block_state = TASK_INTERRUPTIBLE; + if (saved_state == TASK_INTERRUPTIBLE || + saved_state == TASK_STOPPED) + block_state = saved_state; else block_state = TASK_UNINTERRUPTIBLE; |