Skip to content

Commit

Permalink
mm: Added filesystem dynamic read-ahead (Credits to Chad Gooldman)
Browse files Browse the repository at this point in the history
  • Loading branch information
Christopher83 authored and chil360 committed Feb 19, 2014
1 parent 6722c93 commit db2856d
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 5 deletions.
3 changes: 1 addition & 2 deletions block/blk-core.c
Expand Up @@ -500,8 +500,7 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id)
if (q->id < 0)
goto fail_q;

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";
Expand Down
20 changes: 20 additions & 0 deletions block/genhd.c
Expand Up @@ -623,6 +623,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);
Expand Down
2 changes: 1 addition & 1 deletion fs/fuse/inode.c
Expand Up @@ -877,7 +877,7 @@ static int fuse_bdi_init(struct fuse_conn *fc, struct super_block *sb)
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;

Expand Down
6 changes: 4 additions & 2 deletions include/linux/mm.h
Expand Up @@ -1425,8 +1425,10 @@ int write_one_page(struct page *page, int wait);
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 16 /* 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);
Expand Down
30 changes: 30 additions & 0 deletions mm/readahead.c
Expand Up @@ -18,6 +18,36 @@
#include <linux/pagevec.h>
#include <linux/pagemap.h>

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.
Expand Down

0 comments on commit db2856d

Please sign in to comment.