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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux