On Wednesday, 1 August 2007 11:22, Pavel Machek wrote:
> Hi!
> 
> > > Hmm, wonder why this isn't affecting people with VPNs?  Probably
> > > network mounts over VPN are rare, and ever rarer to have fs activity
> > > on them during suspend.
> > > 
> > > Anyway, I think it's long overdue to stop thinking about how to "fix"
> > > fuse, and concentrate on fixing the underlying problem instead ;)
> > 
> > To conclude this branch of the thread, I have a patch in the works that may
> > help a bit with unfreezable FUSE filesystems and it only affects the 
> > freezer.
> > I'll post it when 2.6.23-rc1 is out, because it's on top of some other 
> > patches
> > that need to go first.
> 
> I'm interested... which one is that?

Appended, on top of this:
https://lists.linux-foundation.org/pipermail/linux-pm/2007-July/014521.html

Greetings,
Rafael


---
 kernel/power/process.c |   49 ++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 48 insertions(+), 1 deletion(-)

Index: linux-2.6.23-rc1/kernel/power/process.c
===================================================================
--- linux-2.6.23-rc1.orig/kernel/power/process.c        2007-07-24 
00:14:07.000000000 +0200
+++ linux-2.6.23-rc1/kernel/power/process.c     2007-07-24 00:14:17.000000000 
+0200
@@ -30,6 +30,14 @@
  */
 #define MAX_WAITS 5
 
+/*
+ * If the freezing of tasks fails, we attempt to thaw tasks that have already
+ * been frozen to give a chance the other tasks to freeze, in case one or more
+ * of them are blocked by the frozen ones.  If this fails MAX_ATTEMPTS times
+ * in a row, we give up.
+ */
+#define MAX_ATTEMPTS 10
+
 #define FREEZER_KERNEL_THREADS 0
 #define FREEZER_USER_SPACE 1
 
@@ -192,14 +200,21 @@ static void cancel_freezing(struct task_
 static int try_to_freeze_tasks(int freeze_user_space)
 {
        struct task_struct *g, *p;
-       unsigned int todo, waits;
+       unsigned int todo, waits, attempts;
        unsigned long ret;
        struct timeval start, end;
        s64 elapsed_csecs64;
        unsigned int elapsed_csecs;
+       char *tick = "-\\|/";
+
+       printk(" ");
+       attempts = 0;
 
        do_gettimeofday(&start);
 
+ Repeat:
+       printk("\b%c", tick[attempts++ % 4]);
+
        refrigerator_called = 0;
        waits = 0;
        do {
@@ -235,11 +250,43 @@ static int try_to_freeze_tasks(int freez
                }
        } while (todo);
 
+       if (todo && attempts <= MAX_ATTEMPTS) {
+               /*
+                * Some tasks have not been able to freeze.  They might be stuck
+                * in TASK_UNINTERRUPTIBLE waiting for the frozen tasks.  Try to
+                * thaw the tasks that have frozen without clearing the freeze
+                * requests of the remaining tasks and repeat.
+                */
+               read_lock(&tasklist_lock);
+               do_each_thread(g, p) {
+                       if (frozen(p)) {
+                               p->flags &= ~PF_FROZEN;
+                               wake_up_process(p);
+                       }
+               } while_each_thread(g, p);
+               read_unlock(&tasklist_lock);
+
+               ret = wait_event_timeout(refrigerator_waitq,
+                                               refrigerator_called, TIMEOUT);
+               if (!ret) {
+                       /*
+                        * There is a little hope that we will succeed, but at
+                        * least we want to know which tasks have not been
+                        * frozen.  Thus, we are going to repeat once.
+                        */
+                       attempts = MAX_ATTEMPTS;
+               }
+
+               goto Repeat;
+       }
+
        do_gettimeofday(&end);
        elapsed_csecs64 = timeval_to_ns(&end) - timeval_to_ns(&start);
        do_div(elapsed_csecs64, NSEC_PER_SEC / 100);
        elapsed_csecs = elapsed_csecs64;
 
+       printk("\b");
+
        if (todo) {
                /* This does not unfreeze processes that are already frozen
                 * (we have slightly ugly calling convention in that respect,
-
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/

Reply via email to