Magellan Linux

Annotation 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 - (hide annotations) (download)
Fri May 18 11:04:36 2007 UTC (17 years ago) by niro
File size: 7698 byte(s)
-import

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