From ff39593ad0ff7a79a3717edac6634407aa8200c2 Mon Sep 17 00:00:00 2001 From: Nigel Cunningham Date: Wed, 6 Dec 2006 20:34:28 -0800 Subject: [PATCH] [PATCH] swsusp: thaw userspace and kernel space separately 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 Cc: Pavel Machek Cc: "Rafael J. Wysocki" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/freezer.h | 9 ++++++++- kernel/power/process.c | 25 ++++++++++++++++++------- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/include/linux/freezer.h b/include/linux/freezer.h index 266373f74445..294ebea859c9 100644 --- a/include/linux/freezer.h +++ b/include/linux/freezer.h @@ -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 @@ -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) { @@ -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; } diff --git a/kernel/power/process.c b/kernel/power/process.c index fedabad5a180..cba8a5890eda 100644 --- a/kernel/power/process.c +++ b/kernel/power/process.c @@ -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();