/[pkg-src]/trunk/kernel26-tinyalx/patches-2.6.21-r14/0017-2.6.21-mm-filesize_dependant_lru_cache_add.patch |
Contents of /trunk/kernel26-tinyalx/patches-2.6.21-r14/0017-2.6.21-mm-filesize_dependant_lru_cache_add.patch
Parent Directory | Revision Log
Revision 453 -
(show annotations)
(download)
Fri Jan 25 23:34:48 2008 UTC (16 years, 8 months ago) by niro
File size: 6028 byte(s)
Fri Jan 25 23:34:48 2008 UTC (16 years, 8 months ago) by niro
File size: 6028 byte(s)
-tiny-alx 2.6.21-tinyalx-r14
1 | When reading from large files through the generic file read functions into |
2 | page cache we can detect when a file is so large that it is unlikely to be |
3 | fully cached in ram. |
4 | |
5 | Add a tunable /proc/sys/vm/tail_largefiles that puts them at the tail of the |
6 | inactive list to minimise their harm on present mapped pages and pagecache |
7 | and enable it by default. |
8 | |
9 | Signed-off-by: Con Kolivas <kernel@kolivas.org> |
10 | |
11 | --- |
12 | Documentation/filesystems/proc.txt | 8 +++++ |
13 | Documentation/sysctl/vm.txt | 2 - |
14 | kernel/sysctl.c | 9 ++++++ |
15 | mm/filemap.c | 53 +++++++++++++++++++++++++++++++++++-- |
16 | mm/swap.c | 3 -- |
17 | 5 files changed, 70 insertions(+), 5 deletions(-) |
18 | |
19 | Index: linux-2.6.21-ck2/mm/filemap.c |
20 | =================================================================== |
21 | --- linux-2.6.21-ck2.orig/mm/filemap.c 2007-05-14 19:49:18.000000000 +1000 |
22 | +++ linux-2.6.21-ck2/mm/filemap.c 2007-05-14 19:49:56.000000000 +1000 |
23 | @@ -466,6 +466,16 @@ int add_to_page_cache_lru(struct page *p |
24 | return ret; |
25 | } |
26 | |
27 | +int add_to_page_cache_lru_tail(struct page *page, |
28 | + struct address_space *mapping, pgoff_t offset, gfp_t gfp_mask) |
29 | +{ |
30 | + int ret = add_to_page_cache(page, mapping, offset, gfp_mask); |
31 | + |
32 | + if (ret == 0) |
33 | + lru_cache_add_tail(page); |
34 | + return ret; |
35 | +} |
36 | + |
37 | #ifdef CONFIG_NUMA |
38 | struct page *__page_cache_alloc(gfp_t gfp) |
39 | { |
40 | @@ -836,6 +846,34 @@ static void shrink_readahead_size_eio(st |
41 | ra->ra_pages /= 4; |
42 | } |
43 | |
44 | +/* |
45 | + * Sysctl which determines whether we should read from large files to the |
46 | + * tail of the inactive lru list. |
47 | + */ |
48 | +int vm_tail_largefiles __read_mostly = 1; |
49 | + |
50 | +static inline int nr_mapped(void) |
51 | +{ |
52 | + return global_page_state(NR_FILE_MAPPED) + |
53 | + global_page_state(NR_ANON_PAGES); |
54 | +} |
55 | + |
56 | +/* |
57 | + * This examines how large in pages a file size is and returns 1 if it is |
58 | + * more than half the unmapped ram. Avoid doing read_page_state which is |
59 | + * expensive unless we already know it is likely to be large enough. |
60 | + */ |
61 | +static int large_isize(unsigned long nr_pages) |
62 | +{ |
63 | + if (nr_pages * 6 > vm_total_pages) { |
64 | + unsigned long unmapped_ram = vm_total_pages - nr_mapped(); |
65 | + |
66 | + if (nr_pages * 2 > unmapped_ram) |
67 | + return 1; |
68 | + } |
69 | + return 0; |
70 | +} |
71 | + |
72 | /** |
73 | * do_generic_mapping_read - generic file read routine |
74 | * @mapping: address_space to be read |
75 | @@ -1044,8 +1082,19 @@ no_cached_page: |
76 | goto out; |
77 | } |
78 | } |
79 | - error = add_to_page_cache_lru(cached_page, mapping, |
80 | - index, GFP_KERNEL); |
81 | + |
82 | + /* |
83 | + * If we know the file is large we add the pages read to the |
84 | + * end of the lru as we're unlikely to be able to cache the |
85 | + * whole file in ram so make those pages the first to be |
86 | + * dropped if not referenced soon. |
87 | + */ |
88 | + if (vm_tail_largefiles && large_isize(end_index)) |
89 | + error = add_to_page_cache_lru_tail(cached_page, |
90 | + mapping, index, GFP_KERNEL); |
91 | + else |
92 | + error = add_to_page_cache_lru(cached_page, mapping, |
93 | + index, GFP_KERNEL); |
94 | if (error) { |
95 | if (error == -EEXIST) |
96 | goto find_page; |
97 | Index: linux-2.6.21-ck2/mm/swap.c |
98 | =================================================================== |
99 | --- linux-2.6.21-ck2.orig/mm/swap.c 2007-05-14 19:49:55.000000000 +1000 |
100 | +++ linux-2.6.21-ck2/mm/swap.c 2007-05-14 19:49:56.000000000 +1000 |
101 | @@ -434,8 +434,7 @@ void __pagevec_lru_add_active(struct pag |
102 | |
103 | /* |
104 | * Function used uniquely to put pages back to the lru at the end of the |
105 | - * inactive list to preserve the lru order. Currently only used by swap |
106 | - * prefetch. |
107 | + * inactive list to preserve the lru order. |
108 | */ |
109 | void fastcall lru_cache_add_tail(struct page *page) |
110 | { |
111 | Index: linux-2.6.21-ck2/kernel/sysctl.c |
112 | =================================================================== |
113 | --- linux-2.6.21-ck2.orig/kernel/sysctl.c 2007-05-14 19:49:55.000000000 +1000 |
114 | +++ linux-2.6.21-ck2/kernel/sysctl.c 2007-05-14 19:49:56.000000000 +1000 |
115 | @@ -71,6 +71,7 @@ extern int suid_dumpable; |
116 | extern char core_pattern[]; |
117 | extern int pid_max; |
118 | extern int min_free_kbytes; |
119 | +extern int vm_tail_largefiles; |
120 | extern int printk_ratelimit_jiffies; |
121 | extern int printk_ratelimit_burst; |
122 | extern int pid_max_min, pid_max_max; |
123 | @@ -759,6 +760,14 @@ static ctl_table vm_table[] = { |
124 | .mode = 0644, |
125 | .proc_handler = &proc_dointvec, |
126 | }, |
127 | + { |
128 | + .ctl_name = CTL_UNNUMBERED, |
129 | + .procname = "tail_largefiles", |
130 | + .data = &vm_tail_largefiles, |
131 | + .maxlen = sizeof(int), |
132 | + .mode = 0644, |
133 | + .proc_handler = &proc_dointvec, |
134 | + }, |
135 | #ifdef CONFIG_HUGETLB_PAGE |
136 | { |
137 | .ctl_name = VM_HUGETLB_PAGES, |
138 | Index: linux-2.6.21-ck2/Documentation/filesystems/proc.txt |
139 | =================================================================== |
140 | --- linux-2.6.21-ck2.orig/Documentation/filesystems/proc.txt 2007-05-14 19:49:18.000000000 +1000 |
141 | +++ linux-2.6.21-ck2/Documentation/filesystems/proc.txt 2007-05-14 19:49:56.000000000 +1000 |
142 | @@ -1325,6 +1325,14 @@ To free pagecache, dentries and inodes: |
143 | As this is a non-destructive operation and dirty objects are not freeable, the |
144 | user should run `sync' first. |
145 | |
146 | +tail_largefiles |
147 | +--------------- |
148 | + |
149 | +When enabled reads from large files to the tail end of the inactive lru list. |
150 | +This means that any cache from reading large files is dropped very quickly, |
151 | +preventing loss of mapped ram and useful pagecache when large files are read. |
152 | +This does, however, make caching less effective when working with large files. |
153 | + |
154 | |
155 | 2.5 /proc/sys/dev - Device specific parameters |
156 | ---------------------------------------------- |
157 | Index: linux-2.6.21-ck2/Documentation/sysctl/vm.txt |
158 | =================================================================== |
159 | --- linux-2.6.21-ck2.orig/Documentation/sysctl/vm.txt 2007-05-14 19:49:55.000000000 +1000 |
160 | +++ linux-2.6.21-ck2/Documentation/sysctl/vm.txt 2007-05-14 19:49:56.000000000 +1000 |
161 | @@ -39,7 +39,7 @@ Currently, these files are in /proc/sys/ |
162 | |
163 | dirty_ratio, dirty_background_ratio, dirty_expire_centisecs, |
164 | dirty_writeback_centisecs, vfs_cache_pressure, laptop_mode, |
165 | -block_dump, swap_token_timeout, drop-caches: |
166 | +block_dump, swap_token_timeout, drop-caches, tail_largefiles: |
167 | |
168 | See Documentation/filesystems/proc.txt |
169 |