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, _______________________________________________ linux-pm mailing list linux-pm@xxxxxxxxxxxxxxxxxxxxxxxxxx https://lists.linux-foundation.org/mailman/listinfo/linux-pm