/[pkg-src]/trunk/kernel26-alx/patches-2.6.20-r6/0022-2.6.20-mm-filesize_dependant_lru_cache_add.patch |
Contents of /trunk/kernel26-alx/patches-2.6.20-r6/0022-2.6.20-mm-filesize_dependant_lru_cache_add.patch
Parent Directory | Revision Log
Revision 1175 -
(show annotations)
(download)
Thu Oct 14 12:15:46 2010 UTC (13 years, 11 months ago) by niro
File size: 6637 byte(s)
Thu Oct 14 12:15:46 2010 UTC (13 years, 11 months ago) by niro
File size: 6637 byte(s)
-2.6.20-alx-r6 new magellan 0.5.2 kernel
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 | include/linux/sysctl.h | 1 |
15 | kernel/sysctl.c | 9 ++++++ |
16 | mm/filemap.c | 53 +++++++++++++++++++++++++++++++++++-- |
17 | mm/swap.c | 3 -- |
18 | 6 files changed, 71 insertions(+), 5 deletions(-) |
19 | |
20 | Index: linux-2.6.20-ck1/mm/filemap.c |
21 | =================================================================== |
22 | --- linux-2.6.20-ck1.orig/mm/filemap.c 2007-02-05 22:52:04.000000000 +1100 |
23 | +++ linux-2.6.20-ck1/mm/filemap.c 2007-02-16 19:01:34.000000000 +1100 |
24 | @@ -466,6 +466,16 @@ int add_to_page_cache_lru(struct page *p |
25 | return ret; |
26 | } |
27 | |
28 | +int add_to_page_cache_lru_tail(struct page *page, |
29 | + struct address_space *mapping, pgoff_t offset, gfp_t gfp_mask) |
30 | +{ |
31 | + int ret = add_to_page_cache(page, mapping, offset, gfp_mask); |
32 | + |
33 | + if (ret == 0) |
34 | + lru_cache_add_tail(page); |
35 | + return ret; |
36 | +} |
37 | + |
38 | #ifdef CONFIG_NUMA |
39 | struct page *__page_cache_alloc(gfp_t gfp) |
40 | { |
41 | @@ -856,6 +866,34 @@ static void shrink_readahead_size_eio(st |
42 | ra->ra_pages /= 4; |
43 | } |
44 | |
45 | +/* |
46 | + * Sysctl which determines whether we should read from large files to the |
47 | + * tail of the inactive lru list. |
48 | + */ |
49 | +int vm_tail_largefiles __read_mostly = 1; |
50 | + |
51 | +static inline int nr_mapped(void) |
52 | +{ |
53 | + return global_page_state(NR_FILE_MAPPED) + |
54 | + global_page_state(NR_ANON_PAGES); |
55 | +} |
56 | + |
57 | +/* |
58 | + * This examines how large in pages a file size is and returns 1 if it is |
59 | + * more than half the unmapped ram. Avoid doing read_page_state which is |
60 | + * expensive unless we already know it is likely to be large enough. |
61 | + */ |
62 | +static int large_isize(unsigned long nr_pages) |
63 | +{ |
64 | + if (nr_pages * 6 > vm_total_pages) { |
65 | + unsigned long unmapped_ram = vm_total_pages - nr_mapped(); |
66 | + |
67 | + if (nr_pages * 2 > unmapped_ram) |
68 | + return 1; |
69 | + } |
70 | + return 0; |
71 | +} |
72 | + |
73 | /** |
74 | * do_generic_mapping_read - generic file read routine |
75 | * @mapping: address_space to be read |
76 | @@ -1064,8 +1102,19 @@ no_cached_page: |
77 | goto out; |
78 | } |
79 | } |
80 | - error = add_to_page_cache_lru(cached_page, mapping, |
81 | - index, GFP_KERNEL); |
82 | + |
83 | + /* |
84 | + * If we know the file is large we add the pages read to the |
85 | + * end of the lru as we're unlikely to be able to cache the |
86 | + * whole file in ram so make those pages the first to be |
87 | + * dropped if not referenced soon. |
88 | + */ |
89 | + if (vm_tail_largefiles && large_isize(end_index)) |
90 | + error = add_to_page_cache_lru_tail(cached_page, |
91 | + mapping, index, GFP_KERNEL); |
92 | + else |
93 | + error = add_to_page_cache_lru(cached_page, mapping, |
94 | + index, GFP_KERNEL); |
95 | if (error) { |
96 | if (error == -EEXIST) |
97 | goto find_page; |
98 | Index: linux-2.6.20-ck1/mm/swap.c |
99 | =================================================================== |
100 | --- linux-2.6.20-ck1.orig/mm/swap.c 2007-02-16 19:01:33.000000000 +1100 |
101 | +++ linux-2.6.20-ck1/mm/swap.c 2007-02-16 19:01:34.000000000 +1100 |
102 | @@ -434,8 +434,7 @@ void __pagevec_lru_add_active(struct pag |
103 | |
104 | /* |
105 | * Function used uniquely to put pages back to the lru at the end of the |
106 | - * inactive list to preserve the lru order. Currently only used by swap |
107 | - * prefetch. |
108 | + * inactive list to preserve the lru order. |
109 | */ |
110 | void fastcall lru_cache_add_tail(struct page *page) |
111 | { |
112 | Index: linux-2.6.20-ck1/kernel/sysctl.c |
113 | =================================================================== |
114 | --- linux-2.6.20-ck1.orig/kernel/sysctl.c 2007-02-16 19:01:33.000000000 +1100 |
115 | +++ linux-2.6.20-ck1/kernel/sysctl.c 2007-02-16 19:01:34.000000000 +1100 |
116 | @@ -77,6 +77,7 @@ extern int pid_max_min, pid_max_max; |
117 | extern int sysctl_drop_caches; |
118 | extern int percpu_pagelist_fraction; |
119 | extern int compat_log; |
120 | +extern int vm_tail_largefiles; |
121 | |
122 | /* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */ |
123 | static int maxolduid = 65535; |
124 | @@ -918,6 +919,14 @@ static ctl_table vm_table[] = { |
125 | .mode = 0644, |
126 | .proc_handler = &proc_dointvec, |
127 | }, |
128 | + { |
129 | + .ctl_name = VM_TAIL_LARGEFILES, |
130 | + .procname = "tail_largefiles", |
131 | + .data = &vm_tail_largefiles, |
132 | + .maxlen = sizeof(int), |
133 | + .mode = 0644, |
134 | + .proc_handler = &proc_dointvec, |
135 | + }, |
136 | #ifdef CONFIG_HUGETLB_PAGE |
137 | { |
138 | .ctl_name = VM_HUGETLB_PAGES, |
139 | Index: linux-2.6.20-ck1/Documentation/filesystems/proc.txt |
140 | =================================================================== |
141 | --- linux-2.6.20-ck1.orig/Documentation/filesystems/proc.txt 2007-02-05 22:51:59.000000000 +1100 |
142 | +++ linux-2.6.20-ck1/Documentation/filesystems/proc.txt 2007-02-16 19:01:34.000000000 +1100 |
143 | @@ -1324,6 +1324,14 @@ To free pagecache, dentries and inodes: |
144 | As this is a non-destructive operation and dirty objects are not freeable, the |
145 | user should run `sync' first. |
146 | |
147 | +tail_largefiles |
148 | +--------------- |
149 | + |
150 | +When enabled reads from large files to the tail end of the inactive lru list. |
151 | +This means that any cache from reading large files is dropped very quickly, |
152 | +preventing loss of mapped ram and useful pagecache when large files are read. |
153 | +This does, however, make caching less effective when working with large files. |
154 | + |
155 | |
156 | 2.5 /proc/sys/dev - Device specific parameters |
157 | ---------------------------------------------- |
158 | Index: linux-2.6.20-ck1/Documentation/sysctl/vm.txt |
159 | =================================================================== |
160 | --- linux-2.6.20-ck1.orig/Documentation/sysctl/vm.txt 2007-02-16 19:01:33.000000000 +1100 |
161 | +++ linux-2.6.20-ck1/Documentation/sysctl/vm.txt 2007-02-16 19:01:34.000000000 +1100 |
162 | @@ -39,7 +39,7 @@ Currently, these files are in /proc/sys/ |
163 | |
164 | dirty_ratio, dirty_background_ratio, dirty_expire_centisecs, |
165 | dirty_writeback_centisecs, vfs_cache_pressure, laptop_mode, |
166 | -block_dump, swap_token_timeout, drop-caches: |
167 | +block_dump, swap_token_timeout, drop-caches, tail_largefiles: |
168 | |
169 | See Documentation/filesystems/proc.txt |
170 | |
171 | Index: linux-2.6.20-ck1/include/linux/sysctl.h |
172 | =================================================================== |
173 | --- linux-2.6.20-ck1.orig/include/linux/sysctl.h 2007-02-16 19:01:33.000000000 +1100 |
174 | +++ linux-2.6.20-ck1/include/linux/sysctl.h 2007-02-16 19:01:34.000000000 +1100 |
175 | @@ -204,6 +204,7 @@ enum |
176 | VM_MIN_SLAB=35, /* Percent pages ignored by zone reclaim */ |
177 | VM_SWAP_PREFETCH=36, /* swap prefetch */ |
178 | VM_HARDMAPLIMIT=37, /* Make mapped a hard limit */ |
179 | + VM_TAIL_LARGEFILES=38, /* Read large files to lru tail */ |
180 | }; |
181 | |
182 |