9p: add readahead support for loose mode
Subsystems (3)
RFC PATCH 1/1 9p: add readahead support for loose mode
This patch adds readpages support in support of readahead when using loose cache mode. It substantially increases performance for certain workloads.
--- fs/9p/v9fs.c | 2 +- fs/9p/vfs_addr.c | 98 ++++++++++++++++++++++++++++++++++++++++++---- include/net/9p/client.h | 3 +- net/9p/client.c | 82 +++++++++++++++++++++++++-------------- 4 files changed, 143 insertions(+), 42 deletions(-)
fs/9p/v9fs.c +1 -1
@@ -131,7 +131,7 @@ static void v9fs_parse_options(struct v9fs_session_info *v9ses)char *s, *e;/* setup defaults */ - v9ses->maxdata =8192 ; + v9ses->maxdata = (64 *1024 ); v9ses->afid = ~0 ; v9ses->debug =0 ; v9ses->cache =0 ;
fs/9p/vfs_addr.c +89 -9
128 lines not on this page · raw message
include/net/9p/client.h +1 -2
@@ -67,8 +67,7 @@ int p9_client_fcreate(struct p9_fid *fid, char *name, u32 perm, int mode, char *extension);int p9_client_clunk (struct p9_fid *fid);int p9_client_remove (struct p9_fid *fid); -int p9_client_read (struct p9_fid *fid,char *data,u64 offset,u32 count); -int p9_client_readn (struct p9_fid *fid,char *data,u64 offset,u32 count); +int p9_client_readv (struct p9_fid *fid,struct kvec *kv,u64 offset,u32 count);int p9_client_write (struct p9_fid *fid,char *data,u64 offset,u32 count);int p9_client_uread (struct p9_fid *fid,char __user *data,u64 offset,u32 count);
net/9p/client.c +52 -30
118 lines not on this page · raw message
Signature · 1 line
1.5.3.rc7
Quoted 20 lines · On Fri, 14 Sep 2007 11:02:40 -0500 Eric Van Hensbergen <[email protected]> wrote:
fs/9p/vfs_addr.c +20
-0+list_for_each_entry_reverse (tmp_page, page_list, lru) { +BUG_ON (count > num_pages); +if (add_to_page_cache (tmp_page, mapping, + tmp_page->index,GFP_KERNEL )) { +page_cache_release (tmp_page); +continue ; + } + + kv[count].iov_base =kmap (tmp_page); + kv[count].iov_len =PAGE_CACHE_SIZE ; + count++; + } + + read_size = count *PAGE_CACHE_SIZE ; +if (!read_size) + goto cleanup; + + retval =p9_client_readv (fid, kv, offset, count); + +cleanup:
fs/9p/vfs_addr.c line 149
Quoted 10 lines
fs/9p/vfs_addr.c +10
-0+list_for_each_safe (p, n, page_list) { + tmp_page = list_entry(p, struct page, lru); +list_del (&tmp_page->lru); +if (!pagevec_add (&lru_pvec, tmp_page)) +__pagevec_lru_add (&lru_pvec); +kunmap (tmp_page); +flush_dcache_page (tmp_page); +SetPageUptodate (tmp_page); +unlock_page (tmp_page); + }
eww, kmap. Large amounts of them, apparently.
Be aware that kmap is a) slow and b) deadlockable. The latter happens when multiple tasks want to take more than one kmap simultaneously: they all wait for someone else to release one. Your code here seems especially vulnerable to this.
Nick had a kmap-speedup patchset a while back which addressed a) but I don't know if it addressed the deadlock. But that patch seemed to die.
Strongly recommend that the code be reworked to use kmap_atomic()
Quoted 9 lines · On Sat, 15 Sep 2007 03:41:26 -0700 Andrew Morton <[email protected]>…
eww, kmap. Large amounts of them, apparently.
Be aware that kmap is a) slow and b) deadlockable. The latter happens when multiple tasks want to take more than one kmap simultaneously: they all wait for someone else to release one. Your code here seems especially vulnerable to this.
Nick had a kmap-speedup patchset a while back which addressed a) but I don't know if it addressed the deadlock. But that patch seemed to die.
That would've been me.
What I did to address b) is to pre-allocate each kmap user a second kmap slot. Of course this isn't water-tight either.
These patches are part of -rt, I could respin against mainline if there is interest.