diff options
author | KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> | 2008-10-18 23:26:19 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-20 11:50:25 -0400 |
commit | f04e9ebbe4909f9a41efd55149bc353299f4e83b (patch) | |
tree | 4ff31c7f918edafe7d4e4dd0e926b6ac545c7897 | |
parent | b69408e88bd86b98feb7b9a38fd865e1ddb29827 (diff) |
swap: use an array for the LRU pagevecs
Turn the pagevecs into an array just like the LRUs. This significantly
cleans up the source code and reduces the size of the kernel by about 13kB
after all the LRU lists have been created further down in the split VM
patch series.
Signed-off-by: Rik van Riel <riel@redhat.com>
Signed-off-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | include/linux/pagevec.h | 13 | ||||
-rw-r--r-- | include/linux/swap.h | 18 | ||||
-rw-r--r-- | mm/migrate.c | 11 | ||||
-rw-r--r-- | mm/swap.c | 79 |
4 files changed, 55 insertions, 66 deletions
diff --git a/include/linux/pagevec.h b/include/linux/pagevec.h index 8eb7fa76c1d0..6b8f11bcc948 100644 --- a/include/linux/pagevec.h +++ b/include/linux/pagevec.h | |||
@@ -23,8 +23,7 @@ struct pagevec { | |||
23 | void __pagevec_release(struct pagevec *pvec); | 23 | void __pagevec_release(struct pagevec *pvec); |
24 | void __pagevec_release_nonlru(struct pagevec *pvec); | 24 | void __pagevec_release_nonlru(struct pagevec *pvec); |
25 | void __pagevec_free(struct pagevec *pvec); | 25 | void __pagevec_free(struct pagevec *pvec); |
26 | void __pagevec_lru_add(struct pagevec *pvec); | 26 | void ____pagevec_lru_add(struct pagevec *pvec, enum lru_list lru); |
27 | void __pagevec_lru_add_active(struct pagevec *pvec); | ||
28 | void pagevec_strip(struct pagevec *pvec); | 27 | void pagevec_strip(struct pagevec *pvec); |
29 | unsigned pagevec_lookup(struct pagevec *pvec, struct address_space *mapping, | 28 | unsigned pagevec_lookup(struct pagevec *pvec, struct address_space *mapping, |
30 | pgoff_t start, unsigned nr_pages); | 29 | pgoff_t start, unsigned nr_pages); |
@@ -81,6 +80,16 @@ static inline void pagevec_free(struct pagevec *pvec) | |||
81 | __pagevec_free(pvec); | 80 | __pagevec_free(pvec); |
82 | } | 81 | } |
83 | 82 | ||
83 | static inline void __pagevec_lru_add(struct pagevec *pvec) | ||
84 | { | ||
85 | ____pagevec_lru_add(pvec, LRU_INACTIVE); | ||
86 | } | ||
87 | |||
88 | static inline void __pagevec_lru_add_active(struct pagevec *pvec) | ||
89 | { | ||
90 | ____pagevec_lru_add(pvec, LRU_ACTIVE); | ||
91 | } | ||
92 | |||
84 | static inline void pagevec_lru_add(struct pagevec *pvec) | 93 | static inline void pagevec_lru_add(struct pagevec *pvec) |
85 | { | 94 | { |
86 | if (pagevec_count(pvec)) | 95 | if (pagevec_count(pvec)) |
diff --git a/include/linux/swap.h b/include/linux/swap.h index de40f169a4e4..fcc169610d09 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h | |||
@@ -171,8 +171,8 @@ extern unsigned int nr_free_pagecache_pages(void); | |||
171 | 171 | ||
172 | 172 | ||
173 | /* linux/mm/swap.c */ | 173 | /* linux/mm/swap.c */ |
174 | extern void lru_cache_add(struct page *); | 174 | extern void __lru_cache_add(struct page *, enum lru_list lru); |
175 | extern void lru_cache_add_active(struct page *); | 175 | extern void lru_cache_add_lru(struct page *, enum lru_list lru); |
176 | extern void activate_page(struct page *); | 176 | extern void activate_page(struct page *); |
177 | extern void mark_page_accessed(struct page *); | 177 | extern void mark_page_accessed(struct page *); |
178 | extern void lru_add_drain(void); | 178 | extern void lru_add_drain(void); |
@@ -180,6 +180,20 @@ extern int lru_add_drain_all(void); | |||
180 | extern void rotate_reclaimable_page(struct page *page); | 180 | extern void rotate_reclaimable_page(struct page *page); |
181 | extern void swap_setup(void); | 181 | extern void swap_setup(void); |
182 | 182 | ||
183 | /** | ||
184 | * lru_cache_add: add a page to the page lists | ||
185 | * @page: the page to add | ||
186 | */ | ||
187 | static inline void lru_cache_add(struct page *page) | ||
188 | { | ||
189 | __lru_cache_add(page, LRU_INACTIVE); | ||
190 | } | ||
191 | |||
192 | static inline void lru_cache_add_active(struct page *page) | ||
193 | { | ||
194 | __lru_cache_add(page, LRU_ACTIVE); | ||
195 | } | ||
196 | |||
183 | /* linux/mm/vmscan.c */ | 197 | /* linux/mm/vmscan.c */ |
184 | extern unsigned long try_to_free_pages(struct zonelist *zonelist, int order, | 198 | extern unsigned long try_to_free_pages(struct zonelist *zonelist, int order, |
185 | gfp_t gfp_mask); | 199 | gfp_t gfp_mask); |
diff --git a/mm/migrate.c b/mm/migrate.c index da73742e52a5..ad15b5ef2599 100644 --- a/mm/migrate.c +++ b/mm/migrate.c | |||
@@ -55,16 +55,7 @@ int migrate_prep(void) | |||
55 | 55 | ||
56 | static inline void move_to_lru(struct page *page) | 56 | static inline void move_to_lru(struct page *page) |
57 | { | 57 | { |
58 | if (PageActive(page)) { | 58 | lru_cache_add_lru(page, page_lru(page)); |
59 | /* | ||
60 | * lru_cache_add_active checks that | ||
61 | * the PG_active bit is off. | ||
62 | */ | ||
63 | ClearPageActive(page); | ||
64 | lru_cache_add_active(page); | ||
65 | } else { | ||
66 | lru_cache_add(page); | ||
67 | } | ||
68 | put_page(page); | 59 | put_page(page); |
69 | } | 60 | } |
70 | 61 | ||
@@ -34,8 +34,7 @@ | |||
34 | /* How many pages do we try to swap or page in/out together? */ | 34 | /* How many pages do we try to swap or page in/out together? */ |
35 | int page_cluster; | 35 | int page_cluster; |
36 | 36 | ||
37 | static DEFINE_PER_CPU(struct pagevec, lru_add_pvecs); | 37 | static DEFINE_PER_CPU(struct pagevec[NR_LRU_LISTS], lru_add_pvecs); |
38 | static DEFINE_PER_CPU(struct pagevec, lru_add_active_pvecs); | ||
39 | static DEFINE_PER_CPU(struct pagevec, lru_rotate_pvecs); | 38 | static DEFINE_PER_CPU(struct pagevec, lru_rotate_pvecs); |
40 | 39 | ||
41 | /* | 40 | /* |
@@ -186,28 +185,29 @@ void mark_page_accessed(struct page *page) | |||
186 | 185 | ||
187 | EXPORT_SYMBOL(mark_page_accessed); | 186 | EXPORT_SYMBOL(mark_page_accessed); |
188 | 187 | ||
189 | /** | 188 | void __lru_cache_add(struct page *page, enum lru_list lru) |
190 | * lru_cache_add: add a page to the page lists | ||
191 | * @page: the page to add | ||
192 | */ | ||
193 | void lru_cache_add(struct page *page) | ||
194 | { | 189 | { |
195 | struct pagevec *pvec = &get_cpu_var(lru_add_pvecs); | 190 | struct pagevec *pvec = &get_cpu_var(lru_add_pvecs)[lru]; |
196 | 191 | ||
197 | page_cache_get(page); | 192 | page_cache_get(page); |
198 | if (!pagevec_add(pvec, page)) | 193 | if (!pagevec_add(pvec, page)) |
199 | __pagevec_lru_add(pvec); | 194 | ____pagevec_lru_add(pvec, lru); |
200 | put_cpu_var(lru_add_pvecs); | 195 | put_cpu_var(lru_add_pvecs); |
201 | } | 196 | } |
202 | 197 | ||
203 | void lru_cache_add_active(struct page *page) | 198 | /** |
199 | * lru_cache_add_lru - add a page to a page list | ||
200 | * @page: the page to be added to the LRU. | ||
201 | * @lru: the LRU list to which the page is added. | ||
202 | */ | ||
203 | void lru_cache_add_lru(struct page *page, enum lru_list lru) | ||
204 | { | 204 | { |
205 | struct pagevec *pvec = &get_cpu_var(lru_add_active_pvecs); | 205 | if (PageActive(page)) { |
206 | ClearPageActive(page); | ||
207 | } | ||
206 | 208 | ||
207 | page_cache_get(page); | 209 | VM_BUG_ON(PageLRU(page) || PageActive(page)); |
208 | if (!pagevec_add(pvec, page)) | 210 | __lru_cache_add(page, lru); |
209 | __pagevec_lru_add_active(pvec); | ||
210 | put_cpu_var(lru_add_active_pvecs); | ||
211 | } | 211 | } |
212 | 212 | ||
213 | /* | 213 | /* |
@@ -217,15 +217,15 @@ void lru_cache_add_active(struct page *page) | |||
217 | */ | 217 | */ |
218 | static void drain_cpu_pagevecs(int cpu) | 218 | static void drain_cpu_pagevecs(int cpu) |
219 | { | 219 | { |
220 | struct pagevec *pvecs = per_cpu(lru_add_pvecs, cpu); | ||
220 | struct pagevec *pvec; | 221 | struct pagevec *pvec; |
222 | int lru; | ||
221 | 223 | ||
222 | pvec = &per_cpu(lru_add_pvecs, cpu); | 224 | for_each_lru(lru) { |
223 | if (pagevec_count(pvec)) | 225 | pvec = &pvecs[lru - LRU_BASE]; |
224 | __pagevec_lru_add(pvec); | 226 | if (pagevec_count(pvec)) |
225 | 227 | ____pagevec_lru_add(pvec, lru); | |
226 | pvec = &per_cpu(lru_add_active_pvecs, cpu); | 228 | } |
227 | if (pagevec_count(pvec)) | ||
228 | __pagevec_lru_add_active(pvec); | ||
229 | 229 | ||
230 | pvec = &per_cpu(lru_rotate_pvecs, cpu); | 230 | pvec = &per_cpu(lru_rotate_pvecs, cpu); |
231 | if (pagevec_count(pvec)) { | 231 | if (pagevec_count(pvec)) { |
@@ -380,7 +380,7 @@ void __pagevec_release_nonlru(struct pagevec *pvec) | |||
380 | * Add the passed pages to the LRU, then drop the caller's refcount | 380 | * Add the passed pages to the LRU, then drop the caller's refcount |
381 | * on them. Reinitialises the caller's pagevec. | 381 | * on them. Reinitialises the caller's pagevec. |
382 | */ | 382 | */ |
383 | void __pagevec_lru_add(struct pagevec *pvec) | 383 | void ____pagevec_lru_add(struct pagevec *pvec, enum lru_list lru) |
384 | { | 384 | { |
385 | int i; | 385 | int i; |
386 | struct zone *zone = NULL; | 386 | struct zone *zone = NULL; |
@@ -397,7 +397,9 @@ void __pagevec_lru_add(struct pagevec *pvec) | |||
397 | } | 397 | } |
398 | VM_BUG_ON(PageLRU(page)); | 398 | VM_BUG_ON(PageLRU(page)); |
399 | SetPageLRU(page); | 399 | SetPageLRU(page); |
400 | add_page_to_inactive_list(zone, page); | 400 | if (is_active_lru(lru)) |
401 | SetPageActive(page); | ||
402 | add_page_to_lru_list(zone, page, lru); | ||
401 | } | 403 | } |
402 | if (zone) | 404 | if (zone) |
403 | spin_unlock_irq(&zone->lru_lock); | 405 | spin_unlock_irq(&zone->lru_lock); |
@@ -405,34 +407,7 @@ void __pagevec_lru_add(struct pagevec *pvec) | |||
405 | pagevec_reinit(pvec); | 407 | pagevec_reinit(pvec); |
406 | } | 408 | } |
407 | 409 | ||
408 | EXPORT_SYMBOL(__pagevec_lru_add); | 410 | EXPORT_SYMBOL(____pagevec_lru_add); |
409 | |||
410 | void __pagevec_lru_add_active(struct pagevec *pvec) | ||
411 | { | ||
412 | int i; | ||
413 | struct zone *zone = NULL; | ||
414 | |||
415 | for (i = 0; i < pagevec_count(pvec); i++) { | ||
416 | struct page *page = pvec->pages[i]; | ||
417 | struct zone *pagezone = page_zone(page); | ||
418 | |||
419 | if (pagezone != zone) { | ||
420 | if (zone) | ||
421 | spin_unlock_irq(&zone->lru_lock); | ||
422 | zone = pagezone; | ||
423 | spin_lock_irq(&zone->lru_lock); | ||
424 | } | ||
425 | VM_BUG_ON(PageLRU(page)); | ||
426 | SetPageLRU(page); | ||
427 | VM_BUG_ON(PageActive(page)); | ||
428 | SetPageActive(page); | ||
429 | add_page_to_active_list(zone, page); | ||
430 | } | ||
431 | if (zone) | ||
432 | spin_unlock_irq(&zone->lru_lock); | ||
433 | release_pages(pvec->pages, pvec->nr, pvec->cold); | ||
434 | pagevec_reinit(pvec); | ||
435 | } | ||
436 | 411 | ||
437 | /* | 412 | /* |
438 | * Try to drop buffers from the pages in a pagevec | 413 | * Try to drop buffers from the pages in a pagevec |