Re: [RFC] Fix SMP brokenness for PF_FREEZE and make freezing usable for other purposes

Pavel Machek
2005-06-28T12:47:50Z

Hi!

> <<<< look at error path in freeze_processes (on timeout), it is broken
> as well. You need to wakeup tasks there...
>

Yep, and I have this in my tree to fix it:

[word-wrap-warning]

--- a/kernel/power/process.c
+++ b/kernel/power/process.c
@@ -60,6 +60,7 @@ int freeze_processes(void)
int todo;
unsigned long start_time;
struct task_struct *g, *p;
+ unsigned long flags;

printk( "Stopping tasks: " );
start_time = jiffies;
@@ -67,12 +68,9 @@ int freeze_processes(void)
todo = 0;
read_lock(&tasklist_lock);
do_each_thread(g, p) {
- unsigned long flags;
if (!freezeable(p))
continue;
- if ((p->flags & PF_FROZEN) ||
- (p->state == TASK_TRACED) ||
- (p->state == TASK_STOPPED))
+ if (p->flags & PF_FROZEN)
continue;

/* FIXME: smp problem here: we may not access other process' flags
@@ -85,13 +83,28 @@ int freeze_processes(void)
} while_each_thread(g, p);
read_unlock(&tasklist_lock);
yield(); /* Yield is okay here */
- if (time_after(jiffies, start_time + TIMEOUT)) {
+ if (todo && time_after(jiffies, start_time + TIMEOUT)) {
printk( "\n" );
printk(KERN_ERR " stopping tasks failed (%d tasks remaining)\n", todo );
- return todo;
+ break;
}
} while(todo);
-
+
+ if (todo) {
+ read_lock(&tasklist_lock);
+ do_each_thread(g, p)
+ if (p->flags & PF_FREEZE) {
+ pr_debug(" clean up: %s\n", p->comm);
+ p->flags &= ~PF_FREEZE;
+ spin_lock_irqsave(&p->sighand->siglock, flags);
+ recalc_sigpending_tsk(p);
+ spin_unlock_irqrestore(&p->sighand->siglock, flags);
+ }
+ while_each_thread(g, p);
+ read_unlock(&tasklist_lock);
+ return todo;
+ }
+
printk( "|\n" );
BUG_ON(in_atomic());
return 0;

Pavel

--
Boycott Kodak -- for their patent abuse against Java.