aboutsummaryrefslogtreecommitdiffstats
path: root/mm/swap.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/swap.c')
-rw-r--r--mm/swap.c76
1 files changed, 47 insertions, 29 deletions
diff --git a/mm/swap.c b/mm/swap.c
index 03ae2076f92f..2e0e871f542f 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -34,6 +34,25 @@
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? */
35int page_cluster; 35int page_cluster;
36 36
37/*
38 * This path almost never happens for VM activity - pages are normally
39 * freed via pagevecs. But it gets used by networking.
40 */
41static void fastcall __page_cache_release(struct page *page)
42{
43 if (PageLRU(page)) {
44 unsigned long flags;
45 struct zone *zone = page_zone(page);
46
47 spin_lock_irqsave(&zone->lru_lock, flags);
48 VM_BUG_ON(!PageLRU(page));
49 __ClearPageLRU(page);
50 del_page_from_lru(zone, page);
51 spin_unlock_irqrestore(&zone->lru_lock, flags);
52 }
53 free_hot_page(page);
54}
55
37static void put_compound_page(struct page *page) 56static void put_compound_page(struct page *page)
38{ 57{
39 page = (struct page *)page_private(page); 58 page = (struct page *)page_private(page);
@@ -54,6 +73,26 @@ void put_page(struct page *page)
54} 73}
55EXPORT_SYMBOL(put_page); 74EXPORT_SYMBOL(put_page);
56 75
76/**
77 * put_pages_list(): release a list of pages
78 *
79 * Release a list of pages which are strung together on page.lru. Currently
80 * used by read_cache_pages() and related error recovery code.
81 *
82 * @pages: list of pages threaded on page->lru
83 */
84void put_pages_list(struct list_head *pages)
85{
86 while (!list_empty(pages)) {
87 struct page *victim;
88
89 victim = list_entry(pages->prev, struct page, lru);
90 list_del(&victim->lru);
91 page_cache_release(victim);
92 }
93}
94EXPORT_SYMBOL(put_pages_list);
95
57/* 96/*
58 * Writeback is about to end against a page which has been marked for immediate 97 * Writeback is about to end against a page which has been marked for immediate
59 * reclaim. If it still appears to be reclaimable, move it to the tail of the 98 * reclaim. If it still appears to be reclaimable, move it to the tail of the
@@ -86,9 +125,8 @@ int rotate_reclaimable_page(struct page *page)
86 zone = page_zone(page); 125 zone = page_zone(page);
87 spin_lock_irqsave(&zone->lru_lock, flags); 126 spin_lock_irqsave(&zone->lru_lock, flags);
88 if (PageLRU(page) && !PageActive(page)) { 127 if (PageLRU(page) && !PageActive(page)) {
89 list_del(&page->lru); 128 list_move_tail(&page->lru, &zone->inactive_list);
90 list_add_tail(&page->lru, &zone->inactive_list); 129 __count_vm_event(PGROTATED);
91 inc_page_state(pgrotated);
92 } 130 }
93 if (!test_clear_page_writeback(page)) 131 if (!test_clear_page_writeback(page))
94 BUG(); 132 BUG();
@@ -108,7 +146,7 @@ void fastcall activate_page(struct page *page)
108 del_page_from_inactive_list(zone, page); 146 del_page_from_inactive_list(zone, page);
109 SetPageActive(page); 147 SetPageActive(page);
110 add_page_to_active_list(zone, page); 148 add_page_to_active_list(zone, page);
111 inc_page_state(pgactivate); 149 __count_vm_event(PGACTIVATE);
112 } 150 }
113 spin_unlock_irq(&zone->lru_lock); 151 spin_unlock_irq(&zone->lru_lock);
114} 152}
@@ -204,26 +242,6 @@ int lru_add_drain_all(void)
204#endif 242#endif
205 243
206/* 244/*
207 * This path almost never happens for VM activity - pages are normally
208 * freed via pagevecs. But it gets used by networking.
209 */
210void fastcall __page_cache_release(struct page *page)
211{
212 if (PageLRU(page)) {
213 unsigned long flags;
214 struct zone *zone = page_zone(page);
215
216 spin_lock_irqsave(&zone->lru_lock, flags);
217 BUG_ON(!PageLRU(page));
218 __ClearPageLRU(page);
219 del_page_from_lru(zone, page);
220 spin_unlock_irqrestore(&zone->lru_lock, flags);
221 }
222 free_hot_page(page);
223}
224EXPORT_SYMBOL(__page_cache_release);
225
226/*
227 * Batched page_cache_release(). Decrement the reference count on all the 245 * Batched page_cache_release(). Decrement the reference count on all the
228 * passed pages. If it fell to zero then remove the page from the LRU and 246 * passed pages. If it fell to zero then remove the page from the LRU and
229 * free it. 247 * free it.
@@ -265,7 +283,7 @@ void release_pages(struct page **pages, int nr, int cold)
265 zone = pagezone; 283 zone = pagezone;
266 spin_lock_irq(&zone->lru_lock); 284 spin_lock_irq(&zone->lru_lock);
267 } 285 }
268 BUG_ON(!PageLRU(page)); 286 VM_BUG_ON(!PageLRU(page));
269 __ClearPageLRU(page); 287 __ClearPageLRU(page);
270 del_page_from_lru(zone, page); 288 del_page_from_lru(zone, page);
271 } 289 }
@@ -318,7 +336,7 @@ void __pagevec_release_nonlru(struct pagevec *pvec)
318 for (i = 0; i < pagevec_count(pvec); i++) { 336 for (i = 0; i < pagevec_count(pvec); i++) {
319 struct page *page = pvec->pages[i]; 337 struct page *page = pvec->pages[i];
320 338
321 BUG_ON(PageLRU(page)); 339 VM_BUG_ON(PageLRU(page));
322 if (put_page_testzero(page)) 340 if (put_page_testzero(page))
323 pagevec_add(&pages_to_free, page); 341 pagevec_add(&pages_to_free, page);
324 } 342 }
@@ -345,7 +363,7 @@ void __pagevec_lru_add(struct pagevec *pvec)
345 zone = pagezone; 363 zone = pagezone;
346 spin_lock_irq(&zone->lru_lock); 364 spin_lock_irq(&zone->lru_lock);
347 } 365 }
348 BUG_ON(PageLRU(page)); 366 VM_BUG_ON(PageLRU(page));
349 SetPageLRU(page); 367 SetPageLRU(page);
350 add_page_to_inactive_list(zone, page); 368 add_page_to_inactive_list(zone, page);
351 } 369 }
@@ -372,9 +390,9 @@ void __pagevec_lru_add_active(struct pagevec *pvec)
372 zone = pagezone; 390 zone = pagezone;
373 spin_lock_irq(&zone->lru_lock); 391 spin_lock_irq(&zone->lru_lock);
374 } 392 }
375 BUG_ON(PageLRU(page)); 393 VM_BUG_ON(PageLRU(page));
376 SetPageLRU(page); 394 SetPageLRU(page);
377 BUG_ON(PageActive(page)); 395 VM_BUG_ON(PageActive(page));
378 SetPageActive(page); 396 SetPageActive(page);
379 add_page_to_active_list(zone, page); 397 add_page_to_active_list(zone, page);
380 } 398 }