From: Chad Goodman Date: Sun, 25 Nov 2012 09:36:47 +0000 (-0800) Subject: FILESYSTEM: dynamic read-ahead X-Git-Url: https://www.ziggy471.com/git/gitweb.cgi?p=ziggy471-sgn2-jb.git;a=commitdiff;h=5bc909a3fe11cddf9050e9700d380573a021ad3a FILESYSTEM: dynamic read-ahead Signed-off-by: Ziggy --- --- a/block/blk-core.c +++ b/block/blk-core.c @@ -413,8 +413,7 @@ struct request_queue *blk_alloc_queue_no if (!q) return NULL; - q->backing_dev_info.ra_pages = - (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE; + q->backing_dev_info.ra_pages = max_readahead_pages; q->backing_dev_info.state = 0; q->backing_dev_info.capabilities = BDI_CAP_MAP_COPY; q->backing_dev_info.name = "block"; --- a/block/genhd.c +++ b/block/genhd.c @@ -624,6 +624,26 @@ void add_disk(struct gendisk *disk) "bdi"); WARN_ON(retval); + /* + * Limit default readahead size for small devices. + * disk size readahead size + * 1M 8k + * 4M 16k + * 16M 32k + * 64M 64k + * 256M 128k + * 1G 256k + * 4G 512k + * 16G 1024k + * 64G 2048k + * 256G 4096k + */ + if (get_capacity(disk)) { + unsigned long size = get_capacity(disk) >> 9; + size = 1UL << (ilog2(size) / 2); + bdi->ra_pages = min(bdi->ra_pages, size); + } + disk_add_events(disk); } EXPORT_SYMBOL(add_disk); --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -879,7 +879,7 @@ static int fuse_bdi_init(struct fuse_con int err; fc->bdi.name = "fuse"; - fc->bdi.ra_pages = (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE; + fc->bdi.ra_pages = max_readahead_pages; /* fuse does it's own writeback accounting */ fc->bdi.capabilities = BDI_CAP_NO_ACCT_WB; --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1509,8 +1509,10 @@ int write_one_page(struct page *page, in void task_dirty_inc(struct task_struct *tsk); /* readahead.c */ -#define VM_MAX_READAHEAD 128 /* kbytes */ -#define VM_MIN_READAHEAD 16 /* kbytes (includes current page) */ +#define VM_MAX_READAHEAD 2048 /* kbytes */ +#define VM_MIN_READAHEAD 64 /* kbytes (includes current page) */ + +extern unsigned long max_readahead_pages; int force_page_cache_readahead(struct address_space *mapping, struct file *filp, pgoff_t offset, unsigned long nr_to_read); --- a/mm/readahead.c +++ b/mm/readahead.c @@ -18,6 +18,32 @@ #include #include +unsigned long max_readahead_pages = VM_MAX_READAHEAD * 1024 / PAGE_CACHE_SIZE; + +static int __init readahead(char *str) +{ + unsigned long bytes; + + if (!str) + return -EINVAL; + bytes = memparse(str, &str); + if (*str != '\0') + return -EINVAL; + + if (bytes) { + if (bytes < PAGE_CACHE_SIZE) /* missed 'k'/'m' suffixes? */ + return -EINVAL; + if (bytes > 256 << 20) /* limit to 256MB */ + bytes = 256 << 20; + } + + max_readahead_pages = bytes / PAGE_CACHE_SIZE; + default_backing_dev_info.ra_pages = max_readahead_pages; + return 0; +} + +early_param("readahead", readahead); + /* * Initialise a struct file's readahead state. Assumes that the caller has * memset *ra to zero.