From: Jiri Slaby <jslaby@suse.cz>
To: jirislaby@gmail.com
Cc: pavel@ucw.cz, linux-pm@lists.linux-foundation.org,
linux-kernel@vger.kernel.org, Jiri Slaby <jslaby@suse.cz>,
Nigel Cunningham <ncunningham@crca.org.au>,
"Rafael J. Wysocki" <rjw@sisk.pl>
Subject: [RFC 09/15] PM / Hibernate: user, implement user_ops writer
Date: Tue, 23 Mar 2010 17:17:37 +0100 [thread overview]
Message-ID: <1269361063-3341-9-git-send-email-jslaby@suse.cz> (raw)
In-Reply-To: <1269361063-3341-1-git-send-email-jslaby@suse.cz>
Switch /dev/snapshot writer to sws_module_ops approach so that we
can transparently rewrite the rest of the snapshot from pages pulling
to their pushing through layers.
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Nigel Cunningham <ncunningham@crca.org.au>
Cc: "Rafael J. Wysocki" <rjw@sisk.pl>
---
kernel/power/user.c | 113 +++++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 105 insertions(+), 8 deletions(-)
diff --git a/kernel/power/user.c b/kernel/power/user.c
index 20bf34c..748567d 100644
--- a/kernel/power/user.c
+++ b/kernel/power/user.c
@@ -66,15 +66,82 @@ static struct snapshot_data {
atomic_t snapshot_device_available = ATOMIC_INIT(1);
+static void *to_do_buf;
+static struct workqueue_struct *suspend_worker;
+static DECLARE_WAIT_QUEUE_HEAD(to_do_wait);
+static DECLARE_WAIT_QUEUE_HEAD(to_do_done);
+static DECLARE_BITMAP(to_do_flags, 10);
+
+#define TODO_WORK 1
+#define TODO_FINISH 2
+#define TODO_CLOSED 3
+#define TODO_ERROR 4
+
static unsigned long user_storage_available(void)
{
return ~0UL; /* we have no idea, maybe we will fail later */
}
+static int get_user_writer(void)
+{
+ return 0;
+}
+
+static int user_write_page(void *buf, struct bio **bio_chain)
+{
+ int err = 0;
+
+ if (test_bit(TODO_CLOSED, to_do_flags))
+ return -EIO;
+
+ to_do_buf = buf;
+ wmb();
+ set_bit(TODO_WORK, to_do_flags);
+ wake_up_interruptible(&to_do_wait);
+
+ wait_event(to_do_done, !test_bit(TODO_WORK, to_do_flags) ||
+ (err = test_bit(TODO_CLOSED, to_do_flags)));
+
+ return err ? -EIO : 0;
+}
+
+static int put_user_writer(unsigned int flags, int error)
+{
+ int err = 0;
+
+ if (error)
+ set_bit(TODO_ERROR, to_do_flags);
+ set_bit(TODO_FINISH, to_do_flags);
+ wake_up_interruptible(&to_do_wait);
+
+ wait_event(to_do_done, !test_bit(TODO_FINISH, to_do_flags) ||
+ (err = test_bit(TODO_CLOSED, to_do_flags)));
+
+ if (!error && err)
+ error = -EIO;
+
+ return error;
+}
+
struct sws_module_ops user_ops = {
.storage_available = user_storage_available,
+
+ .get_writer = get_user_writer,
+ .put_writer = put_user_writer,
+ .write_page = user_write_page,
};
+static void snapshot_writer(struct work_struct *work)
+{
+ int ret;
+
+ ret = swsusp_write(0);
+ if (ret)
+ printk(KERN_ERR "PM: write failed with %d\n", ret);
+}
+
+static DECLARE_WORK(snapshot_writer_w, snapshot_writer);
+
static int snapshot_open(struct inode *inode, struct file *filp)
{
struct snapshot_data *data;
@@ -132,6 +199,7 @@ static int snapshot_open(struct inode *inode, struct file *filp)
data->frozen = 0;
data->ready = 0;
data->platform_support = 0;
+ memset(to_do_flags, 0, sizeof(*to_do_flags));
Unlock:
mutex_unlock(&pm_mutex);
@@ -145,6 +213,10 @@ static int snapshot_release(struct inode *inode, struct file *filp)
mutex_lock(&pm_mutex);
+ set_bit(TODO_CLOSED, to_do_flags);
+ wake_up(&to_do_done);
+ flush_workqueue(suspend_worker);
+
swsusp_free();
free_basic_memory_bitmaps();
data = filp->private_data;
@@ -167,6 +239,7 @@ static ssize_t snapshot_read(struct file *filp, char __user *buf,
struct snapshot_data *data;
ssize_t res;
loff_t pg_offp = *offp & ~PAGE_MASK;
+ int fin = 0;
mutex_lock(&pm_mutex);
@@ -176,17 +249,29 @@ static ssize_t snapshot_read(struct file *filp, char __user *buf,
goto Unlock;
}
if (!pg_offp) { /* on page boundary? */
- res = snapshot_read_next(&data->handle);
- if (res <= 0)
+ res = wait_event_interruptible(to_do_wait,
+ test_bit(TODO_WORK, to_do_flags) ||
+ (fin = test_and_clear_bit(TODO_FINISH, to_do_flags)));
+ if (res)
goto Unlock;
- } else
- res = PAGE_SIZE - pg_offp;
+ if (test_bit(TODO_ERROR, to_do_flags)) {
+ res = -EIO;
+ goto Unlock;
+ }
+ if (fin)
+ goto wake;
+ }
+ res = PAGE_SIZE - pg_offp;
- res = simple_read_from_buffer(buf, count, &pg_offp,
- data_of(data->handle), res);
+ res = simple_read_from_buffer(buf, count, &pg_offp, to_do_buf, res);
if (res > 0)
*offp += res;
+ if (!(pg_offp & ~PAGE_MASK)) {
+ clear_bit(TODO_WORK, to_do_flags);
+wake:
+ wake_up(&to_do_done);
+ }
Unlock:
mutex_unlock(&pm_mutex);
@@ -291,8 +376,11 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
error = hibernation_snapshot(data->platform_support);
if (!error)
error = put_user(in_suspend, (int __user *)arg);
- if (!error)
+ if (!error) {
+ if (in_suspend)
+ queue_work(suspend_worker, &snapshot_writer_w);
data->ready = 1;
+ }
break;
case SNAPSHOT_ATOMIC_RESTORE:
@@ -486,7 +574,16 @@ static struct miscdevice snapshot_device = {
static int __init snapshot_device_init(void)
{
- return misc_register(&snapshot_device);
+ int ret;
+
+ suspend_worker = create_singlethread_workqueue("suspend_worker");
+ if (!suspend_worker)
+ return -ENOMEM;
+
+ ret = misc_register(&snapshot_device);
+ if (ret)
+ destroy_workqueue(suspend_worker);
+ return ret;
};
device_initcall(snapshot_device_init);
--
1.7.0.2
next prev parent reply other threads:[~2010-03-23 16:24 UTC|newest]
Thread overview: 70+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-03-23 16:17 [RFC 01/15] FS: libfs, implement simple_write_to_buffer Jiri Slaby
2010-03-23 16:17 ` [RFC 02/15] PM / Hibernate: snapshot cleanup Jiri Slaby
2010-03-24 20:29 ` Pavel Machek
2010-03-24 22:35 ` Rafael J. Wysocki
2010-03-25 5:29 ` Pavel Machek
2010-03-23 16:17 ` [RFC 03/15] PM / Hibernate: separate block_io Jiri Slaby
2010-03-24 20:30 ` Pavel Machek
2010-03-24 21:22 ` Jiri Slaby
2010-03-24 22:58 ` Nigel Cunningham
2010-03-25 2:35 ` [linux-pm] " Nigel Cunningham
2010-03-25 20:12 ` Rafael J. Wysocki
2010-03-25 20:13 ` Nigel Cunningham
2010-03-25 20:33 ` Rafael J. Wysocki
2010-03-25 20:36 ` Nigel Cunningham
2010-03-29 13:30 ` Pavel Machek
2010-03-25 14:29 ` Pavel Machek
2010-03-23 16:17 ` [RFC 04/15] PM / Hibernate: move the first_sector out of swsusp_write Jiri Slaby
2010-03-24 20:31 ` Pavel Machek
2010-03-25 21:26 ` Rafael J. Wysocki
2010-03-23 16:17 ` [RFC 05/15] PM / Hibernate: group swap ops Jiri Slaby
2010-03-25 21:28 ` Rafael J. Wysocki
2010-03-23 16:17 ` [RFC 06/15] PM / Hibernate: swap, remove swap_map_handle usages Jiri Slaby
2010-03-24 20:33 ` Pavel Machek
2010-03-24 21:29 ` Jiri Slaby
2010-03-25 21:35 ` Rafael J. Wysocki
2010-03-23 16:17 ` [RFC 07/15] PM / Hibernate: add sws_modules_ops Jiri Slaby
2010-03-24 20:36 ` Pavel Machek
2010-03-24 21:31 ` Jiri Slaby
2010-03-25 22:02 ` Rafael J. Wysocki
2010-03-23 16:17 ` [RFC 08/15] PM / Hibernate: add user module_ops Jiri Slaby
2010-03-25 22:07 ` Rafael J. Wysocki
2010-03-26 9:43 ` Jiri Slaby
2010-03-23 16:17 ` Jiri Slaby [this message]
2010-03-24 20:42 ` [RFC 09/15] PM / Hibernate: user, implement user_ops writer Pavel Machek
2010-03-24 21:40 ` Jiri Slaby
2010-03-25 21:36 ` Pavel Machek
2010-03-25 22:14 ` Rafael J. Wysocki
2010-03-26 9:34 ` Jiri Slaby
2010-03-26 22:04 ` Rafael J. Wysocki
2010-03-29 15:33 ` Jiri Slaby
2010-03-27 7:02 ` Pavel Machek
2010-03-23 16:17 ` [RFC 10/15] PM / Hibernate: user, implement user_ops reader Jiri Slaby
2010-03-25 5:30 ` what the patches do " Pavel Machek
2010-03-25 5:42 ` Nigel Cunningham
2010-03-25 6:12 ` [linux-pm] " Nigel Cunningham
2010-03-25 20:14 ` Rafael J. Wysocki
2010-03-25 20:21 ` Nigel Cunningham
2010-03-25 20:29 ` Rafael J. Wysocki
2010-03-25 20:35 ` Nigel Cunningham
2010-03-25 21:13 ` Rafael J. Wysocki
2010-03-25 21:26 ` Pavel Machek
2010-03-25 21:49 ` [linux-pm] " Nigel Cunningham
2010-04-02 6:36 ` Pavel Machek
2010-04-02 17:03 ` Rafael J. Wysocki
2010-03-25 22:21 ` Rafael J. Wysocki
2010-03-23 16:17 ` [RFC 11/15] PM / Hibernate: add chunk i/o support Jiri Slaby
2010-03-25 22:38 ` Rafael J. Wysocki
2010-03-26 9:09 ` Jiri Slaby
2010-03-26 10:02 ` Nigel Cunningham
2010-03-23 16:17 ` [RFC 12/15] PM / Hibernate: split snapshot_read_next Jiri Slaby
2010-03-25 22:44 ` Rafael J. Wysocki
2010-03-23 16:17 ` [RFC 13/15] PM / Hibernate: split snapshot_write_next Jiri Slaby
2010-03-25 22:46 ` Rafael J. Wysocki
2010-03-23 16:17 ` [RFC 14/15] PM / Hibernate: dealign swsusp_info Jiri Slaby
2010-03-25 22:46 ` Rafael J. Wysocki
2010-03-23 16:17 ` [RFC 15/15] PM / Hibernate: move non-swap code to snapshot.c Jiri Slaby
2010-03-25 22:50 ` Rafael J. Wysocki
2010-03-23 21:51 ` [RFC 01/15] FS: libfs, implement simple_write_to_buffer Rafael J. Wysocki
2010-03-23 22:09 ` [linux-pm] " Nigel Cunningham
2010-03-24 22:13 ` 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=1269361063-3341-9-git-send-email-jslaby@suse.cz \
--to=jslaby@suse.cz \
--cc=jirislaby@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@lists.linux-foundation.org \
--cc=ncunningham@crca.org.au \
--cc=pavel@ucw.cz \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®