From: Pavel Machek <pavel@suse.cz>
To: "Rafael J. Wysocki" <rjw@sisk.pl>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>,
linux-kernel@vger.kernel.org, akpm@osdl.org,
pm list <linux-pm@lists.linux-foundation.org>
Subject: Re: [RFC][PATCH] snapshot: Use pm_mutex for mutual exclusion
Date: Wed, 4 Jun 2008 00:20:05 +0200 [thread overview]
Message-ID: <20080603222005.GA10929@elf.ucw.cz> (raw)
In-Reply-To: <200806022333.56939.rjw@sisk.pl>
Hi!
> Appended is what I think we can do.
Looks ok to me. ACK.
Pavel
> ---
> We can avoid taking the BKL in snapshot_ioctl() if pm_mutex is used to prevent
> the ioctls from being executed concurrently.
>
> In addition, although it is only possible to open /dev/snapshot once, the task
> which has done that may spawn a child that will inherit the open descriptor,
> so in theory they can call snapshot_write(), snapshot_read() and
> snapshot_release() concurrently. pm_mutex can also be used for mutual
> exclusion in such cases.
>
> Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
> ---
> kernel/power/user.c | 68 ++++++++++++++++++++++++++++++++--------------------
> 1 file changed, 42 insertions(+), 26 deletions(-)
>
> Index: linux-2.6/kernel/power/user.c
> ===================================================================
> --- linux-2.6.orig/kernel/power/user.c
> +++ linux-2.6/kernel/power/user.c
> @@ -70,16 +70,22 @@ static int snapshot_open(struct inode *i
> struct snapshot_data *data;
> int error;
>
> - if (!atomic_add_unless(&snapshot_device_available, -1, 0))
> - return -EBUSY;
> + mutex_lock(&pm_mutex);
> +
> + if (!atomic_add_unless(&snapshot_device_available, -1, 0)) {
> + error = -EBUSY;
> + goto Unlock;
> + }
>
> if ((filp->f_flags & O_ACCMODE) == O_RDWR) {
> atomic_inc(&snapshot_device_available);
> - return -ENOSYS;
> + error = -ENOSYS;
> + goto Unlock;
> }
> if(create_basic_memory_bitmaps()) {
> atomic_inc(&snapshot_device_available);
> - return -ENOMEM;
> + error = -ENOMEM;
> + goto Unlock;
> }
> nonseekable_open(inode, filp);
> data = &snapshot_state;
> @@ -99,33 +105,36 @@ static int snapshot_open(struct inode *i
> if (error)
> pm_notifier_call_chain(PM_POST_HIBERNATION);
> }
> - if (error) {
> + if (error)
> atomic_inc(&snapshot_device_available);
> - return error;
> - }
> data->frozen = 0;
> data->ready = 0;
> data->platform_support = 0;
>
> - return 0;
> + Unlock:
> + mutex_unlock(&pm_mutex);
> +
> + return error;
> }
>
> static int snapshot_release(struct inode *inode, struct file *filp)
> {
> struct snapshot_data *data;
>
> + mutex_lock(&pm_mutex);
> +
> swsusp_free();
> free_basic_memory_bitmaps();
> data = filp->private_data;
> free_all_swap_pages(data->swap);
> - if (data->frozen) {
> - mutex_lock(&pm_mutex);
> + if (data->frozen)
> thaw_processes();
> - mutex_unlock(&pm_mutex);
> - }
> pm_notifier_call_chain(data->mode == O_WRONLY ?
> PM_POST_HIBERNATION : PM_POST_RESTORE);
> atomic_inc(&snapshot_device_available);
> +
> + mutex_unlock(&pm_mutex);
> +
> return 0;
> }
>
> @@ -135,9 +144,13 @@ static ssize_t snapshot_read(struct file
> struct snapshot_data *data;
> ssize_t res;
>
> + mutex_lock(&pm_mutex);
> +
> data = filp->private_data;
> - if (!data->ready)
> - return -ENODATA;
> + if (!data->ready) {
> + res = -ENODATA;
> + goto Unlock;
> + }
> res = snapshot_read_next(&data->handle, count);
> if (res > 0) {
> if (copy_to_user(buf, data_of(data->handle), res))
> @@ -145,6 +158,10 @@ static ssize_t snapshot_read(struct file
> else
> *offp = data->handle.offset;
> }
> +
> + Unlock:
> + mutex_unlock(&pm_mutex);
> +
> return res;
> }
>
> @@ -154,6 +171,8 @@ static ssize_t snapshot_write(struct fil
> struct snapshot_data *data;
> ssize_t res;
>
> + mutex_lock(&pm_mutex);
> +
> data = filp->private_data;
> res = snapshot_write_next(&data->handle, count);
> if (res > 0) {
> @@ -162,6 +181,9 @@ static ssize_t snapshot_write(struct fil
> else
> *offp = data->handle.offset;
> }
> +
> + mutex_unlock(&pm_mutex);
> +
> return res;
> }
>
> @@ -180,16 +202,16 @@ static long snapshot_ioctl(struct file *
> if (!capable(CAP_SYS_ADMIN))
> return -EPERM;
>
> - data = filp->private_data;
> + if (!mutex_trylock(&pm_mutex))
> + return -EBUSY;
>
> - lock_kernel();
> + data = filp->private_data;
>
> switch (cmd) {
>
> case SNAPSHOT_FREEZE:
> if (data->frozen)
> break;
> - mutex_lock(&pm_mutex);
> printk("Syncing filesystems ... ");
> sys_sync();
> printk("done.\n");
> @@ -197,7 +219,6 @@ static long snapshot_ioctl(struct file *
> error = freeze_processes();
> if (error)
> thaw_processes();
> - mutex_unlock(&pm_mutex);
> if (!error)
> data->frozen = 1;
> break;
> @@ -205,9 +226,7 @@ static long snapshot_ioctl(struct file *
> case SNAPSHOT_UNFREEZE:
> if (!data->frozen || data->ready)
> break;
> - mutex_lock(&pm_mutex);
> thaw_processes();
> - mutex_unlock(&pm_mutex);
> data->frozen = 0;
> break;
>
> @@ -310,16 +329,11 @@ static long snapshot_ioctl(struct file *
> error = -EPERM;
> break;
> }
> - if (!mutex_trylock(&pm_mutex)) {
> - error = -EBUSY;
> - break;
> - }
> /*
> * Tasks are frozen and the notifiers have been called with
> * PM_HIBERNATION_PREPARE
> */
> error = suspend_devices_and_enter(PM_SUSPEND_MEM);
> - mutex_unlock(&pm_mutex);
> break;
>
> case SNAPSHOT_PLATFORM_SUPPORT:
> @@ -392,7 +406,9 @@ static long snapshot_ioctl(struct file *
> error = -ENOTTY;
>
> }
> - unlock_kernel();
> +
> + mutex_unlock(&pm_mutex);
> +
> return error;
> }
>
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
next prev parent reply other threads:[~2008-06-03 22:19 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-05-22 21:25 [PATCH] snapshot: Push BKL down into ioctl handlers Alan Cox
2008-05-23 1:09 ` Rafael J. Wysocki
2008-05-23 11:04 ` Alan Cox
2008-05-23 11:22 ` Rafael J. Wysocki
2008-06-02 21:33 ` [RFC][PATCH] snapshot: Use pm_mutex for mutual exclusion Rafael J. Wysocki
2008-06-03 22:20 ` Pavel Machek [this message]
2008-06-03 22:20 ` Pavel Machek
2008-06-02 21:33 ` Rafael J. Wysocki
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=20080603222005.GA10929@elf.ucw.cz \
--to=pavel@suse.cz \
--cc=akpm@osdl.org \
--cc=alan@lxorguk.ukuu.org.uk \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@lists.linux-foundation.org \
--cc=rjw@sisk.pl \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.