On Tuesday, 5 December 2006 22:26, Rafael J. Wysocki wrote:
> On Tuesday, 5 December 2006 22:03, Rafael J. Wysocki wrote:
> > Okay, I have replaced my [1/2] with the patch below ...
> >
> > On Tuesday, 5 December 2006 11:34, Pavel Machek wrote:
<--snip-->
>
> Well, now the task that was stopped before the suspend doesn't go to the
> refrigerator when it's received the continuation signal after the resume.
> Good, but is it sufficient?
Well, almost.
Namely, if you suspend with a stopped vi and you look at the dmesg output
after the resume, there will be something like this:
Restarting tasks ... <4> Strange, vi not stopped
which means that thaw_tasks() is confused by the lurking stopped task. We can
fix that by checking if the task in question is not stopped before printing
the message in thaw_tasks() and we get this:
kernel/power/process.c | 21 ++++++++++++++++++---
kernel/signal.c | 4 +++-
2 files changed, 21 insertions(+), 4 deletions(-)
Index: linux-2.6.19-rc6-mm2/kernel/power/process.c
===================================================================
--- linux-2.6.19-rc6-mm2.orig/kernel/power/process.c 2006-12-05
21:10:00.000000000 +0100
+++ linux-2.6.19-rc6-mm2/kernel/power/process.c 2006-12-05 22:44:45.000000000
+0100
@@ -28,8 +28,7 @@ static inline int freezeable(struct task
if ((p == current) ||
(p->flags & PF_NOFREEZE) ||
(p->exit_state == EXIT_ZOMBIE) ||
- (p->exit_state == EXIT_DEAD) ||
- (p->state == TASK_STOPPED))
+ (p->exit_state == EXIT_DEAD))
return 0;
return 1;
}
@@ -103,6 +102,9 @@ static unsigned int try_to_freeze_tasks(
if (frozen(p))
continue;
+ if (p->state == TASK_STOPPED && freezing(p))
+ continue;
+
if (p->state == TASK_TRACED &&
(frozen(p->parent) ||
p->parent->state == TASK_STOPPED)) {
@@ -185,6 +187,18 @@ int freeze_processes(void)
return 0;
}
+static inline void release_stopped_tasks(void)
+{
+ struct task_struct *g, *p;
+
+ read_lock(&tasklist_lock);
+ do_each_thread(g, p) {
+ if (p->state == TASK_STOPPED && freezing(p))
+ cancel_freezing(p);
+ } while_each_thread(g, p);
+ read_unlock(&tasklist_lock);
+}
+
static void thaw_tasks(int thaw_user_space)
{
struct task_struct *g, *p;
@@ -197,7 +211,7 @@ static void thaw_tasks(int thaw_user_spa
if (is_user_space(p) == !thaw_user_space)
continue;
- if (!thaw_process(p))
+ if (!thaw_process(p) && p->state != TASK_STOPPED)
printk(KERN_WARNING " Strange, %s not stopped\n",
p->comm );
} while_each_thread(g, p);
@@ -207,6 +221,7 @@ static void thaw_tasks(int thaw_user_spa
void thaw_processes(void)
{
printk("Restarting tasks ... ");
+ release_stopped_tasks();
thaw_tasks(FREEZER_KERNEL_THREADS);
thaw_tasks(FREEZER_USER_SPACE);
schedule();
Index: linux-2.6.19-rc6-mm2/kernel/signal.c
===================================================================
--- linux-2.6.19-rc6-mm2.orig/kernel/signal.c 2006-12-05 21:10:00.000000000
+0100
+++ linux-2.6.19-rc6-mm2/kernel/signal.c 2006-12-05 21:11:31.000000000
+0100
@@ -1829,7 +1829,9 @@ finish_stop(int stop_count)
read_unlock(&tasklist_lock);
}
- schedule();
+ do {
+ schedule();
+ } while (try_to_freeze());
/*
* Now we don't run again until continued.
*/
But now it looks almost like my [1/2], doesn't it? ;-)
Greetings,
Rafael
--
If you don't have the time to read,
you don't have the time or the tools to write.
- Stephen King
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Suspend-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/suspend-devel