aboutsummaryrefslogtreecommitdiffstats
path: root/mm/readahead.c
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2006-03-31 15:34:58 -0500
committerSteven Whitehouse <swhiteho@redhat.com>2006-03-31 15:34:58 -0500
commit86579dd06deecfa6ac88d5e84e4d63c397cd6f6d (patch)
treeb4475d3ccde53015ad84a06e4e55e64591171b75 /mm/readahead.c
parent7ea9ea832212c4a755650f7c7cc1ff0b63292a41 (diff)
parenta0f067802576d4eb4c65d40b8ee7d6ea3c81dd61 (diff)
Merge branch 'master'
Diffstat (limited to 'mm/readahead.c')
-rw-r--r--mm/readahead.c33
1 files changed, 24 insertions, 9 deletions
diff --git a/mm/readahead.c b/mm/readahead.c
index 9f0b98227b41..ba7db816f4c8 100644
--- a/mm/readahead.c
+++ b/mm/readahead.c
@@ -53,13 +53,24 @@ static inline unsigned long get_min_readahead(struct file_ra_state *ra)
53 return (VM_MIN_READAHEAD * 1024) / PAGE_CACHE_SIZE; 53 return (VM_MIN_READAHEAD * 1024) / PAGE_CACHE_SIZE;
54} 54}
55 55
56static inline void reset_ahead_window(struct file_ra_state *ra)
57{
58 /*
59 * ... but preserve ahead_start + ahead_size value,
60 * see 'recheck:' label in page_cache_readahead().
61 * Note: We never use ->ahead_size as rvalue without
62 * checking ->ahead_start != 0 first.
63 */
64 ra->ahead_size += ra->ahead_start;
65 ra->ahead_start = 0;
66}
67
56static inline void ra_off(struct file_ra_state *ra) 68static inline void ra_off(struct file_ra_state *ra)
57{ 69{
58 ra->start = 0; 70 ra->start = 0;
59 ra->flags = 0; 71 ra->flags = 0;
60 ra->size = 0; 72 ra->size = 0;
61 ra->ahead_start = 0; 73 reset_ahead_window(ra);
62 ra->ahead_size = 0;
63 return; 74 return;
64} 75}
65 76
@@ -73,10 +84,10 @@ static unsigned long get_init_ra_size(unsigned long size, unsigned long max)
73{ 84{
74 unsigned long newsize = roundup_pow_of_two(size); 85 unsigned long newsize = roundup_pow_of_two(size);
75 86
76 if (newsize <= max / 64) 87 if (newsize <= max / 32)
77 newsize = newsize * newsize; 88 newsize = newsize * 4;
78 else if (newsize <= max / 4) 89 else if (newsize <= max / 4)
79 newsize = max / 4; 90 newsize = newsize * 2;
80 else 91 else
81 newsize = max; 92 newsize = max;
82 return newsize; 93 return newsize;
@@ -427,8 +438,7 @@ static int make_ahead_window(struct address_space *mapping, struct file *filp,
427 * congestion. The ahead window will any way be closed 438 * congestion. The ahead window will any way be closed
428 * in case we failed due to excessive page cache hits. 439 * in case we failed due to excessive page cache hits.
429 */ 440 */
430 ra->ahead_start = 0; 441 reset_ahead_window(ra);
431 ra->ahead_size = 0;
432 } 442 }
433 443
434 return ret; 444 return ret;
@@ -521,11 +531,11 @@ page_cache_readahead(struct address_space *mapping, struct file_ra_state *ra,
521 * If we get here we are doing sequential IO and this was not the first 531 * If we get here we are doing sequential IO and this was not the first
522 * occurence (ie we have an existing window) 532 * occurence (ie we have an existing window)
523 */ 533 */
524
525 if (ra->ahead_start == 0) { /* no ahead window yet */ 534 if (ra->ahead_start == 0) { /* no ahead window yet */
526 if (!make_ahead_window(mapping, filp, ra, 0)) 535 if (!make_ahead_window(mapping, filp, ra, 0))
527 goto out; 536 goto recheck;
528 } 537 }
538
529 /* 539 /*
530 * Already have an ahead window, check if we crossed into it. 540 * Already have an ahead window, check if we crossed into it.
531 * If so, shift windows and issue a new ahead window. 541 * If so, shift windows and issue a new ahead window.
@@ -537,11 +547,16 @@ page_cache_readahead(struct address_space *mapping, struct file_ra_state *ra,
537 ra->start = ra->ahead_start; 547 ra->start = ra->ahead_start;
538 ra->size = ra->ahead_size; 548 ra->size = ra->ahead_size;
539 make_ahead_window(mapping, filp, ra, 0); 549 make_ahead_window(mapping, filp, ra, 0);
550recheck:
551 /* prev_page shouldn't overrun the ahead window */
552 ra->prev_page = min(ra->prev_page,
553 ra->ahead_start + ra->ahead_size - 1);
540 } 554 }
541 555
542out: 556out:
543 return ra->prev_page + 1; 557 return ra->prev_page + 1;
544} 558}
559EXPORT_SYMBOL_GPL(page_cache_readahead);
545 560
546/* 561/*
547 * handle_ra_miss() is called when it is known that a page which should have 562 * handle_ra_miss() is called when it is known that a page which should have