From 6b3453880600279a9eac00f48f3b7dee16ecaf10 Mon Sep 17 00:00:00 2001 From: Nigel Cunningham Date: Wed, 6 Dec 2006 20:34:28 -0800 Subject: [PATCH] --- yaml --- r: 42722 b: refs/heads/master c: ff39593ad0ff7a79a3717edac6634407aa8200c2 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/include/linux/freezer.h | 9 ++++++++- trunk/kernel/power/process.c | 25 ++++++++++++++++++------- 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/[refs] b/[refs] index b3a1068249e1..b327b79aeee4 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 14b5b7cfaa110b1d25b8f80b01a8c97cf2db30bc +refs/heads/master: ff39593ad0ff7a79a3717edac6634407aa8200c2 diff --git a/trunk/include/linux/freezer.h b/trunk/include/linux/freezer.h index 266373f74445..294ebea859c9 100644 --- a/trunk/include/linux/freezer.h +++ b/trunk/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/trunk/kernel/power/process.c b/trunk/kernel/power/process.c index fedabad5a180..cba8a5890eda 100644 --- a/trunk/kernel/power/process.c +++ b/trunk/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();