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>
next prev 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).