aboutsummaryrefslogtreecommitdiffstats
path: root/mm/swap.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/swap.c')
-rw-r--r--mm/swap.c129
1 files changed, 78 insertions, 51 deletions
diff --git a/mm/swap.c b/mm/swap.c
index 5c13f1338972..4e7e2ec67078 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -47,13 +47,15 @@ static DEFINE_PER_CPU(struct pagevec, lru_deactivate_pvecs);
47static void __page_cache_release(struct page *page) 47static void __page_cache_release(struct page *page)
48{ 48{
49 if (PageLRU(page)) { 49 if (PageLRU(page)) {
50 unsigned long flags;
51 struct zone *zone = page_zone(page); 50 struct zone *zone = page_zone(page);
51 struct lruvec *lruvec;
52 unsigned long flags;
52 53
53 spin_lock_irqsave(&zone->lru_lock, flags); 54 spin_lock_irqsave(&zone->lru_lock, flags);
55 lruvec = mem_cgroup_page_lruvec(page, zone);
54 VM_BUG_ON(!PageLRU(page)); 56 VM_BUG_ON(!PageLRU(page));
55 __ClearPageLRU(page); 57 __ClearPageLRU(page);
56 del_page_from_lru_list(zone, page, page_off_lru(page)); 58 del_page_from_lru_list(page, lruvec, page_off_lru(page));
57 spin_unlock_irqrestore(&zone->lru_lock, flags); 59 spin_unlock_irqrestore(&zone->lru_lock, flags);
58 } 60 }
59} 61}
@@ -82,6 +84,25 @@ static void put_compound_page(struct page *page)
82 if (likely(page != page_head && 84 if (likely(page != page_head &&
83 get_page_unless_zero(page_head))) { 85 get_page_unless_zero(page_head))) {
84 unsigned long flags; 86 unsigned long flags;
87
88 /*
89 * THP can not break up slab pages so avoid taking
90 * compound_lock(). Slab performs non-atomic bit ops
91 * on page->flags for better performance. In particular
92 * slab_unlock() in slub used to be a hot path. It is
93 * still hot on arches that do not support
94 * this_cpu_cmpxchg_double().
95 */
96 if (PageSlab(page_head)) {
97 if (PageTail(page)) {
98 if (put_page_testzero(page_head))
99 VM_BUG_ON(1);
100
101 atomic_dec(&page->_mapcount);
102 goto skip_lock_tail;
103 } else
104 goto skip_lock;
105 }
85 /* 106 /*
86 * page_head wasn't a dangling pointer but it 107 * page_head wasn't a dangling pointer but it
87 * may not be a head page anymore by the time 108 * may not be a head page anymore by the time
@@ -92,10 +113,10 @@ static void put_compound_page(struct page *page)
92 if (unlikely(!PageTail(page))) { 113 if (unlikely(!PageTail(page))) {
93 /* __split_huge_page_refcount run before us */ 114 /* __split_huge_page_refcount run before us */
94 compound_unlock_irqrestore(page_head, flags); 115 compound_unlock_irqrestore(page_head, flags);
95 VM_BUG_ON(PageHead(page_head)); 116skip_lock:
96 if (put_page_testzero(page_head)) 117 if (put_page_testzero(page_head))
97 __put_single_page(page_head); 118 __put_single_page(page_head);
98 out_put_single: 119out_put_single:
99 if (put_page_testzero(page)) 120 if (put_page_testzero(page))
100 __put_single_page(page); 121 __put_single_page(page);
101 return; 122 return;
@@ -115,6 +136,8 @@ static void put_compound_page(struct page *page)
115 VM_BUG_ON(atomic_read(&page_head->_count) <= 0); 136 VM_BUG_ON(atomic_read(&page_head->_count) <= 0);
116 VM_BUG_ON(atomic_read(&page->_count) != 0); 137 VM_BUG_ON(atomic_read(&page->_count) != 0);
117 compound_unlock_irqrestore(page_head, flags); 138 compound_unlock_irqrestore(page_head, flags);
139
140skip_lock_tail:
118 if (put_page_testzero(page_head)) { 141 if (put_page_testzero(page_head)) {
119 if (PageHead(page_head)) 142 if (PageHead(page_head))
120 __put_compound_page(page_head); 143 __put_compound_page(page_head);
@@ -162,6 +185,18 @@ bool __get_page_tail(struct page *page)
162 struct page *page_head = compound_trans_head(page); 185 struct page *page_head = compound_trans_head(page);
163 186
164 if (likely(page != page_head && get_page_unless_zero(page_head))) { 187 if (likely(page != page_head && get_page_unless_zero(page_head))) {
188
189 /* Ref to put_compound_page() comment. */
190 if (PageSlab(page_head)) {
191 if (likely(PageTail(page))) {
192 __get_page_tail_foll(page, false);
193 return true;
194 } else {
195 put_page(page_head);
196 return false;
197 }
198 }
199
165 /* 200 /*
166 * page_head wasn't a dangling pointer but it 201 * page_head wasn't a dangling pointer but it
167 * may not be a head page anymore by the time 202 * may not be a head page anymore by the time
@@ -202,11 +237,12 @@ void put_pages_list(struct list_head *pages)
202EXPORT_SYMBOL(put_pages_list); 237EXPORT_SYMBOL(put_pages_list);
203 238
204static void pagevec_lru_move_fn(struct pagevec *pvec, 239static void pagevec_lru_move_fn(struct pagevec *pvec,
205 void (*move_fn)(struct page *page, void *arg), 240 void (*move_fn)(struct page *page, struct lruvec *lruvec, void *arg),
206 void *arg) 241 void *arg)
207{ 242{
208 int i; 243 int i;
209 struct zone *zone = NULL; 244 struct zone *zone = NULL;
245 struct lruvec *lruvec;
210 unsigned long flags = 0; 246 unsigned long flags = 0;
211 247
212 for (i = 0; i < pagevec_count(pvec); i++) { 248 for (i = 0; i < pagevec_count(pvec); i++) {
@@ -220,7 +256,8 @@ static void pagevec_lru_move_fn(struct pagevec *pvec,
220 spin_lock_irqsave(&zone->lru_lock, flags); 256 spin_lock_irqsave(&zone->lru_lock, flags);
221 } 257 }
222 258
223 (*move_fn)(page, arg); 259 lruvec = mem_cgroup_page_lruvec(page, zone);
260 (*move_fn)(page, lruvec, arg);
224 } 261 }
225 if (zone) 262 if (zone)
226 spin_unlock_irqrestore(&zone->lru_lock, flags); 263 spin_unlock_irqrestore(&zone->lru_lock, flags);
@@ -228,16 +265,13 @@ static void pagevec_lru_move_fn(struct pagevec *pvec,
228 pagevec_reinit(pvec); 265 pagevec_reinit(pvec);
229} 266}
230 267
231static void pagevec_move_tail_fn(struct page *page, void *arg) 268static void pagevec_move_tail_fn(struct page *page, struct lruvec *lruvec,
269 void *arg)
232{ 270{
233 int *pgmoved = arg; 271 int *pgmoved = arg;
234 272
235 if (PageLRU(page) && !PageActive(page) && !PageUnevictable(page)) { 273 if (PageLRU(page) && !PageActive(page) && !PageUnevictable(page)) {
236 enum lru_list lru = page_lru_base_type(page); 274 enum lru_list lru = page_lru_base_type(page);
237 struct lruvec *lruvec;
238
239 lruvec = mem_cgroup_lru_move_lists(page_zone(page),
240 page, lru, lru);
241 list_move_tail(&page->lru, &lruvec->lists[lru]); 275 list_move_tail(&page->lru, &lruvec->lists[lru]);
242 (*pgmoved)++; 276 (*pgmoved)++;
243 } 277 }
@@ -276,41 +310,30 @@ void rotate_reclaimable_page(struct page *page)
276 } 310 }
277} 311}
278 312
279static void update_page_reclaim_stat(struct zone *zone, struct page *page, 313static void update_page_reclaim_stat(struct lruvec *lruvec,
280 int file, int rotated) 314 int file, int rotated)
281{ 315{
282 struct zone_reclaim_stat *reclaim_stat = &zone->reclaim_stat; 316 struct zone_reclaim_stat *reclaim_stat = &lruvec->reclaim_stat;
283 struct zone_reclaim_stat *memcg_reclaim_stat;
284
285 memcg_reclaim_stat = mem_cgroup_get_reclaim_stat_from_page(page);
286 317
287 reclaim_stat->recent_scanned[file]++; 318 reclaim_stat->recent_scanned[file]++;
288 if (rotated) 319 if (rotated)
289 reclaim_stat->recent_rotated[file]++; 320 reclaim_stat->recent_rotated[file]++;
290
291 if (!memcg_reclaim_stat)
292 return;
293
294 memcg_reclaim_stat->recent_scanned[file]++;
295 if (rotated)
296 memcg_reclaim_stat->recent_rotated[file]++;
297} 321}
298 322
299static void __activate_page(struct page *page, void *arg) 323static void __activate_page(struct page *page, struct lruvec *lruvec,
324 void *arg)
300{ 325{
301 struct zone *zone = page_zone(page);
302
303 if (PageLRU(page) && !PageActive(page) && !PageUnevictable(page)) { 326 if (PageLRU(page) && !PageActive(page) && !PageUnevictable(page)) {
304 int file = page_is_file_cache(page); 327 int file = page_is_file_cache(page);
305 int lru = page_lru_base_type(page); 328 int lru = page_lru_base_type(page);
306 del_page_from_lru_list(zone, page, lru);
307 329
330 del_page_from_lru_list(page, lruvec, lru);
308 SetPageActive(page); 331 SetPageActive(page);
309 lru += LRU_ACTIVE; 332 lru += LRU_ACTIVE;
310 add_page_to_lru_list(zone, page, lru); 333 add_page_to_lru_list(page, lruvec, lru);
311 __count_vm_event(PGACTIVATE);
312 334
313 update_page_reclaim_stat(zone, page, file, 1); 335 __count_vm_event(PGACTIVATE);
336 update_page_reclaim_stat(lruvec, file, 1);
314 } 337 }
315} 338}
316 339
@@ -347,7 +370,7 @@ void activate_page(struct page *page)
347 struct zone *zone = page_zone(page); 370 struct zone *zone = page_zone(page);
348 371
349 spin_lock_irq(&zone->lru_lock); 372 spin_lock_irq(&zone->lru_lock);
350 __activate_page(page, NULL); 373 __activate_page(page, mem_cgroup_page_lruvec(page, zone), NULL);
351 spin_unlock_irq(&zone->lru_lock); 374 spin_unlock_irq(&zone->lru_lock);
352} 375}
353#endif 376#endif
@@ -414,11 +437,13 @@ void lru_cache_add_lru(struct page *page, enum lru_list lru)
414void add_page_to_unevictable_list(struct page *page) 437void add_page_to_unevictable_list(struct page *page)
415{ 438{
416 struct zone *zone = page_zone(page); 439 struct zone *zone = page_zone(page);
440 struct lruvec *lruvec;
417 441
418 spin_lock_irq(&zone->lru_lock); 442 spin_lock_irq(&zone->lru_lock);
443 lruvec = mem_cgroup_page_lruvec(page, zone);
419 SetPageUnevictable(page); 444 SetPageUnevictable(page);
420 SetPageLRU(page); 445 SetPageLRU(page);
421 add_page_to_lru_list(zone, page, LRU_UNEVICTABLE); 446 add_page_to_lru_list(page, lruvec, LRU_UNEVICTABLE);
422 spin_unlock_irq(&zone->lru_lock); 447 spin_unlock_irq(&zone->lru_lock);
423} 448}
424 449
@@ -443,11 +468,11 @@ void add_page_to_unevictable_list(struct page *page)
443 * be write it out by flusher threads as this is much more effective 468 * be write it out by flusher threads as this is much more effective
444 * than the single-page writeout from reclaim. 469 * than the single-page writeout from reclaim.
445 */ 470 */
446static void lru_deactivate_fn(struct page *page, void *arg) 471static void lru_deactivate_fn(struct page *page, struct lruvec *lruvec,
472 void *arg)
447{ 473{
448 int lru, file; 474 int lru, file;
449 bool active; 475 bool active;
450 struct zone *zone = page_zone(page);
451 476
452 if (!PageLRU(page)) 477 if (!PageLRU(page))
453 return; 478 return;
@@ -460,13 +485,13 @@ static void lru_deactivate_fn(struct page *page, void *arg)
460 return; 485 return;
461 486
462 active = PageActive(page); 487 active = PageActive(page);
463
464 file = page_is_file_cache(page); 488 file = page_is_file_cache(page);
465 lru = page_lru_base_type(page); 489 lru = page_lru_base_type(page);
466 del_page_from_lru_list(zone, page, lru + active); 490
491 del_page_from_lru_list(page, lruvec, lru + active);
467 ClearPageActive(page); 492 ClearPageActive(page);
468 ClearPageReferenced(page); 493 ClearPageReferenced(page);
469 add_page_to_lru_list(zone, page, lru); 494 add_page_to_lru_list(page, lruvec, lru);
470 495
471 if (PageWriteback(page) || PageDirty(page)) { 496 if (PageWriteback(page) || PageDirty(page)) {
472 /* 497 /*
@@ -476,19 +501,17 @@ static void lru_deactivate_fn(struct page *page, void *arg)
476 */ 501 */
477 SetPageReclaim(page); 502 SetPageReclaim(page);
478 } else { 503 } else {
479 struct lruvec *lruvec;
480 /* 504 /*
481 * The page's writeback ends up during pagevec 505 * The page's writeback ends up during pagevec
482 * We moves tha page into tail of inactive. 506 * We moves tha page into tail of inactive.
483 */ 507 */
484 lruvec = mem_cgroup_lru_move_lists(zone, page, lru, lru);
485 list_move_tail(&page->lru, &lruvec->lists[lru]); 508 list_move_tail(&page->lru, &lruvec->lists[lru]);
486 __count_vm_event(PGROTATED); 509 __count_vm_event(PGROTATED);
487 } 510 }
488 511
489 if (active) 512 if (active)
490 __count_vm_event(PGDEACTIVATE); 513 __count_vm_event(PGDEACTIVATE);
491 update_page_reclaim_stat(zone, page, file, 0); 514 update_page_reclaim_stat(lruvec, file, 0);
492} 515}
493 516
494/* 517/*
@@ -588,6 +611,7 @@ void release_pages(struct page **pages, int nr, int cold)
588 int i; 611 int i;
589 LIST_HEAD(pages_to_free); 612 LIST_HEAD(pages_to_free);
590 struct zone *zone = NULL; 613 struct zone *zone = NULL;
614 struct lruvec *lruvec;
591 unsigned long uninitialized_var(flags); 615 unsigned long uninitialized_var(flags);
592 616
593 for (i = 0; i < nr; i++) { 617 for (i = 0; i < nr; i++) {
@@ -615,9 +639,11 @@ void release_pages(struct page **pages, int nr, int cold)
615 zone = pagezone; 639 zone = pagezone;
616 spin_lock_irqsave(&zone->lru_lock, flags); 640 spin_lock_irqsave(&zone->lru_lock, flags);
617 } 641 }
642
643 lruvec = mem_cgroup_page_lruvec(page, zone);
618 VM_BUG_ON(!PageLRU(page)); 644 VM_BUG_ON(!PageLRU(page));
619 __ClearPageLRU(page); 645 __ClearPageLRU(page);
620 del_page_from_lru_list(zone, page, page_off_lru(page)); 646 del_page_from_lru_list(page, lruvec, page_off_lru(page));
621 } 647 }
622 648
623 list_add(&page->lru, &pages_to_free); 649 list_add(&page->lru, &pages_to_free);
@@ -649,8 +675,8 @@ EXPORT_SYMBOL(__pagevec_release);
649 675
650#ifdef CONFIG_TRANSPARENT_HUGEPAGE 676#ifdef CONFIG_TRANSPARENT_HUGEPAGE
651/* used by __split_huge_page_refcount() */ 677/* used by __split_huge_page_refcount() */
652void lru_add_page_tail(struct zone* zone, 678void lru_add_page_tail(struct page *page, struct page *page_tail,
653 struct page *page, struct page *page_tail) 679 struct lruvec *lruvec)
654{ 680{
655 int uninitialized_var(active); 681 int uninitialized_var(active);
656 enum lru_list lru; 682 enum lru_list lru;
@@ -659,7 +685,8 @@ void lru_add_page_tail(struct zone* zone,
659 VM_BUG_ON(!PageHead(page)); 685 VM_BUG_ON(!PageHead(page));
660 VM_BUG_ON(PageCompound(page_tail)); 686 VM_BUG_ON(PageCompound(page_tail));
661 VM_BUG_ON(PageLRU(page_tail)); 687 VM_BUG_ON(PageLRU(page_tail));
662 VM_BUG_ON(NR_CPUS != 1 && !spin_is_locked(&zone->lru_lock)); 688 VM_BUG_ON(NR_CPUS != 1 &&
689 !spin_is_locked(&lruvec_zone(lruvec)->lru_lock));
663 690
664 SetPageLRU(page_tail); 691 SetPageLRU(page_tail);
665 692
@@ -688,20 +715,20 @@ void lru_add_page_tail(struct zone* zone,
688 * Use the standard add function to put page_tail on the list, 715 * Use the standard add function to put page_tail on the list,
689 * but then correct its position so they all end up in order. 716 * but then correct its position so they all end up in order.
690 */ 717 */
691 add_page_to_lru_list(zone, page_tail, lru); 718 add_page_to_lru_list(page_tail, lruvec, lru);
692 list_head = page_tail->lru.prev; 719 list_head = page_tail->lru.prev;
693 list_move_tail(&page_tail->lru, list_head); 720 list_move_tail(&page_tail->lru, list_head);
694 } 721 }
695 722
696 if (!PageUnevictable(page)) 723 if (!PageUnevictable(page))
697 update_page_reclaim_stat(zone, page_tail, file, active); 724 update_page_reclaim_stat(lruvec, file, active);
698} 725}
699#endif /* CONFIG_TRANSPARENT_HUGEPAGE */ 726#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
700 727
701static void __pagevec_lru_add_fn(struct page *page, void *arg) 728static void __pagevec_lru_add_fn(struct page *page, struct lruvec *lruvec,
729 void *arg)
702{ 730{
703 enum lru_list lru = (enum lru_list)arg; 731 enum lru_list lru = (enum lru_list)arg;
704 struct zone *zone = page_zone(page);
705 int file = is_file_lru(lru); 732 int file = is_file_lru(lru);
706 int active = is_active_lru(lru); 733 int active = is_active_lru(lru);
707 734
@@ -712,8 +739,8 @@ static void __pagevec_lru_add_fn(struct page *page, void *arg)
712 SetPageLRU(page); 739 SetPageLRU(page);
713 if (active) 740 if (active)
714 SetPageActive(page); 741 SetPageActive(page);
715 add_page_to_lru_list(zone, page, lru); 742 add_page_to_lru_list(page, lruvec, lru);
716 update_page_reclaim_stat(zone, page, file, active); 743 update_page_reclaim_stat(lruvec, file, active);
717} 744}
718 745
719/* 746/*