diff options
Diffstat (limited to 'kernel/freezer.c')
| -rw-r--r-- | kernel/freezer.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/kernel/freezer.c b/kernel/freezer.c index c38893b0efba..b462fa197517 100644 --- a/kernel/freezer.c +++ b/kernel/freezer.c | |||
| @@ -33,7 +33,7 @@ static DEFINE_SPINLOCK(freezer_lock); | |||
| 33 | */ | 33 | */ |
| 34 | bool freezing_slow_path(struct task_struct *p) | 34 | bool freezing_slow_path(struct task_struct *p) |
| 35 | { | 35 | { |
| 36 | if (p->flags & PF_NOFREEZE) | 36 | if (p->flags & (PF_NOFREEZE | PF_SUSPEND_TASK)) |
| 37 | return false; | 37 | return false; |
| 38 | 38 | ||
| 39 | if (pm_nosig_freezing || cgroup_freezing(p)) | 39 | if (pm_nosig_freezing || cgroup_freezing(p)) |
| @@ -110,6 +110,18 @@ bool freeze_task(struct task_struct *p) | |||
| 110 | { | 110 | { |
| 111 | unsigned long flags; | 111 | unsigned long flags; |
| 112 | 112 | ||
| 113 | /* | ||
| 114 | * This check can race with freezer_do_not_count, but worst case that | ||
| 115 | * will result in an extra wakeup being sent to the task. It does not | ||
| 116 | * race with freezer_count(), the barriers in freezer_count() and | ||
| 117 | * freezer_should_skip() ensure that either freezer_count() sees | ||
| 118 | * freezing == true in try_to_freeze() and freezes, or | ||
| 119 | * freezer_should_skip() sees !PF_FREEZE_SKIP and freezes the task | ||
| 120 | * normally. | ||
| 121 | */ | ||
| 122 | if (freezer_should_skip(p)) | ||
| 123 | return false; | ||
| 124 | |||
| 113 | spin_lock_irqsave(&freezer_lock, flags); | 125 | spin_lock_irqsave(&freezer_lock, flags); |
| 114 | if (!freezing(p) || frozen(p)) { | 126 | if (!freezing(p) || frozen(p)) { |
| 115 | spin_unlock_irqrestore(&freezer_lock, flags); | 127 | spin_unlock_irqrestore(&freezer_lock, flags); |
