Magellan Linux

Contents of /trunk/kernel26-alx/patches-2.6.17-r6/0027-2.6.17-mm-filesize_dependant_lru_cache_add.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 199 - (show annotations) (download)
Fri May 18 11:04:36 2007 UTC (16 years, 11 months ago) by niro
File size: 7698 byte(s)
-import

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 include/linux/writeback.h | 2 +
16 kernel/sysctl.c | 9 +++++++
17 mm/filemap.c | 47 +++++++++++++++++++++++++++++++++++--
18 mm/page-writeback.c | 2 -
19 mm/swap.c | 3 --
20 8 files changed, 68 insertions(+), 6 deletions(-)
21
22 Index: linux-ck-dev/include/linux/writeback.h
23 ===================================================================
24 --- linux-ck-dev.orig/include/linux/writeback.h 2006-06-18 15:20:10.000000000 +1000
25 +++ linux-ck-dev/include/linux/writeback.h 2006-06-18 15:25:25.000000000 +1000
26 @@ -85,6 +85,8 @@ void laptop_io_completion(void);
27 void laptop_sync_completion(void);
28 void throttle_vm_writeout(void);
29
30 +extern long total_pages;
31 +
32 /* These are exported to sysctl. */
33 extern int dirty_background_ratio;
34 extern int vm_dirty_ratio;
35 Index: linux-ck-dev/mm/filemap.c
36 ===================================================================
37 --- linux-ck-dev.orig/mm/filemap.c 2006-06-18 15:20:10.000000000 +1000
38 +++ linux-ck-dev/mm/filemap.c 2006-06-18 15:25:25.000000000 +1000
39 @@ -434,6 +434,16 @@ int add_to_page_cache_lru(struct page *p
40 return ret;
41 }
42
43 +int add_to_page_cache_lru_tail(struct page *page,
44 + struct address_space *mapping, pgoff_t offset, gfp_t gfp_mask)
45 +{
46 + int ret = add_to_page_cache(page, mapping, offset, gfp_mask);
47 +
48 + if (ret == 0)
49 + lru_cache_add_tail(page);
50 + return ret;
51 +}
52 +
53 #ifdef CONFIG_NUMA
54 struct page *page_cache_alloc(struct address_space *x)
55 {
56 @@ -783,6 +793,28 @@ grab_cache_page_nowait(struct address_sp
57 EXPORT_SYMBOL(grab_cache_page_nowait);
58
59 /*
60 + * Sysctl which determines whether we should read from large files to the
61 + * tail of the inactive lru list.
62 + */
63 +int vm_tail_largefiles __read_mostly = 1;
64 +
65 +/*
66 + * This examines how large in pages a file size is and returns 1 if it is
67 + * more than half the unmapped ram. Avoid doing read_page_state which is
68 + * expensive unless we already know it is likely to be large enough.
69 + */
70 +static int large_isize(unsigned long nr_pages)
71 +{
72 + if (nr_pages * 6 > total_pages) {
73 + unsigned long unmapped_ram = total_pages - read_page_state(nr_mapped);
74 +
75 + if (nr_pages * 2 > unmapped_ram)
76 + return 1;
77 + }
78 + return 0;
79 +}
80 +
81 +/*
82 * This is a generic file read routine, and uses the
83 * mapping->a_ops->readpage() function for the actual low-level
84 * stuff.
85 @@ -982,8 +1014,19 @@ no_cached_page:
86 goto out;
87 }
88 }
89 - error = add_to_page_cache_lru(cached_page, mapping,
90 - index, GFP_KERNEL);
91 +
92 + /*
93 + * If we know the file is large we add the pages read to the
94 + * end of the lru as we're unlikely to be able to cache the
95 + * whole file in ram so make those pages the first to be
96 + * dropped if not referenced soon.
97 + */
98 + if (vm_tail_largefiles && large_isize(end_index))
99 + error = add_to_page_cache_lru_tail(cached_page,
100 + mapping, index, GFP_KERNEL);
101 + else
102 + error = add_to_page_cache_lru(cached_page, mapping,
103 + index, GFP_KERNEL);
104 if (error) {
105 if (error == -EEXIST)
106 goto find_page;
107 Index: linux-ck-dev/mm/page-writeback.c
108 ===================================================================
109 --- linux-ck-dev.orig/mm/page-writeback.c 2006-06-18 15:25:22.000000000 +1000
110 +++ linux-ck-dev/mm/page-writeback.c 2006-06-18 15:25:25.000000000 +1000
111 @@ -45,7 +45,7 @@
112 */
113 static long ratelimit_pages = 32;
114
115 -static long total_pages; /* The total number of pages in the machine. */
116 +long total_pages __read_mostly; /* The total number of pages in the machine. */
117 static int dirty_exceeded __cacheline_aligned_in_smp; /* Dirty mem may be over limit */
118
119 /*
120 Index: linux-ck-dev/mm/swap.c
121 ===================================================================
122 --- linux-ck-dev.orig/mm/swap.c 2006-06-18 15:24:48.000000000 +1000
123 +++ linux-ck-dev/mm/swap.c 2006-06-18 15:25:25.000000000 +1000
124 @@ -416,8 +416,7 @@ void __pagevec_lru_add_active(struct pag
125
126 /*
127 * Function used uniquely to put pages back to the lru at the end of the
128 - * inactive list to preserve the lru order. Currently only used by swap
129 - * prefetch.
130 + * inactive list to preserve the lru order.
131 */
132 void fastcall lru_cache_add_tail(struct page *page)
133 {
134 Index: linux-ck-dev/include/linux/sysctl.h
135 ===================================================================
136 --- linux-ck-dev.orig/include/linux/sysctl.h 2006-06-18 15:24:58.000000000 +1000
137 +++ linux-ck-dev/include/linux/sysctl.h 2006-06-18 15:25:25.000000000 +1000
138 @@ -191,6 +191,7 @@ enum
139 VM_ZONE_RECLAIM_INTERVAL=32, /* time period to wait after reclaim failure */
140 VM_SWAP_PREFETCH=33, /* swap prefetch */
141 VM_HARDMAPLIMIT=34, /* Make mapped a hard limit */
142 + VM_TAIL_LARGEFILES=35, /* Read large files to lru tail */
143 };
144
145
146 Index: linux-ck-dev/kernel/sysctl.c
147 ===================================================================
148 --- linux-ck-dev.orig/kernel/sysctl.c 2006-06-18 15:24:58.000000000 +1000
149 +++ linux-ck-dev/kernel/sysctl.c 2006-06-18 15:25:25.000000000 +1000
150 @@ -73,6 +73,7 @@ extern int printk_ratelimit_burst;
151 extern int pid_max_min, pid_max_max;
152 extern int sysctl_drop_caches;
153 extern int percpu_pagelist_fraction;
154 +extern int vm_tail_largefiles;
155
156 #if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86)
157 int unknown_nmi_panic;
158 @@ -809,6 +810,14 @@ static ctl_table vm_table[] = {
159 .mode = 0644,
160 .proc_handler = &proc_dointvec,
161 },
162 + {
163 + .ctl_name = VM_TAIL_LARGEFILES,
164 + .procname = "tail_largefiles",
165 + .data = &vm_tail_largefiles,
166 + .maxlen = sizeof(int),
167 + .mode = 0644,
168 + .proc_handler = &proc_dointvec,
169 + },
170 #ifdef CONFIG_HUGETLB_PAGE
171 {
172 .ctl_name = VM_HUGETLB_PAGES,
173 Index: linux-ck-dev/Documentation/filesystems/proc.txt
174 ===================================================================
175 --- linux-ck-dev.orig/Documentation/filesystems/proc.txt 2006-06-18 15:20:10.000000000 +1000
176 +++ linux-ck-dev/Documentation/filesystems/proc.txt 2006-06-18 15:25:25.000000000 +1000
177 @@ -1318,6 +1318,14 @@ To free pagecache, dentries and inodes:
178 As this is a non-destructive operation and dirty objects are not freeable, the
179 user should run `sync' first.
180
181 +tail_largefiles
182 +---------------
183 +
184 +When enabled reads from large files to the tail end of the inactive lru list.
185 +This means that any cache from reading large files is dropped very quickly,
186 +preventing loss of mapped ram and useful pagecache when large files are read.
187 +This does, however, make caching less effective when working with large files.
188 +
189
190 2.5 /proc/sys/dev - Device specific parameters
191 ----------------------------------------------
192 Index: linux-ck-dev/Documentation/sysctl/vm.txt
193 ===================================================================
194 --- linux-ck-dev.orig/Documentation/sysctl/vm.txt 2006-06-18 15:24:58.000000000 +1000
195 +++ linux-ck-dev/Documentation/sysctl/vm.txt 2006-06-18 15:25:25.000000000 +1000
196 @@ -37,7 +37,7 @@ Currently, these files are in /proc/sys/
197
198 dirty_ratio, dirty_background_ratio, dirty_expire_centisecs,
199 dirty_writeback_centisecs, vfs_cache_pressure, laptop_mode,
200 -block_dump, swap_token_timeout, drop-caches:
201 +block_dump, swap_token_timeout, drop-caches, tail_largefiles:
202
203 See Documentation/filesystems/proc.txt
204