Contents of /trunk/kernel26-magellan/patches-2.6.16-r12/0026-2.6.16-sp-resume1.patch
Parent Directory | Revision Log
Revision 72 -
(show annotations)
(download)
Mon Jun 5 09:25:38 2006 UTC (18 years, 3 months ago) by niro
File size: 6222 byte(s)
Mon Jun 5 09:25:38 2006 UTC (18 years, 3 months ago) by niro
File size: 6222 byte(s)
ver bump to 2.6.16-r12: - updated to linux-2.6.16.19 - updated to ck11
1 | --- |
2 | Documentation/sysctl/vm.txt | 9 +++ |
3 | mm/swap_prefetch.c | 119 +++++++++++++++++++++++++++++--------------- |
4 | 2 files changed, 90 insertions(+), 38 deletions(-) |
5 | |
6 | Index: linux-2.6.16-ck1/mm/swap_prefetch.c |
7 | =================================================================== |
8 | --- linux-2.6.16-ck1.orig/mm/swap_prefetch.c 2006-03-20 20:46:55.000000000 +1100 |
9 | +++ linux-2.6.16-ck1/mm/swap_prefetch.c 2006-03-20 20:47:00.000000000 +1100 |
10 | @@ -27,8 +27,18 @@ |
11 | */ |
12 | #define PREFETCH_DELAY (HZ * 5) |
13 | |
14 | -/* sysctl - enable/disable swap prefetching */ |
15 | -int swap_prefetch __read_mostly = 1; |
16 | +#define PREFETCH_NORMAL (1 << 0) |
17 | +#define PREFETCH_AGGRESSIVE (1 << 1) |
18 | +/* |
19 | + * sysctl - enable/disable swap prefetching bits |
20 | + * This is composed of the bitflags PREFETCH_NORMAL and PREFETCH_AGGRESSIVE. |
21 | + * Once PREFETCH_AGGRESSIVE is set, swap prefetching will be peformed as much |
22 | + * as possible irrespective of load conditions and then the |
23 | + * PREFETCH_AGGRESSIVE bit will be unset. |
24 | + */ |
25 | +int swap_prefetch __read_mostly = PREFETCH_NORMAL; |
26 | + |
27 | +#define aggressive_prefetch (unlikely(swap_prefetch & PREFETCH_AGGRESSIVE)) |
28 | |
29 | struct swapped_root { |
30 | unsigned long busy; /* vm busy */ |
31 | @@ -291,43 +301,17 @@ static void examine_free_limits(void) |
32 | } |
33 | |
34 | /* |
35 | - * We want to be absolutely certain it's ok to start prefetching. |
36 | + * Have some hysteresis between where page reclaiming and prefetching |
37 | + * will occur to prevent ping-ponging between them. |
38 | */ |
39 | -static int prefetch_suitable(void) |
40 | +static void set_suitable_nodes(void) |
41 | { |
42 | - unsigned long limit; |
43 | struct zone *z; |
44 | - int node, ret = 0, test_pagestate = 0; |
45 | - |
46 | - /* Purposefully racy */ |
47 | - if (test_bit(0, &swapped.busy)) { |
48 | - __clear_bit(0, &swapped.busy); |
49 | - goto out; |
50 | - } |
51 | - |
52 | - /* |
53 | - * get_page_state and above_background_load are expensive so we only |
54 | - * perform them every SWAP_CLUSTER_MAX prefetched_pages. |
55 | - * We test to see if we're above_background_load as disk activity |
56 | - * even at low priority can cause interrupt induced scheduling |
57 | - * latencies. |
58 | - */ |
59 | - if (!(sp_stat.prefetched_pages % SWAP_CLUSTER_MAX)) { |
60 | - if (above_background_load()) |
61 | - goto out; |
62 | - test_pagestate = 1; |
63 | - } |
64 | |
65 | - clear_current_prefetch_free(); |
66 | - |
67 | - /* |
68 | - * Have some hysteresis between where page reclaiming and prefetching |
69 | - * will occur to prevent ping-ponging between them. |
70 | - */ |
71 | for_each_zone(z) { |
72 | struct node_stats *ns; |
73 | unsigned long free; |
74 | - int idx; |
75 | + int node, idx; |
76 | |
77 | if (!populated_zone(z)) |
78 | continue; |
79 | @@ -349,6 +333,45 @@ static int prefetch_suitable(void) |
80 | } |
81 | ns->current_free += free; |
82 | } |
83 | +} |
84 | + |
85 | +/* |
86 | + * We want to be absolutely certain it's ok to start prefetching. |
87 | + */ |
88 | +static int prefetch_suitable(void) |
89 | +{ |
90 | + unsigned long limit; |
91 | + int node, ret = 0, test_pagestate = 0; |
92 | + |
93 | + if (aggressive_prefetch) { |
94 | + clear_current_prefetch_free(); |
95 | + set_suitable_nodes(); |
96 | + if (!nodes_empty(sp_stat.prefetch_nodes)) |
97 | + ret = 1; |
98 | + goto out; |
99 | + } |
100 | + |
101 | + /* Purposefully racy */ |
102 | + if (test_bit(0, &swapped.busy)) { |
103 | + __clear_bit(0, &swapped.busy); |
104 | + goto out; |
105 | + } |
106 | + |
107 | + /* |
108 | + * get_page_state and above_background_load are expensive so we only |
109 | + * perform them every SWAP_CLUSTER_MAX prefetched_pages. |
110 | + * We test to see if we're above_background_load as disk activity |
111 | + * even at low priority can cause interrupt induced scheduling |
112 | + * latencies. |
113 | + */ |
114 | + if (!(sp_stat.prefetched_pages % SWAP_CLUSTER_MAX)) { |
115 | + if (above_background_load()) |
116 | + goto out; |
117 | + test_pagestate = 1; |
118 | + } |
119 | + |
120 | + clear_current_prefetch_free(); |
121 | + set_suitable_nodes(); |
122 | |
123 | /* |
124 | * We iterate over each node testing to see if it is suitable for |
125 | @@ -421,6 +444,17 @@ static inline struct swapped_entry *prev |
126 | struct swapped_entry, swapped_list); |
127 | } |
128 | |
129 | +static unsigned long pages_prefetched(void) |
130 | +{ |
131 | + unsigned long pages = sp_stat.prefetched_pages; |
132 | + |
133 | + if (pages) { |
134 | + lru_add_drain(); |
135 | + sp_stat.prefetched_pages = 0; |
136 | + } |
137 | + return pages; |
138 | +} |
139 | + |
140 | /* |
141 | * trickle_swap is the main function that initiates the swap prefetching. It |
142 | * first checks to see if the busy flag is set, and does not prefetch if it |
143 | @@ -438,7 +472,7 @@ static enum trickle_return trickle_swap( |
144 | * If laptop_mode is enabled don't prefetch to avoid hard drives |
145 | * doing unnecessary spin-ups |
146 | */ |
147 | - if (!swap_prefetch || laptop_mode) |
148 | + if (!swap_prefetch || (laptop_mode && !aggressive_prefetch)) |
149 | return ret; |
150 | |
151 | examine_free_limits(); |
152 | @@ -474,6 +508,14 @@ static enum trickle_return trickle_swap( |
153 | * delay attempting further prefetching. |
154 | */ |
155 | spin_unlock(&swapped.lock); |
156 | + if (aggressive_prefetch) { |
157 | + /* |
158 | + * If we're prefetching aggressively and |
159 | + * making progress then don't give up. |
160 | + */ |
161 | + if (pages_prefetched()) |
162 | + continue; |
163 | + } |
164 | break; |
165 | } |
166 | |
167 | @@ -491,14 +533,15 @@ static enum trickle_return trickle_swap( |
168 | entry = prev_swapped_entry(entry); |
169 | spin_unlock(&swapped.lock); |
170 | |
171 | - if (trickle_swap_cache_async(swp_entry, node) == TRICKLE_DELAY) |
172 | + if (trickle_swap_cache_async(swp_entry, node) == TRICKLE_DELAY && |
173 | + !aggressive_prefetch) |
174 | break; |
175 | } |
176 | |
177 | - if (sp_stat.prefetched_pages) { |
178 | - lru_add_drain(); |
179 | - sp_stat.prefetched_pages = 0; |
180 | - } |
181 | + /* Return value of pages_prefetched irrelevant here */ |
182 | + pages_prefetched(); |
183 | + if (aggressive_prefetch) |
184 | + swap_prefetch &= ~PREFETCH_AGGRESSIVE; |
185 | return ret; |
186 | } |
187 | |
188 | Index: linux-2.6.16-ck1/Documentation/sysctl/vm.txt |
189 | =================================================================== |
190 | --- linux-2.6.16-ck1.orig/Documentation/sysctl/vm.txt 2006-03-20 20:46:55.000000000 +1100 |
191 | +++ linux-2.6.16-ck1/Documentation/sysctl/vm.txt 2006-03-20 20:47:00.000000000 +1100 |
192 | @@ -188,4 +188,13 @@ memory subsystem has been extremely idle |
193 | copying back pages from swap into the swapcache and keep a copy in swap. In |
194 | practice it can take many minutes before the vm is idle enough. |
195 | |
196 | +This is value ORed together of |
197 | +1 = Normal background swap prefetching when load is light |
198 | +2 = Aggressively swap prefetch as much as possible |
199 | + |
200 | +When 2 is set, after the maximum amount possible has been prefetched, this bit |
201 | +is unset. ie Setting the value to 3 will prefetch aggressively then drop to 1. |
202 | +This is useful for doing aggressive prefetching for short periods in scripts |
203 | +such as after resuming from software suspend. |
204 | + |
205 | The default value is 1. |