diff options
Diffstat (limited to 'kernel/power/process.c')
-rw-r--r-- | kernel/power/process.c | 21 |
1 files changed, 12 insertions, 9 deletions
diff --git a/kernel/power/process.c b/kernel/power/process.c index 99eeb119b06d..6d566bf7085c 100644 --- a/kernel/power/process.c +++ b/kernel/power/process.c | |||
@@ -28,8 +28,7 @@ static inline int freezeable(struct task_struct * p) | |||
28 | if ((p == current) || | 28 | if ((p == current) || |
29 | (p->flags & PF_NOFREEZE) || | 29 | (p->flags & PF_NOFREEZE) || |
30 | (p->exit_state == EXIT_ZOMBIE) || | 30 | (p->exit_state == EXIT_ZOMBIE) || |
31 | (p->exit_state == EXIT_DEAD) || | 31 | (p->exit_state == EXIT_DEAD)) |
32 | (p->state == TASK_STOPPED)) | ||
33 | return 0; | 32 | return 0; |
34 | return 1; | 33 | return 1; |
35 | } | 34 | } |
@@ -61,10 +60,16 @@ static inline void freeze_process(struct task_struct *p) | |||
61 | unsigned long flags; | 60 | unsigned long flags; |
62 | 61 | ||
63 | if (!freezing(p)) { | 62 | if (!freezing(p)) { |
64 | freeze(p); | 63 | rmb(); |
65 | spin_lock_irqsave(&p->sighand->siglock, flags); | 64 | if (!frozen(p)) { |
66 | signal_wake_up(p, 0); | 65 | if (p->state == TASK_STOPPED) |
67 | spin_unlock_irqrestore(&p->sighand->siglock, flags); | 66 | force_sig_specific(SIGSTOP, p); |
67 | |||
68 | freeze(p); | ||
69 | spin_lock_irqsave(&p->sighand->siglock, flags); | ||
70 | signal_wake_up(p, p->state == TASK_STOPPED); | ||
71 | spin_unlock_irqrestore(&p->sighand->siglock, flags); | ||
72 | } | ||
68 | } | 73 | } |
69 | } | 74 | } |
70 | 75 | ||
@@ -103,9 +108,7 @@ static unsigned int try_to_freeze_tasks(int freeze_user_space) | |||
103 | if (frozen(p)) | 108 | if (frozen(p)) |
104 | continue; | 109 | continue; |
105 | 110 | ||
106 | if (p->state == TASK_TRACED && | 111 | if (p->state == TASK_TRACED && frozen(p->parent)) { |
107 | (frozen(p->parent) || | ||
108 | p->parent->state == TASK_STOPPED)) { | ||
109 | cancel_freezing(p); | 112 | cancel_freezing(p); |
110 | continue; | 113 | continue; |
111 | } | 114 | } |