Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 151514
b: refs/heads/master
c: 10be0b3
h: refs/heads/master
v: v3
  • Loading branch information
Wu Fengguang authored and Linus Torvalds committed Jun 17, 2009
1 parent 3d02cc9 commit c203378
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 045a2529a3513faed2d45bd82f9013b124309d94
refs/heads/master: 10be0b372cac50e2e7a477852f98bf069a97a3fa
60 changes: 60 additions & 0 deletions trunk/mm/readahead.c
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,59 @@ static unsigned long get_next_ra_size(struct file_ra_state *ra,
* it approaches max_readhead.
*/

/*
* Count contiguously cached pages from @offset-1 to @offset-@max,
* this count is a conservative estimation of
* - length of the sequential read sequence, or
* - thrashing threshold in memory tight systems
*/
static pgoff_t count_history_pages(struct address_space *mapping,
struct file_ra_state *ra,
pgoff_t offset, unsigned long max)
{
pgoff_t head;

rcu_read_lock();
head = radix_tree_prev_hole(&mapping->page_tree, offset - 1, max);
rcu_read_unlock();

return offset - 1 - head;
}

/*
* page cache context based read-ahead
*/
static int try_context_readahead(struct address_space *mapping,
struct file_ra_state *ra,
pgoff_t offset,
unsigned long req_size,
unsigned long max)
{
pgoff_t size;

size = count_history_pages(mapping, ra, offset, max);

/*
* no history pages:
* it could be a random read
*/
if (!size)
return 0;

/*
* starts from beginning of file:
* it is a strong indication of long-run stream (or whole-file-read)
*/
if (size >= offset)
size *= 2;

ra->start = offset;
ra->size = get_init_ra_size(size + req_size, max);
ra->async_size = ra->size;

return 1;
}

/*
* A minimal readahead algorithm for trivial sequential/random reads.
*/
Expand Down Expand Up @@ -394,6 +447,13 @@ ondemand_readahead(struct address_space *mapping,
if (offset - (ra->prev_pos >> PAGE_CACHE_SHIFT) <= 1UL)
goto initial_readahead;

/*
* Query the page cache and look for the traces(cached history pages)
* that a sequential stream would leave behind.
*/
if (try_context_readahead(mapping, ra, offset, req_size, max))
goto readit;

/*
* standalone, small random read
* Read as is, and do not pollute the readahead state.
Expand Down

0 comments on commit c203378

Please sign in to comment.