Magellan Linux

Annotation of /trunk/kernel26-magellan/patches-2.6.20-r1/0022-2.6.20-mm-filesize_dependant_lru_cache_add.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 106 - (hide annotations) (download)
Sun Mar 11 16:18:20 2007 UTC (17 years, 2 months ago) by niro
File size: 6637 byte(s)
ver bump to 2.6.20-r1;
- using linux-2.6.20.2
- 2.6.20-ck1 patch set
- 8.34.8 ati-drivers
- 1.0-9755 nvidia-drivers
- 1.2.0 ipw-drivers
- squashfs-3.0 support
- vesafb-tng 1.0-rc2
- fbsplash-0.9.2-r5 for linux-2.6.20-rc6
- removed zd1211 drivers (now in upstream tree)

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