diff options
author | Steven Whitehouse <swhiteho@redhat.com> | 2006-03-31 15:34:58 -0500 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2006-03-31 15:34:58 -0500 |
commit | 86579dd06deecfa6ac88d5e84e4d63c397cd6f6d (patch) | |
tree | b4475d3ccde53015ad84a06e4e55e64591171b75 /mm/readahead.c | |
parent | 7ea9ea832212c4a755650f7c7cc1ff0b63292a41 (diff) | |
parent | a0f067802576d4eb4c65d40b8ee7d6ea3c81dd61 (diff) |
Merge branch 'master'
Diffstat (limited to 'mm/readahead.c')
-rw-r--r-- | mm/readahead.c | 33 |
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 | ||
56 | static 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 | |||
56 | static inline void ra_off(struct file_ra_state *ra) | 68 | static 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); |
550 | recheck: | ||
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 | ||
542 | out: | 556 | out: |
543 | return ra->prev_page + 1; | 557 | return ra->prev_page + 1; |
544 | } | 558 | } |
559 | EXPORT_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 |