Skip to content

Commit

Permalink
[PATCH] swsusp: thaw userspace and kernel space separately
Browse files Browse the repository at this point in the history
Modify process thawing so that we can thaw kernel space without thawing
userspace, and thaw kernelspace first.  This will be useful in later
patches, where I intend to get swsusp thawing kernel threads only before
seeking to free memory.

Signed-off-by: Nigel Cunningham <nigel@suspend2.net>
Cc: Pavel Machek <pavel@ucw.cz>
Cc: "Rafael J. Wysocki" <rjw@sisk.pl>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
  • Loading branch information
Nigel Cunningham authored and Linus Torvalds committed Dec 7, 2006
1 parent 14b5b7c commit ff39593
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 8 deletions.
9 changes: 8 additions & 1 deletion include/linux/freezer.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
/* Freezer declarations */

#define FREEZER_KERNEL_THREADS 0
#define FREEZER_ALL_THREADS 1

#ifdef CONFIG_PM
/*
* Check if a process has been frozen
Expand Down Expand Up @@ -57,7 +60,8 @@ static inline void frozen_process(struct task_struct *p)

extern void refrigerator(void);
extern int freeze_processes(void);
extern void thaw_processes(void);
#define thaw_processes() do { thaw_some_processes(FREEZER_ALL_THREADS); } while(0)
#define thaw_kernel_threads() do { thaw_some_processes(FREEZER_KERNEL_THREADS); } while(0)

static inline int try_to_freeze(void)
{
Expand All @@ -67,6 +71,9 @@ static inline int try_to_freeze(void)
} else
return 0;
}

extern void thaw_some_processes(int all);

#else
static inline int frozen(struct task_struct *p) { return 0; }
static inline int freezing(struct task_struct *p) { return 0; }
Expand Down
25 changes: 18 additions & 7 deletions kernel/power/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,18 +153,29 @@ int freeze_processes(void)
return 0;
}

void thaw_processes(void)
void thaw_some_processes(int all)
{
struct task_struct *g, *p;
int pass = 0; /* Pass 0 = Kernel space, 1 = Userspace */

printk("Restarting tasks... ");
read_lock(&tasklist_lock);
do_each_thread(g, p) {
if (!freezeable(p))
continue;
if (!thaw_process(p))
printk(KERN_INFO "Strange, %s not stopped\n", p->comm);
} while_each_thread(g, p);
do {
do_each_thread(g, p) {
/*
* is_user = 0 if kernel thread or borrowed mm,
* 1 otherwise.
*/
int is_user = !!(p->mm && !(p->flags & PF_BORROWED_MM));
if (!freezeable(p) || (is_user != pass))
continue;
if (!thaw_process(p))
printk(KERN_INFO
"Strange, %s not stopped\n", p->comm);
} while_each_thread(g, p);

pass++;
} while (pass < 2 && all);

read_unlock(&tasklist_lock);
schedule();
Expand Down

0 comments on commit ff39593

Please sign in to comment.