Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 280369
b: refs/heads/master
c: 0c9af09
h: refs/heads/master
i:
  280367: e956e13
v: v3
  • Loading branch information
Tejun Heo committed Nov 21, 2011
1 parent 3f3d67e commit fce6bd1
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 50 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 6cd8dedcdd8e8de01391a7cf25f0b2afeb24f8f4
refs/heads/master: 0c9af09262864a2744091ee94c98c4a8fd60c98b
84 changes: 37 additions & 47 deletions trunk/kernel/freezer.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,8 @@
#include <linux/freezer.h>
#include <linux/kthread.h>

/*
* freezing is complete, mark current process as frozen
*/
static inline void frozen_process(void)
{
if (!unlikely(current->flags & PF_NOFREEZE)) {
current->flags |= PF_FROZEN;
smp_wmb();
}
clear_freeze_flag(current);
}
/* protects freezing and frozen transitions */
static DEFINE_SPINLOCK(freezer_lock);

/* Refrigerator is place where frozen processes are stored :-). */
bool __refrigerator(bool check_kthr_stop)
Expand All @@ -31,14 +22,16 @@ bool __refrigerator(bool check_kthr_stop)
bool was_frozen = false;
long save;

task_lock(current);
if (freezing(current)) {
frozen_process();
task_unlock(current);
} else {
task_unlock(current);
spin_lock_irq(&freezer_lock);
if (!freezing(current)) {
spin_unlock_irq(&freezer_lock);
return was_frozen;
}
if (!(current->flags & PF_NOFREEZE))
current->flags |= PF_FROZEN;
clear_freeze_flag(current);
spin_unlock_irq(&freezer_lock);

save = current->state;
pr_debug("%s entered refrigerator\n", current->comm);

Expand Down Expand Up @@ -99,21 +92,18 @@ static void fake_signal_wake_up(struct task_struct *p)
*/
bool freeze_task(struct task_struct *p, bool sig_only)
{
/*
* We first check if the task is freezing and next if it has already
* been frozen to avoid the race with frozen_process() which first marks
* the task as frozen and next clears its TIF_FREEZE.
*/
if (!freezing(p)) {
smp_rmb();
if (frozen(p))
return false;

if (!sig_only || should_send_signal(p))
set_freeze_flag(p);
else
return false;
}
unsigned long flags;
bool ret = false;

spin_lock_irqsave(&freezer_lock, flags);

if (sig_only && !should_send_signal(p))
goto out_unlock;

if (frozen(p))
goto out_unlock;

set_freeze_flag(p);

if (should_send_signal(p)) {
fake_signal_wake_up(p);
Expand All @@ -123,26 +113,28 @@ bool freeze_task(struct task_struct *p, bool sig_only)
* TASK_RUNNING transition can't race with task state
* testing in try_to_freeze_tasks().
*/
} else if (sig_only) {
return false;
} else {
wake_up_state(p, TASK_INTERRUPTIBLE);
}

return true;
ret = true;
out_unlock:
spin_unlock_irqrestore(&freezer_lock, flags);
return ret;
}

void cancel_freezing(struct task_struct *p)
{
unsigned long flags;

spin_lock_irqsave(&freezer_lock, flags);
if (freezing(p)) {
pr_debug(" clean up: %s\n", p->comm);
clear_freeze_flag(p);
spin_lock_irqsave(&p->sighand->siglock, flags);
spin_lock(&p->sighand->siglock);
recalc_sigpending_and_wake(p);
spin_unlock_irqrestore(&p->sighand->siglock, flags);
spin_unlock(&p->sighand->siglock);
}
spin_unlock_irqrestore(&freezer_lock, flags);
}

/*
Expand All @@ -156,16 +148,14 @@ void cancel_freezing(struct task_struct *p)
*/
void __thaw_task(struct task_struct *p)
{
bool was_frozen;
unsigned long flags;

task_lock(p);
was_frozen = frozen(p);
if (was_frozen)
spin_lock_irqsave(&freezer_lock, flags);
if (frozen(p)) {
p->flags &= ~PF_FROZEN;
else
clear_freeze_flag(p);
task_unlock(p);

if (was_frozen)
wake_up_process(p);
} else {
clear_freeze_flag(p);
}
spin_unlock_irqrestore(&freezer_lock, flags);
}
2 changes: 0 additions & 2 deletions trunk/kernel/power/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,11 +118,9 @@ static int try_to_freeze_tasks(bool sig_only)

read_lock(&tasklist_lock);
do_each_thread(g, p) {
task_lock(p);
if (!wakeup && freezing(p) && !freezer_should_skip(p))
sched_show_task(p);
cancel_freezing(p);
task_unlock(p);
} while_each_thread(g, p);
read_unlock(&tasklist_lock);
} else {
Expand Down

0 comments on commit fce6bd1

Please sign in to comment.