linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Shaohua Li <shli@kernel.org>
To: linux-mm@kvack.org
Cc: sjenning@linux.vnet.ibm.com, bob.liu@oracle.com,
	dan.magenheimer@oracle.com
Subject: [RFC 2/4] cleancache: make get_page async possible
Date: Thu, 26 Sep 2013 22:14:30 +0800	[thread overview]
Message-ID: <20130926141602.309768162@kernel.org> (raw)
In-Reply-To: 20130926141428.392345308@kernel.org

[-- Attachment #1: cleancache-async-get_page.patch --]
[-- Type: text/plain, Size: 6014 bytes --]

Make cleancache get_page support async page fetch. Just normal page read,
cleancache unlock the page after page fetch is finished.

But we don't support IO error from cleancache get_page. That is if cleancache
get_page fails, we can't fallback to normal page read.

Signed-off-by: Shaohua Li <shli@kernel.org>
---
 drivers/xen/tmem.c         |    8 +++++---
 fs/btrfs/extent_io.c       |   10 ++++++++--
 fs/mpage.c                 |   15 ++++++++++++---
 include/linux/cleancache.h |   11 +++++++----
 mm/cleancache.c            |    5 +++--
 5 files changed, 35 insertions(+), 14 deletions(-)

Index: linux/fs/btrfs/extent_io.c
===================================================================
--- linux.orig/fs/btrfs/extent_io.c	2013-09-26 21:21:14.530330681 +0800
+++ linux/fs/btrfs/extent_io.c	2013-09-26 21:21:14.522330771 +0800
@@ -2530,6 +2530,12 @@ readpage_ok:
 	bio_put(bio);
 }
 
+static void extent_end_get_page(struct page *page, int err)
+{
+	SetPageUptodate(page);
+	unlock_page(page);
+}
+
 /*
  * this allocates from the btrfs_bioset.  We're returning a bio right now
  * but you can call btrfs_io_bio for the appropriate container_of magic
@@ -2770,10 +2776,10 @@ static int __do_readpage(struct extent_i
 
 	end = page_end;
 	if (!PageUptodate(page)) {
-		if (cleancache_get_page(page) == 0) {
+		if (cleancache_get_page(page, extent_end_get_page) == 0) {
 			BUG_ON(blocksize != PAGE_SIZE);
 			unlock_extent(tree, start, end);
-			goto out;
+			return 0;
 		}
 	}
 
Index: linux/fs/mpage.c
===================================================================
--- linux.orig/fs/mpage.c	2013-09-26 21:21:14.530330681 +0800
+++ linux/fs/mpage.c	2013-09-26 21:21:14.522330771 +0800
@@ -71,6 +71,14 @@ static void mpage_end_io(struct bio *bio
 	bio_put(bio);
 }
 
+static void mpage_end_get_page(struct page *page, int err)
+{
+	/* We don't support IO error so far */
+	WARN_ON(err);
+	SetPageUptodate(page);
+	unlock_page(page);
+}
+
 static struct bio *mpage_bio_submit(int rw, struct bio *bio)
 {
 	bio->bi_end_io = mpage_end_io;
@@ -273,9 +281,10 @@ do_mpage_readpage(struct bio *bio, struc
 	}
 
 	if (fully_mapped && blocks_per_page == 1 && !PageUptodate(page) &&
-	    cleancache_get_page(page) == 0) {
-		SetPageUptodate(page);
-		goto confused;
+	    cleancache_get_page(page, mpage_end_get_page) == 0) {
+		if (bio)
+			bio = mpage_bio_submit(READ, bio);
+		goto out;
 	}
 
 	/*
Index: linux/include/linux/cleancache.h
===================================================================
--- linux.orig/include/linux/cleancache.h	2013-09-26 21:21:14.530330681 +0800
+++ linux/include/linux/cleancache.h	2013-09-26 21:21:14.526330726 +0800
@@ -25,7 +25,8 @@ struct cleancache_ops {
 	int (*init_fs)(size_t);
 	int (*init_shared_fs)(char *uuid, size_t);
 	int (*get_page)(int, struct cleancache_filekey,
-			pgoff_t, struct page *);
+			pgoff_t, struct page *,
+			void (*end_get_page)(struct page *, int err));
 	void (*put_page)(int, struct cleancache_filekey,
 			pgoff_t, struct page *);
 	void (*invalidate_page)(int, struct cleancache_filekey, pgoff_t);
@@ -37,7 +38,8 @@ extern struct cleancache_ops *
 	cleancache_register_ops(struct cleancache_ops *ops);
 extern void __cleancache_init_fs(struct super_block *);
 extern void __cleancache_init_shared_fs(char *, struct super_block *);
-extern int  __cleancache_get_page(struct page *);
+extern int  __cleancache_get_page(struct page *,
+	void (*end_get_page)(struct page *page, int err));
 extern void __cleancache_put_page(struct page *);
 extern void __cleancache_invalidate_page(struct address_space *, struct page *);
 extern void __cleancache_invalidate_inode(struct address_space *);
@@ -84,12 +86,13 @@ static inline void cleancache_init_share
 		__cleancache_init_shared_fs(uuid, sb);
 }
 
-static inline int cleancache_get_page(struct page *page)
+static inline int cleancache_get_page(struct page *page,
+	void (*end_get_page)(struct page *page, int err))
 {
 	int ret = -1;
 
 	if (cleancache_enabled && cleancache_fs_enabled(page))
-		ret = __cleancache_get_page(page);
+		ret = __cleancache_get_page(page, end_get_page);
 	return ret;
 }
 
Index: linux/mm/cleancache.c
===================================================================
--- linux.orig/mm/cleancache.c	2013-09-26 21:21:14.530330681 +0800
+++ linux/mm/cleancache.c	2013-09-26 21:21:14.526330726 +0800
@@ -225,7 +225,8 @@ static int get_poolid_from_fake(int fake
  * a backend is registered and whether the sb->cleancache_poolid
  * is correct.
  */
-int __cleancache_get_page(struct page *page)
+int __cleancache_get_page(struct page *page,
+	void (*end_get_page)(struct page *page, int err))
 {
 	int ret = -1;
 	int pool_id;
@@ -248,7 +249,7 @@ int __cleancache_get_page(struct page *p
 
 	if (pool_id >= 0)
 		ret = cleancache_ops->get_page(pool_id,
-				key, page->index, page);
+				key, page->index, page, end_get_page);
 	if (ret == 0)
 		cleancache_succ_gets++;
 	else
Index: linux/drivers/xen/tmem.c
===================================================================
--- linux.orig/drivers/xen/tmem.c	2013-09-26 21:21:14.530330681 +0800
+++ linux/drivers/xen/tmem.c	2013-09-26 21:21:14.526330726 +0800
@@ -184,7 +184,8 @@ static void tmem_cleancache_put_page(int
 }
 
 static int tmem_cleancache_get_page(int pool, struct cleancache_filekey key,
-				    pgoff_t index, struct page *page)
+				    pgoff_t index, struct page *page,
+				    void (*end_get_page)(struct page *, int))
 {
 	u32 ind = (u32) index;
 	struct tmem_oid oid = *(struct tmem_oid *)&key;
@@ -197,9 +198,10 @@ static int tmem_cleancache_get_page(int
 	if (ind != index)
 		return -1;
 	ret = xen_tmem_get_page((u32)pool, oid, ind, pfn);
-	if (ret == 1)
+	if (ret == 1) {
+		end_get_page(page, 0);
 		return 0;
-	else
+	} else
 		return -1;
 }
 

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

  parent reply	other threads:[~2013-09-26 14:16 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-09-26 14:14 [RFC 0/4] cleancache: SSD backed cleancache backend Shaohua Li
2013-09-26 14:14 ` [RFC 1/4] cleancache: make put_page async possible Shaohua Li
2013-09-26 14:14 ` Shaohua Li [this message]
2013-09-26 14:14 ` [RFC 3/4] cleancache: invalidate cache at dirty page Shaohua Li
2013-09-26 14:14 ` [RFC 4/4] cleancache: SSD backed cleancache backend Shaohua Li
2013-09-26 16:14 ` [RFC 0/4] " Seth Jennings
2013-09-29  9:19   ` Shaohua Li
2013-10-09 11:52   ` Theodore Ts'o
2013-10-10 10:24     ` Alex Elsayed
2013-10-10 10:38     ` Bob Liu

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=20130926141602.309768162@kernel.org \
    --to=shli@kernel.org \
    --cc=bob.liu@oracle.com \
    --cc=dan.magenheimer@oracle.com \
    --cc=linux-mm@kvack.org \
    --cc=sjenning@linux.vnet.ibm.com \
    /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).