Re: [PATCH 3/8] PM: suspend_block: Abort task freezing if a suspend_blocker is active.

Rafael J. Wysocki
2009-04-29T22:56:42Z

On Wednesday 15 April 2009, Arve Hjønnevåg wrote:
> If a suspend_blocker is active, suspend will fail anyway. Since
> try_to_freeze_tasks can take up to 20 seconds to complete or fail, aborting
> as soon as someone blocks suspend (e.g. from an interrupt handler) improves
> the worst case wakeup latency.
>
> On an older kernel where task freezing could fail for processes attached
> to a debugger, this fixed a problem where the device sometimes hung for
> 20 seconds before the screen turned on.
>
> Signed-off-by: Arve Hjønnevåg <arve@android.com>
> ---
> kernel/power/process.c | 23 ++++++++++++++++++-----
> 1 files changed, 18 insertions(+), 5 deletions(-)
>
> diff --git a/kernel/power/process.c b/kernel/power/process.c
> index ca63401..76d7cdb 100644
> --- a/kernel/power/process.c
> +++ b/kernel/power/process.c
> @@ -13,6 +13,7 @@
> #include <linux/module.h>
> #include <linux/syscalls.h>
> #include <linux/freezer.h>
> +#include <linux/suspend_block.h>
>
> /*
> * Timeout for stopping processes
> @@ -36,6 +37,7 @@ static int try_to_freeze_tasks(bool sig_only)
> struct timeval start, end;
> u64 elapsed_csecs64;
> unsigned int elapsed_csecs;
> + unsigned int wakeup = 0;

Make it a bool, please.

> do_gettimeofday(&start);
>
> @@ -62,6 +64,10 @@ static int try_to_freeze_tasks(bool sig_only)
> } while_each_thread(g, p);
> read_unlock(&tasklist_lock);
> yield(); /* Yield is okay here */
> + if (todo && suspend_is_blocked()) {
> + wakeup = 1;

'true', please.

> + break;
> + }
> if (time_after(jiffies, end_time))
> break;
> } while (todo);
> @@ -77,11 +83,18 @@ static int try_to_freeze_tasks(bool sig_only)
> * and caller must call thaw_processes() if something fails),
> * but it cleans up leftover PF_FREEZE requests.
> */
> - printk("\n");
> - printk(KERN_ERR "Freezing of tasks failed after %d.%02d seconds "
> - "(%d tasks refusing to freeze):\n",
> - elapsed_csecs / 100, elapsed_csecs % 100, todo);
> - show_state();
> + if (wakeup) {
> + printk("\n");

Why is the separate printk() necessary ?

> + printk(KERN_ERR "Freezing of %s aborted\n",
> + sig_only ? "user space " : "tasks ");
> + } else {
> + printk("\n");

Why is the separate printk() necessary ?

> + printk(KERN_ERR
> + "Freezing of tasks failed after %d.%02d seconds "
> + "(%d tasks refusing to freeze):\n",
> + elapsed_csecs / 100, elapsed_csecs % 100, todo);
> + show_state();
> + }
> read_lock(&tasklist_lock);
> do_each_thread(g, p) {
> task_lock(p);

--
Everyone knows that debugging is twice as hard as writing a program
in the first place. So if you're as clever as you can be when you write it,
how will you ever debug it? --- Brian Kernighan
_______________________________________________
linux-pm mailing list
linux-pm@lists.linux-foundation.org