linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jiri Slaby <jslaby@suse.cz>
To: rjw@sisk.pl
Cc: pavel@ucw.cz, linux-pm@lists.linux-foundation.org,
	linux-kernel@vger.kernel.org, jirislaby@gmail.com
Subject: [PATCH 4/9] PM / Hibernate: user, implement user_ops reader
Date: Wed,  2 Jun 2010 10:52:43 +0200	[thread overview]
Message-ID: <1275468768-28229-4-git-send-email-jslaby@suse.cz> (raw)
In-Reply-To: <1275468768-28229-1-git-send-email-jslaby@suse.cz>

Switch /dev/snapshot writer to hibernate_io_ops approach so that we
can do whatever we want with snapshot processing code. All the later
code changes will be transparent and needn't care about different
readers/writers.

In this patch only reader is implemented, writer was done previously.

It works similarly to writer, CONSUMER here is snapshot layer,
PRODUCER is fops->write.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: "Rafael J. Wysocki" <rjw@sisk.pl>
---
 kernel/power/user.c |   76 +++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 68 insertions(+), 8 deletions(-)

diff --git a/kernel/power/user.c b/kernel/power/user.c
index b4610c3..fb9e5c8 100644
--- a/kernel/power/user.c
+++ b/kernel/power/user.c
@@ -79,6 +79,7 @@ static struct {
 #define TODO_FINISH	2
 #define TODO_CLOSED	3
 #define TODO_ERROR	4
+#define TODO_RD_RUNNING	5
 	DECLARE_BITMAP(flags, 10); /* TODO_* flags defined above */
 } to_do;
 
@@ -131,12 +132,43 @@ static int user_writer_finish(struct hibernate_io_handle *io_handle,
 	return error;
 }
 
+static struct hibernate_io_handle *user_reader_start(unsigned int *flags_p)
+{
+	return hib_io_handle_alloc(0) ? : ERR_PTR(-ENOMEM);
+}
+
+static int user_read_page(struct hibernate_io_handle *io_handle, void *addr,
+		struct bio **bio_chain)
+{
+	int err = 0;
+
+	mutex_lock(&to_do.lock);
+	to_do.buffer = addr;
+	mutex_unlock(&to_do.lock);
+	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 user_reader_finish(struct hibernate_io_handle *io_handle)
+{
+	return 0;
+}
+
 struct hibernate_io_ops user_ops = {
 	.free_space = user_free_space,
 
 	.writer_start = user_writer_start,
 	.writer_finish = user_writer_finish,
 	.write_page = user_write_page,
+
+	.reader_start = user_reader_start,
+	.reader_finish = user_reader_finish,
+	.read_page = user_read_page,
 };
 
 static void snapshot_writer(struct work_struct *work)
@@ -150,6 +182,22 @@ static void snapshot_writer(struct work_struct *work)
 
 static DECLARE_WORK(snapshot_writer_w, snapshot_writer);
 
+static void snapshot_reader(struct work_struct *work)
+{
+	int ret;
+
+	set_bit(TODO_RD_RUNNING, to_do.flags);
+	ret = swsusp_read(NULL);
+	if (ret) {
+		printk(KERN_ERR "PM: read failed with %d\n", ret);
+		set_bit(TODO_ERROR, to_do.flags);
+	}
+	clear_bit(TODO_RD_RUNNING, to_do.flags);
+	wake_up_interruptible(&to_do.wait);
+}
+
+static DECLARE_WORK(snapshot_reader_w, snapshot_reader);
+
 static int snapshot_open(struct inode *inode, struct file *filp)
 {
 	struct snapshot_data *data;
@@ -300,20 +348,29 @@ static ssize_t snapshot_write(struct file *filp, const char __user *buf,
 
 	mutex_lock(&pm_mutex);
 
+	if (!test_bit(TODO_RD_RUNNING, to_do.flags))
+		queue_work(to_do.worker, &snapshot_reader_w);
+
 	data = filp->private_data;
 
 	if (!pg_offp) {
-		res = snapshot_write_next(&data->handle);
-		if (res <= 0)
+		res = wait_event_interruptible(to_do.wait,
+				test_bit(TODO_WORK, to_do.flags));
+		if (res)
 			goto unlock;
-	} else {
-		res = PAGE_SIZE - pg_offp;
 	}
+	res = PAGE_SIZE - pg_offp;
 
-	res = simple_write_to_buffer(data_of(data->handle), res, &pg_offp,
-			buf, count);
+	mutex_lock(&to_do.lock);
+	res = simple_write_to_buffer(to_do.buffer, res, &pg_offp, buf, count);
+	mutex_unlock(&to_do.lock);
 	if (res > 0)
 		*offp += res;
+
+	if (!(pg_offp & ~PAGE_MASK)) {
+		clear_bit(TODO_WORK, to_do.flags);
+		wake_up(&to_do.done);
+	}
 unlock:
 	mutex_unlock(&pm_mutex);
 
@@ -398,9 +455,12 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
 		break;
 
 	case SNAPSHOT_ATOMIC_RESTORE:
-		snapshot_write_finalize(&data->handle);
+		error = wait_event_interruptible(to_do.wait,
+				!test_bit(TODO_RD_RUNNING, to_do.flags));
+		if (error)
+			break;
 		if (data->mode != O_WRONLY || !data->frozen ||
-		    !snapshot_image_loaded(&data->handle)) {
+				test_bit(TODO_ERROR, to_do.flags)) {
 			error = -EPERM;
 			break;
 		}
-- 
1.7.1



  parent reply	other threads:[~2010-06-02  8:53 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-06-02  8:52 [PATCH 1/9] PM / Hibernate: swap, switch to hibernate_io_handle Jiri Slaby
2010-06-02  8:52 ` [PATCH 2/9] PM / Hibernate: add hibernate_io_ops Jiri Slaby
2010-06-24 15:23   ` Rafael J. Wysocki
2010-06-02  8:52 ` [PATCH 3/9] PM / Hibernate: user, implement user_ops writer Jiri Slaby
2010-06-24 16:27   ` Rafael J. Wysocki
2010-06-02  8:52 ` Jiri Slaby [this message]
2010-06-25 13:37   ` [PATCH 4/9] PM / Hibernate: user, implement user_ops reader Rafael J. Wysocki
2010-06-02  8:52 ` [PATCH 5/9] PM / Hibernate: add chunk i/o support Jiri Slaby
2010-06-25 13:44   ` Rafael J. Wysocki
2010-06-02  8:52 ` [PATCH 6/9] PM / Hibernate: split snapshot_read_next Jiri Slaby
2010-06-25 13:53   ` Rafael J. Wysocki
2010-07-19 16:42     ` Jiri Slaby
2010-06-02  8:52 ` [PATCH 7/9] PM / Hibernate: split snapshot_write_next Jiri Slaby
2010-06-25 13:54   ` Rafael J. Wysocki
2010-06-02  8:52 ` [PATCH 8/9] PM / Hibernate: dealign swsusp_info Jiri Slaby
2010-06-25 13:54   ` Rafael J. Wysocki
2010-06-02  8:52 ` [PATCH 9/9] PM / Hibernate: move non-swap code to image.c Jiri Slaby
2010-06-25 13:55   ` Rafael J. Wysocki
2010-06-02 11:40 ` [PATCH 1/9] PM / Hibernate: swap, switch to hibernate_io_handle Nigel Cunningham
2010-06-02 12:37 ` [linux-pm] " Nigel Cunningham
2010-06-10 13:55 ` Pavel Machek
2010-06-21 15:23   ` Jiri Slaby
2010-07-18 12:36     ` Pavel Machek
2010-06-11  9:46 ` [linux-pm] " Nigel Cunningham
2010-06-21 15:21   ` Jiri Slaby
2010-06-21 21:58     ` Nigel Cunningham
2010-06-25 14:00       ` Rafael J. Wysocki
2010-06-24 15:20 ` 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=1275468768-28229-4-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=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;
as well as URLs for NNTP newsgroup(s).