linux/include
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
..
acpi Merge branch 'linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6 2008-07-16 17:25:46 -07:00
asm-alpha [PATCH] kill altroot 2008-07-26 20:53:20 -04:00
asm-arm spi_s3c24xx: really assign busnum 2008-07-28 16:30:21 -07:00
asm-avr32 Merge commit 'upstream/master' 2008-07-27 13:54:08 +02:00
asm-blackfin [PATCH] kill altroot 2008-07-26 20:53:20 -04:00
asm-cris [PATCH] kill altroot 2008-07-26 20:53:20 -04:00
asm-frv [PATCH] kill altroot 2008-07-26 20:53:20 -04:00
asm-generic Merge git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild-next 2008-07-27 09:59:59 -07:00
asm-h8300 [PATCH] kill altroot 2008-07-26 20:53:20 -04:00
asm-ia64 [PATCH] kill altroot 2008-07-26 20:53:20 -04:00
asm-m32r [PATCH] kill altroot 2008-07-26 20:53:20 -04:00
asm-m68k [PATCH] kill altroot 2008-07-26 20:53:20 -04:00
asm-m68knommu [PATCH] kill altroot 2008-07-26 20:53:20 -04:00
asm-mips [PATCH] kill altroot 2008-07-26 20:53:20 -04:00
asm-mn10300 [PATCH] kill altroot 2008-07-26 20:53:20 -04:00
asm-parisc [PATCH] kill altroot 2008-07-26 20:53:20 -04:00
asm-powerpc powerpc/mm: Implement _PAGE_SPECIAL & pte_special() for 64-bit 2008-07-28 16:30:52 +10:00
asm-s390 KVM: s390: Fix instruction naming for lctlg 2008-07-27 11:36:12 +03:00
asm-sh sh: Add SuperH Mobile CEU platform data for Migo-R 2008-07-28 18:51:07 +09:00
asm-um [PATCH] kill altroot 2008-07-26 20:53:20 -04:00
asm-x86 KVM: SVM: allow enabling/disabling NPT by reloading only the architecture module 2008-07-27 11:34:09 +03:00
asm-xtensa [PATCH] kill altroot 2008-07-26 20:53:20 -04:00
crypto crypto: hash - Move ahash functions into crypto/hash.h 2008-07-10 20:35:18 +08:00
drm drm/radeon: fixup issue with radeon and PAT support. 2008-07-15 15:48:05 +10:00
keys
linux vfs: pagecache usage optimization for pagesize!=blocksize 2008-07-28 16:30:21 -07:00
math-emu
media V4L/DVB (8525): fix a few assorted spelling mistakes. 2008-07-27 11:07:13 -03:00
mtd Merge branch 'linux-next' of git://git.infradead.org/~dedekind/ubi-2.6 2008-07-25 10:40:14 -04:00
net missing bits of net-namespace / sysctl 2008-07-27 09:45:34 -07:00
pcmcia pcmcia: (re)move {pcmcia,pccard}_get_status 2008-06-24 15:33:44 +02:00
rdma dma-mapping: add the device argument to dma_mapping_error() 2008-07-26 12:00:03 -07:00
rxrpc
scsi [SCSI] extend the last_sector_bug flag to cover more sectors 2008-07-27 10:16:13 -04:00
sound ALSA: Release v1.0.17 2008-07-14 09:54:43 +02:00
video include/video/atmel_lcdc.h must #include <linux/workqueue.h> 2008-07-26 12:00:01 -07:00
xen xen: implement Xen-specific spinlocks 2008-07-16 11:15:53 +02:00
Kbuild kbuild: only one call for include/ in make headers_* 2008-07-25 22:11:44 +02:00