From: "Rafael J. Wysocki" <rjw@sisk.pl>
To: Alan Stern <stern@rowland.harvard.edu>
Cc: Linux-pm mailing list <linux-pm@lists.linux-foundation.org>
Subject: Re: [RFC] Add the "icebox"
Date: Wed, 7 Nov 2007 23:31:54 +0100 [thread overview]
Message-ID: <200711072331.54708.rjw@sisk.pl> (raw)
In-Reply-To: <Pine.LNX.4.44L0.0711071210570.6349-100000@iolanthe.rowland.org>
On Wednesday, 7 of November 2007, Alan Stern wrote:
> On Mon, 5 Nov 2007, Rafael J. Wysocki wrote:
>
> > I like the idea, but I think that start_icebox() should be called after
> > freeze_processes(). Similarly, IMO it's better to call stop_icebox() before
> > thaw_processes().
>
> Okay. On the assumption that freezable kernel threads will continue to
> use the freezer and won't try to use the icebox, I have updated the
> patch. Other comments?
OK by me.
> Alan Stern
>
> P.S.: What about mutual exclusion in kernel/power/user.c? If we stop
> freezing user tasks, there's nothing to prevent more than one task
> holding an open file reference to the snapshot file and submitting
> ioctls concurrently. Maybe the regions covered by pm_mutex should be
> expanded.
/dev/snapshot can only be open once at a time.
Greetings,
Rafael
> Index: usb-2.6/include/linux/freezer.h
> ===================================================================
> --- usb-2.6.orig/include/linux/freezer.h
> +++ usb-2.6/include/linux/freezer.h
> @@ -157,6 +157,12 @@ static inline void set_freezable(void)
> } while (try_to_freeze()); \
> __retval; \
> })
> +
> +/*
> + * Kernel threads that want to freeze themselves go into the icebox.
> + */
> +extern void icebox(void);
> +
> #else /* !CONFIG_PM_SLEEP */
> static inline int frozen(struct task_struct *p) { return 0; }
> static inline int freezing(struct task_struct *p) { return 0; }
> @@ -181,6 +187,7 @@ static inline void set_freezable(void) {
> #define wait_event_freezable_timeout(wq, condition, timeout) \
> wait_event_interruptible_timeout(wq, condition, timeout)
>
> +static inline void icebox(void) {}
> #endif /* !CONFIG_PM_SLEEP */
>
> #endif /* FREEZER_H_INCLUDED */
> Index: usb-2.6/kernel/power/power.h
> ===================================================================
> --- usb-2.6.orig/kernel/power/power.h
> +++ usb-2.6/kernel/power/power.h
> @@ -207,3 +207,9 @@ static inline int suspend_devices_and_en
> /* kernel/power/main.c */
> extern int pm_notifier_call_chain(unsigned long val);
> #endif
> +
> +#ifdef CONFIG_PM_SLEEP
> +/* kerne/power/process.c */
> +extern void start_icebox(void);
> +extern void stop_icebox(void);
> +#endif
> Index: usb-2.6/kernel/power/main.c
> ===================================================================
> --- usb-2.6.orig/kernel/power/main.c
> +++ usb-2.6/kernel/power/main.c
> @@ -108,6 +108,8 @@ static int suspend_prepare(void)
> goto Thaw;
> }
>
> + start_icebox();
> +
> free_pages = global_page_state(NR_FREE_PAGES);
> if (free_pages < FREE_PAGE_NUMBER) {
> pr_debug("PM: free some memory\n");
> @@ -120,6 +122,7 @@ static int suspend_prepare(void)
> if (!error)
> return 0;
>
> + stop_icebox();
> Thaw:
> thaw_processes();
> pm_restore_console();
> @@ -215,6 +218,7 @@ int suspend_devices_and_enter(suspend_st
> */
> static void suspend_finish(void)
> {
> + stop_icebox();
> thaw_processes();
> pm_restore_console();
> pm_notifier_call_chain(PM_POST_SUSPEND);
> Index: usb-2.6/kernel/power/disk.c
> ===================================================================
> --- usb-2.6.orig/kernel/power/disk.c
> +++ usb-2.6/kernel/power/disk.c
> @@ -406,6 +406,8 @@ int hibernate(void)
> if (error)
> goto Finish;
>
> + start_icebox();
> +
> if (hibernation_mode == HIBERNATION_TESTPROC) {
> printk("swsusp debug: Waiting for 5 seconds.\n");
> mdelay(5000);
> @@ -427,6 +429,7 @@ int hibernate(void)
> swsusp_free();
> }
> Thaw:
> + stop_icebox();
> unprepare_processes();
> Finish:
> free_basic_memory_bitmaps();
> @@ -504,6 +507,8 @@ static int software_resume(void)
> goto Done;
> }
>
> + start_icebox();
> +
> pr_debug("PM: Reading swsusp image.\n");
>
> error = swsusp_read(&flags);
> @@ -512,6 +517,7 @@ static int software_resume(void)
>
> printk(KERN_ERR "PM: Restore failed, recovering.\n");
> swsusp_free();
> + stop_icebox();
> unprepare_processes();
> Done:
> free_basic_memory_bitmaps();
> Index: usb-2.6/kernel/power/user.c
> ===================================================================
> --- usb-2.6.orig/kernel/power/user.c
> +++ usb-2.6/kernel/power/user.c
> @@ -172,13 +172,16 @@ static int snapshot_ioctl(struct inode *
> if (error)
> thaw_processes();
> mutex_unlock(&pm_mutex);
> - if (!error)
> + if (!error) {
> data->frozen = 1;
> + start_icebox();
> + }
> break;
>
> case SNAPSHOT_UNFREEZE:
> if (!data->frozen || data->ready)
> break;
> + stop_icebox();
> mutex_lock(&pm_mutex);
> thaw_processes();
> mutex_unlock(&pm_mutex);
> Index: usb-2.6/kernel/power/process.c
> ===================================================================
> --- usb-2.6.orig/kernel/power/process.c
> +++ usb-2.6/kernel/power/process.c
> @@ -14,6 +14,8 @@
> #include <linux/syscalls.h>
> #include <linux/freezer.h>
>
> +#include "power.h"
> +
> /*
> * Timeout for stopping processes
> */
> @@ -283,3 +285,52 @@ void thaw_processes(void)
> }
>
> EXPORT_SYMBOL(refrigerator);
> +
> +/*
> + * Routines for kernel threads that want to freeze themselves in the icebox
> + */
> +static DECLARE_WAIT_QUEUE_HEAD(icebox_wait_queue_head);
> +static int icebox_active;
> +
> +/**
> + * start_icebox -- activate the icebox
> + *
> + * Kernel power code should call this routine before sending the
> + * PM_HIBERNATION_PREPARE, PM_SUSPEND_PREPARE, or PM_RESTORE_PREPARE
> + * notifications.
> + */
> +void start_icebox(void)
> +{
> + icebox_active = 1;
> +}
> +
> +/**
> + * stop_icebox -- deactivate the icebox and awaken waiting threads
> + *
> + * Kernel power code should call this routine before sending the
> + * PM_POST_HIBERNATION, PM_POST_SUSPEND, or PM_POST_RESTORE notifications.
> + */
> +void stop_icebox(void)
> +{
> + icebox_active = 0;
> + wake_up_all(&icebox_wait_queue_head);
> +}
> +
> +/**
> + * icebox -- place for kernel threads to wait during suspend or hibernation
> + *
> + * Tasks can call this routine at any time. It will return immediately
> + * unless a system suspend or hibernation has started and the icebox is
> + * active, in which case it won't return until the suspend/hibernation
> + * is over.
> + *
> + * This routine should be used by drivers that want to delay user-initiated
> + * I/O until a system sleep is over. Kernel threads should not use it
> + * in place of the freezer, because the icebox doesn't get activated until
> + * after freezing is complete.
> + */
> +void icebox(void)
> +{
> + wait_event(icebox_wait_queue_head, !icebox_active);
> +}
> +EXPORT_SYMBOL_GPL(icebox);
>
next prev parent reply other threads:[~2007-11-07 22:31 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-11-05 21:27 [RFC] Add the "icebox" Alan Stern
2007-11-05 22:11 ` Rafael J. Wysocki
2007-11-06 15:08 ` Alan Stern
2007-11-07 17:16 ` Alan Stern
2007-11-07 22:31 ` Rafael J. Wysocki [this message]
2007-11-07 22:28 ` Alan Stern
2007-11-07 23:32 ` Rafael J. Wysocki
2007-11-07 8:58 ` Johannes Berg
2007-11-07 15:47 ` Alan Stern
2007-11-07 15:54 ` Johannes Berg
2007-11-07 16:47 ` Alan Stern
2007-11-07 16:53 ` Johannes Berg
2007-11-07 19:49 ` Mark Gross
2007-11-07 20:02 ` Alan Stern
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200711072331.54708.rjw@sisk.pl \
--to=rjw@sisk.pl \
--cc=linux-pm@lists.linux-foundation.org \
--cc=stern@rowland.harvard.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox