aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/power
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/power')
-rw-r--r--kernel/power/Kconfig6
-rw-r--r--kernel/power/process.c26
2 files changed, 23 insertions, 9 deletions
diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
index ae44a70aae8a..619ecabf7c58 100644
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -56,7 +56,7 @@ config PM_TRACE
56 56
57config SOFTWARE_SUSPEND 57config SOFTWARE_SUSPEND
58 bool "Software Suspend" 58 bool "Software Suspend"
59 depends on PM && SWAP && (X86 && (!SMP || SUSPEND_SMP)) || ((FRV || PPC32) && !SMP) 59 depends on PM && SWAP && ((X86 && (!SMP || SUSPEND_SMP) && !X86_PAE) || ((FRV || PPC32) && !SMP))
60 ---help--- 60 ---help---
61 Enable the possibility of suspending the machine. 61 Enable the possibility of suspending the machine.
62 It doesn't need ACPI or APM. 62 It doesn't need ACPI or APM.
@@ -78,6 +78,10 @@ config SOFTWARE_SUSPEND
78 78
79 For more information take a look at <file:Documentation/power/swsusp.txt>. 79 For more information take a look at <file:Documentation/power/swsusp.txt>.
80 80
81 (For now, swsusp is incompatible with PAE aka HIGHMEM_64G on i386.
82 we need identity mapping for resume to work, and that is trivial
83 to get with 4MB pages, but less than trivial on PAE).
84
81config PM_STD_PARTITION 85config PM_STD_PARTITION
82 string "Default resume partition" 86 string "Default resume partition"
83 depends on SOFTWARE_SUSPEND 87 depends on SOFTWARE_SUSPEND
diff --git a/kernel/power/process.c b/kernel/power/process.c
index b2a5f671d6cd..72e72d2c61e6 100644
--- a/kernel/power/process.c
+++ b/kernel/power/process.c
@@ -66,13 +66,25 @@ static inline void freeze_process(struct task_struct *p)
66 } 66 }
67} 67}
68 68
69static void cancel_freezing(struct task_struct *p)
70{
71 unsigned long flags;
72
73 if (freezing(p)) {
74 pr_debug(" clean up: %s\n", p->comm);
75 do_not_freeze(p);
76 spin_lock_irqsave(&p->sighand->siglock, flags);
77 recalc_sigpending_tsk(p);
78 spin_unlock_irqrestore(&p->sighand->siglock, flags);
79 }
80}
81
69/* 0 = success, else # of processes that we failed to stop */ 82/* 0 = success, else # of processes that we failed to stop */
70int freeze_processes(void) 83int freeze_processes(void)
71{ 84{
72 int todo, nr_user, user_frozen; 85 int todo, nr_user, user_frozen;
73 unsigned long start_time; 86 unsigned long start_time;
74 struct task_struct *g, *p; 87 struct task_struct *g, *p;
75 unsigned long flags;
76 88
77 printk( "Stopping tasks: " ); 89 printk( "Stopping tasks: " );
78 start_time = jiffies; 90 start_time = jiffies;
@@ -85,6 +97,10 @@ int freeze_processes(void)
85 continue; 97 continue;
86 if (frozen(p)) 98 if (frozen(p))
87 continue; 99 continue;
100 if (p->state == TASK_TRACED && frozen(p->parent)) {
101 cancel_freezing(p);
102 continue;
103 }
88 if (p->mm && !(p->flags & PF_BORROWED_MM)) { 104 if (p->mm && !(p->flags & PF_BORROWED_MM)) {
89 /* The task is a user-space one. 105 /* The task is a user-space one.
90 * Freeze it unless there's a vfork completion 106 * Freeze it unless there's a vfork completion
@@ -126,13 +142,7 @@ int freeze_processes(void)
126 do_each_thread(g, p) { 142 do_each_thread(g, p) {
127 if (freezeable(p) && !frozen(p)) 143 if (freezeable(p) && !frozen(p))
128 printk(KERN_ERR " %s\n", p->comm); 144 printk(KERN_ERR " %s\n", p->comm);
129 if (freezing(p)) { 145 cancel_freezing(p);
130 pr_debug(" clean up: %s\n", p->comm);
131 p->flags &= ~PF_FREEZE;
132 spin_lock_irqsave(&p->sighand->siglock, flags);
133 recalc_sigpending_tsk(p);
134 spin_unlock_irqrestore(&p->sighand->siglock, flags);
135 }
136 } while_each_thread(g, p); 146 } while_each_thread(g, p);
137 read_unlock(&tasklist_lock); 147 read_unlock(&tasklist_lock);
138 return todo; 148 return todo;