Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 56863
b: refs/heads/master
c: ba96a0c
h: refs/heads/master
i:
  56861: b0d1450
  56859: e18ca26
  56855: 6ae7e73
  56847: e933072
  56831: d641ca0
v: v3
  • Loading branch information
Rafael J. Wysocki authored and Linus Torvalds committed May 24, 2007
1 parent 2208b4a commit 7ac0d8f
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 23 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: 33e1c288da62a6a5aa9077a6b7bfa690b1b02cf4
refs/heads/master: ba96a0c88098697a63e80157718b7440414ed24d
48 changes: 46 additions & 2 deletions trunk/include/linux/freezer.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,49 @@ static inline int try_to_freeze(void)
return 0;
}

extern void thaw_some_processes(int all);
/*
* The PF_FREEZER_SKIP flag should be set by a vfork parent right before it
* calls wait_for_completion(&vfork) and reset right after it returns from this
* function. Next, the parent should call try_to_freeze() to freeze itself
* appropriately in case the child has exited before the freezing of tasks is
* complete. However, we don't want kernel threads to be frozen in unexpected
* places, so we allow them to block freeze_processes() instead or to set
* PF_NOFREEZE if needed and PF_FREEZER_SKIP is only set for userland vfork
* parents. Fortunately, in the ____call_usermodehelper() case the parent won't
* really block freeze_processes(), since ____call_usermodehelper() (the child)
* does a little before exec/exit and it can't be frozen before waking up the
* parent.
*/

/*
* If the current task is a user space one, tell the freezer not to count it as
* freezable.
*/
static inline void freezer_do_not_count(void)
{
if (current->mm)
current->flags |= PF_FREEZER_SKIP;
}

/*
* If the current task is a user space one, tell the freezer to count it as
* freezable again and try to freeze it.
*/
static inline void freezer_count(void)
{
if (current->mm) {
current->flags &= ~PF_FREEZER_SKIP;
try_to_freeze();
}
}

/*
* Check if the task should be counted as freezeable by the freezer
*/
static inline int freezer_should_skip(struct task_struct *p)
{
return !!(p->flags & PF_FREEZER_SKIP);
}

#else
static inline int frozen(struct task_struct *p) { return 0; }
Expand All @@ -96,5 +138,7 @@ static inline void thaw_processes(void) {}

static inline int try_to_freeze(void) { return 0; }


static inline void freezer_do_not_count(void) {}
static inline void freezer_count(void) {}
static inline int freezer_should_skip(struct task_struct *p) { return 0; }
#endif
1 change: 1 addition & 0 deletions trunk/include/linux/sched.h
Original file line number Diff line number Diff line change
Expand Up @@ -1182,6 +1182,7 @@ static inline void put_task_struct(struct task_struct *t)
#define PF_SPREAD_SLAB 0x02000000 /* Spread some slab caches over cpuset */
#define PF_MEMPOLICY 0x10000000 /* Non-default NUMA mempolicy */
#define PF_MUTEX_TESTER 0x20000000 /* Thread belongs to the rt mutex tester */
#define PF_FREEZER_SKIP 0x40000000 /* Freezer should not count it as freezeable */

/*
* Only the _current_ task can read/write to tsk->flags, but other
Expand Down
3 changes: 3 additions & 0 deletions trunk/kernel/fork.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
#include <linux/acct.h>
#include <linux/tsacct_kern.h>
#include <linux/cn_proc.h>
#include <linux/freezer.h>
#include <linux/delayacct.h>
#include <linux/taskstats_kern.h>
#include <linux/random.h>
Expand Down Expand Up @@ -1405,7 +1406,9 @@ long do_fork(unsigned long clone_flags,
}

if (clone_flags & CLONE_VFORK) {
freezer_do_not_count();
wait_for_completion(&vfork);
freezer_count();
if (unlikely (current->ptrace & PT_TRACE_VFORK_DONE)) {
current->ptrace_message = nr;
ptrace_notify ((PTRACE_EVENT_VFORK_DONE << 8) | SIGTRAP);
Expand Down
29 changes: 9 additions & 20 deletions trunk/kernel/power/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,22 +120,12 @@ static unsigned int try_to_freeze_tasks(int freeze_user_space)
cancel_freezing(p);
continue;
}
if (is_user_space(p)) {
if (!freeze_user_space)
continue;

/* Freeze the task unless there is a vfork
* completion pending
*/
if (!p->vfork_done)
freeze_process(p);
} else {
if (freeze_user_space)
continue;

freeze_process(p);
}
todo++;
if (is_user_space(p) == !freeze_user_space)
continue;

freeze_process(p);
if (!freezer_should_skip(p))
todo++;
} while_each_thread(g, p);
read_unlock(&tasklist_lock);
yield(); /* Yield is okay here */
Expand All @@ -161,7 +151,8 @@ static unsigned int try_to_freeze_tasks(int freeze_user_space)
continue;

task_lock(p);
if (freezeable(p) && !frozen(p))
if (freezeable(p) && !frozen(p) &&
!freezer_should_skip(p))
printk(KERN_ERR " %s\n", p->comm);

cancel_freezing(p);
Expand Down Expand Up @@ -210,9 +201,7 @@ static void thaw_tasks(int thaw_user_space)
if (is_user_space(p) == !thaw_user_space)
continue;

if (!thaw_process(p))
printk(KERN_WARNING " Strange, %s not stopped\n",
p->comm );
thaw_process(p);
} while_each_thread(g, p);
read_unlock(&tasklist_lock);
}
Expand Down

0 comments on commit 7ac0d8f

Please sign in to comment.