Magellan Linux

Annotation of /trunk/kernel26-alx/patches-2.6.21-r14/0017-2.6.21-mm-filesize_dependant_lru_cache_add.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 447 - (hide annotations) (download)
Tue Jan 22 17:55:52 2008 UTC (16 years, 3 months ago) by niro
File size: 6028 byte(s)
-2.6.21-alx-r14 - fixed some natsemi errors on wys terminals

1 niro 447 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