1
linux/fs
Hisashi Hifumi 8ab22b9abb vfs: pagecache usage optimization for pagesize!=blocksize
When we read some part of a file through pagecache, if there is a
pagecache of corresponding index but this page is not uptodate, read IO
is issued and this page will be uptodate.

I think this is good for pagesize == blocksize environment but there is
room for improvement on pagesize != blocksize environment.  Because in
this case a page can have multiple buffers and even if a page is not
uptodate, some buffers can be uptodate.

So I suggest that when all buffers which correspond to a part of a file
that we want to read are uptodate, use this pagecache and copy data from
this pagecache to user buffer even if a page is not uptodate.  This can
reduce read IO and improve system throughput.

I wrote a benchmark program and got result number with this program.

This benchmark do:

  1: mount and open a test file.

  2: create a 512MB file.

  3: close a file and umount.

  4: mount and again open a test file.

  5: pwrite randomly 300000 times on a test file.  offset is aligned
     by IO size(1024bytes).

  6: measure time of preading randomly 100000 times on a test file.

The result was:
	2.6.26
        330 sec

	2.6.26-patched
        226 sec

Arch:i386
Filesystem:ext3
Blocksize:1024 bytes
Memory: 1GB

On ext3/4, a file is written through buffer/block.  So random read/write
mixed workloads or random read after random write workloads are optimized
with this patch under pagesize != blocksize environment.  This test result
showed this.

The benchmark program is as follows:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mount.h>

#define LEN 1024
#define LOOP 1024*512 /* 512MB */

main(void)
{
	unsigned long i, offset, filesize;
	int fd;
	char buf[LEN];
	time_t t1, t2;

	if (mount("/dev/sda1", "/root/test1/", "ext3", 0, 0) < 0) {
		perror("cannot mount\n");
		exit(1);
	}
	memset(buf, 0, LEN);
	fd = open("/root/test1/testfile", O_CREAT|O_RDWR|O_TRUNC);
	if (fd < 0) {
		perror("cannot open file\n");
		exit(1);
	}
	for (i = 0; i < LOOP; i++)
		write(fd, buf, LEN);
	close(fd);
	if (umount("/root/test1/") < 0) {
		perror("cannot umount\n");
		exit(1);
	}
	if (mount("/dev/sda1", "/root/test1/", "ext3", 0, 0) < 0) {
		perror("cannot mount\n");
		exit(1);
	}
	fd = open("/root/test1/testfile", O_RDWR);
	if (fd < 0) {
		perror("cannot open file\n");
		exit(1);
	}

	filesize = LEN * LOOP;
	for (i = 0; i < 300000; i++){
		offset = (random() % filesize) & (~(LEN - 1));
		pwrite(fd, buf, LEN, offset);
	}
	printf("start test\n");
	time(&t1);
	for (i = 0; i < 100000; i++){
		offset = (random() % filesize) & (~(LEN - 1));
		pread(fd, buf, LEN, offset);
	}
	time(&t2);
	printf("%ld sec\n", t2-t1);
	close(fd);
	if (umount("/root/test1/") < 0) {
		perror("cannot umount\n");
		exit(1);
	}
}

Signed-off-by: Hisashi Hifumi <hifumi.hisashi@oss.ntt.co.jp>
Cc: Nick Piggin <nickpiggin@yahoo.com.au>
Cc: Christoph Hellwig <hch@infradead.org>
Cc: Jan Kara <jack@ucw.cz>
Cc: <linux-ext4@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2008-07-28 16:30:21 -07:00
..
9p
adfs SL*B: drop kmem cache argument from constructor 2008-07-26 12:00:07 -07:00
affs [PATCH] f_count may wrap around 2008-07-26 20:53:40 -04:00
afs [PATCH] sanitize ->permission() prototype 2008-07-26 20:53:14 -04:00
autofs
autofs4 autofs4: remove unused ioctls 2008-07-24 10:47:33 -07:00
befs SL*B: drop kmem cache argument from constructor 2008-07-26 12:00:07 -07:00
bfs SL*B: drop kmem cache argument from constructor 2008-07-26 12:00:07 -07:00
cifs [PATCH] sanitize ->permission() prototype 2008-07-26 20:53:14 -04:00
coda [PATCH] sanitize __user_walk_fd() et.al. 2008-07-26 20:53:34 -04:00
configfs configfs: Allow ->make_item() and ->make_group() to return detailed errors. 2008-07-17 15:21:29 -07:00
cramfs
debugfs debugfs: Implement debugfs_remove_recursive() 2008-07-21 21:54:59 -07:00
devpts
dlm Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/teigland/dlm 2008-07-28 09:46:00 -07:00
ecryptfs [PATCH] kill nameidata passing to permission(), rename to inode_permission() 2008-07-26 20:53:31 -04:00
efs SL*B: drop kmem cache argument from constructor 2008-07-26 12:00:07 -07:00
exportfs
ext2 vfs: pagecache usage optimization for pagesize!=blocksize 2008-07-28 16:30:21 -07:00
ext3 vfs: pagecache usage optimization for pagesize!=blocksize 2008-07-28 16:30:21 -07:00
ext4 vfs: pagecache usage optimization for pagesize!=blocksize 2008-07-28 16:30:21 -07:00
fat [patch 3/4] fat: dont call notify_change 2008-07-26 20:53:27 -04:00
freevxfs
fuse [PATCH] fix MAY_CHDIR/MAY_ACCESS/LOOKUP_ACCESS mess 2008-07-26 20:53:21 -04:00
gfs2 [PATCH] don't pass nameidata to gfs2_lookupi() 2008-07-26 20:53:36 -04:00
hfs [PATCH] f_count may wrap around 2008-07-26 20:53:40 -04:00
hfsplus [PATCH] f_count may wrap around 2008-07-26 20:53:40 -04:00
hostfs [PATCH] sanitize ->permission() prototype 2008-07-26 20:53:14 -04:00
hpfs [patch 05/14] hpfs: dont call permission() 2008-07-26 20:53:13 -04:00
hppfs [patch] hppfs: remove hppfs_permission 2008-07-26 20:53:07 -04:00
hugetlbfs SL*B: drop kmem cache argument from constructor 2008-07-26 12:00:07 -07:00
isofs SL*B: drop kmem cache argument from constructor 2008-07-26 12:00:07 -07:00
jbd jbd: don't abort if flushing file data failed 2008-07-25 10:53:32 -07:00
jbd2
jffs2 Merge git://git.infradead.org/mtd-2.6 2008-07-26 20:30:56 -07:00
jfs [PATCH] sanitize ->permission() prototype 2008-07-26 20:53:14 -04:00
lockd locks: add special return value for asynchronous locks 2008-07-25 10:53:47 -07:00
minix SL*B: drop kmem cache argument from constructor 2008-07-26 12:00:07 -07:00
msdos fatfs: add UTC timestamp option 2008-07-25 10:53:34 -07:00
ncpfs [PATCH] don't pass nameidata to __ncp_lookup_validate() 2008-07-26 20:53:37 -04:00
nfs NFS: Ensure we call nfs_sb_deactive() after releasing the directory inode 2008-07-27 18:20:51 -04:00
nfs_common
nfsd [PATCH] get rid of indirect users of namei.h 2008-07-26 20:53:42 -04:00
nls
ntfs [patch 3/5] vfs: change remove_suid() to file_remove_suid() 2008-07-26 20:53:16 -04:00
ocfs2 [PATCH] sanitize ->permission() prototype 2008-07-26 20:53:14 -04:00
omfs omfs: update kbuild to include OMFS 2008-07-26 12:00:05 -07:00
openpromfs SL*B: drop kmem cache argument from constructor 2008-07-26 12:00:07 -07:00
partitions fs/partitions/efi: convert to pr_debug 2008-07-25 10:53:44 -07:00
proc task IO accounting: move all IO statistics in struct task_io_accounting 2008-07-27 16:12:28 -07:00
qnx4 SL*B: drop kmem cache argument from constructor 2008-07-26 12:00:07 -07:00
ramfs
reiserfs [PATCH] sanitize ->permission() prototype 2008-07-26 20:53:14 -04:00
romfs SL*B: drop kmem cache argument from constructor 2008-07-26 12:00:07 -07:00
smbfs [PATCH] sanitize ->permission() prototype 2008-07-26 20:53:14 -04:00
sysfs Use WARN() in fs/sysfs 2008-07-26 12:00:07 -07:00
sysv SL*B: drop kmem cache argument from constructor 2008-07-26 12:00:07 -07:00
ubifs [PATCH] get rid of indirect users of namei.h 2008-07-26 20:53:42 -04:00
udf SL*B: drop kmem cache argument from constructor 2008-07-26 12:00:07 -07:00
ufs SL*B: drop kmem cache argument from constructor 2008-07-26 12:00:07 -07:00
vfat fatfs: add UTC timestamp option 2008-07-25 10:53:34 -07:00
xfs [PATCH] sanitize __user_walk_fd() et.al. 2008-07-26 20:53:34 -04:00
aio.c [PATCH] f_count may wrap around 2008-07-26 20:53:40 -04:00
anon_inodes.c flag parameters: NONBLOCK in anon_inode_getfd 2008-07-24 10:47:28 -07:00
attr.c [patch 4/4] vfs: immutable inode checking cleanup 2008-07-26 20:53:28 -04:00
bad_inode.c [PATCH] sanitize ->permission() prototype 2008-07-26 20:53:14 -04:00
binfmt_aout.c tracehook: exec 2008-07-26 12:00:08 -07:00
binfmt_elf_fdpic.c binfmt_elf_fdpic: Magical stack pointer index, for NEW_AUX_ENT compat. 2008-07-28 18:10:28 +09:00
binfmt_elf.c tracehook: exec 2008-07-26 12:00:08 -07:00
binfmt_em86.c
binfmt_flat.c tracehook: exec 2008-07-26 12:00:08 -07:00
binfmt_misc.c binfmt_misc: use simple_read_from_buffer() 2008-07-24 10:47:27 -07:00
binfmt_script.c
binfmt_som.c tracehook: exec 2008-07-26 12:00:08 -07:00
bio-integrity.c
bio.c dio: use get_user_pages_fast 2008-07-26 12:00:06 -07:00
block_dev.c SL*B: drop kmem cache argument from constructor 2008-07-26 12:00:07 -07:00
buffer.c vfs: pagecache usage optimization for pagesize!=blocksize 2008-07-28 16:30:21 -07:00
char_dev.c
compat_binfmt_elf.c
compat_ioctl.c remove unused #include <linux/dirent.h>'s 2008-07-25 10:53:34 -07:00
compat.c [PATCH] sanitize __user_walk_fd() et.al. 2008-07-26 20:53:34 -04:00
dcache.c vfs: add cond_resched_lock while scanning dentry LRU lists 2008-07-26 12:00:02 -07:00
dcookies.c
direct-io.c dio: use get_user_pages_fast 2008-07-26 12:00:06 -07:00
dnotify.c
dquot.c quota: implement sending information via netlink about user below quota 2008-07-25 10:53:35 -07:00
drop_caches.c
eventfd.c flag parameters: check magic constants 2008-07-24 10:47:29 -07:00
eventpoll.c flag parameters add-on: remove epoll_create size param 2008-07-24 10:47:29 -07:00
exec.c exec: include pagemap.h again to fix build 2008-07-28 16:30:20 -07:00
fcntl.c [PATCH] fix RLIM_NOFILE handling 2008-07-26 20:53:45 -04:00
fifo.c [PATCH] reuse xxx_fifo_fops for xxx_pipe_fops 2008-07-26 20:53:06 -04:00
file_table.c [PATCH] f_count may wrap around 2008-07-26 20:53:40 -04:00
file.c [PATCH] fix RLIM_NOFILE handling 2008-07-26 20:53:45 -04:00
filesystems.c
fs-writeback.c
generic_acl.c
inode.c SL*B: drop kmem cache argument from constructor 2008-07-26 12:00:07 -07:00
inotify_user.c [PATCH] sanitize __user_walk_fd() et.al. 2008-07-26 20:53:34 -04:00
inotify.c
internal.h
ioctl.c
ioprio.c
Kconfig omfs: update kbuild to include OMFS 2008-07-26 12:00:05 -07:00
Kconfig.binfmt sh: Initial ELF FDPIC support. 2008-07-28 18:10:28 +09:00
libfs.c
locks.c SL*B: drop kmem cache argument from constructor 2008-07-26 12:00:07 -07:00
Makefile omfs: update kbuild to include OMFS 2008-07-26 12:00:05 -07:00
mbcache.c
mpage.c
namei.c [PATCH] get rid of __user_path_lookup_open 2008-07-26 20:53:41 -04:00
namespace.c [PATCH] sanitize __user_walk_fd() et.al. 2008-07-26 20:53:34 -04:00
nfsctl.c
no-block.c
open.c [PATCH] fix RLIM_NOFILE handling 2008-07-26 20:53:45 -04:00
pipe.c [PATCH] reuse xxx_fifo_fops for xxx_pipe_fops 2008-07-26 20:53:06 -04:00
pnode.c
pnode.h
posix_acl.c
quota_v1.c quota: move function-macros from quota.h to quotaops.h 2008-07-25 10:53:35 -07:00
quota_v2.c quota: move function-macros from quota.h to quotaops.h 2008-07-25 10:53:35 -07:00
quota.c quota: cleanup loop in sync_dquots() 2008-07-25 10:53:35 -07:00
read_write.c
read_write.h
readdir.c
select.c
seq_file.c
signalfd.c flag parameters: check magic constants 2008-07-24 10:47:29 -07:00
splice.c [patch 3/5] vfs: change remove_suid() to file_remove_suid() 2008-07-26 20:53:16 -04:00
stack.c
stat.c [PATCH] sanitize __user_walk_fd() et.al. 2008-07-26 20:53:34 -04:00
super.c fix soft lock up at NFS mount via per-SB LRU-list of unused dentries 2008-07-24 10:47:15 -07:00
sync.c SYNC_FILE_RANGE_WRITE may and will block. Document that. 2008-07-24 10:47:17 -07:00
timerfd.c flag parameters: check magic constants 2008-07-24 10:47:29 -07:00
utimes.c [PATCH] sanitize __user_walk_fd() et.al. 2008-07-26 20:53:34 -04:00
xattr_acl.c
xattr.c [PATCH] sanitize __user_walk_fd() et.al. 2008-07-26 20:53:34 -04:00