aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorMel Gorman <mgorman@suse.de>2013-07-03 18:01:58 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-07-03 19:07:29 -0400
commitb1a6f21e3b2315d46ae8af88a8f4eb8ea2763107 (patch)
tree6e4a9a45085f465d56f1d695f6b1eb0b02d7c1cc /mm
parente2be15f6c3eecedfbe1550cca8d72c5057abbbd2 (diff)
mm: vmscan: stall page reclaim after a list of pages have been processed
Commit "mm: vmscan: Block kswapd if it is encountering pages under writeback" blocks page reclaim if it encounters pages under writeback marked for immediate reclaim. It blocks while pages are still isolated from the LRU which is unnecessary. This patch defers the blocking until after the isolated pages have been processed and tidies up some of the comments. Signed-off-by: Mel Gorman <mgorman@suse.de> Cc: Johannes Weiner <hannes@cmpxchg.org> Cc: Michal Hocko <mhocko@suse.cz> Cc: Rik van Riel <riel@redhat.com> Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Cc: Jiri Slaby <jslaby@suse.cz> Cc: Valdis Kletnieks <Valdis.Kletnieks@vt.edu> Cc: Zlatko Calusic <zcalusic@bitsync.net> Cc: dormando <dormando@rydia.net> Cc: Trond Myklebust <trond.myklebust@fys.uio.no> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm')
-rw-r--r--mm/vmscan.c49
1 files changed, 33 insertions, 16 deletions
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 999ef0b9399a..5b1a79c8f0cb 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -697,6 +697,7 @@ static unsigned long shrink_page_list(struct list_head *page_list,
697 enum ttu_flags ttu_flags, 697 enum ttu_flags ttu_flags,
698 unsigned long *ret_nr_unqueued_dirty, 698 unsigned long *ret_nr_unqueued_dirty,
699 unsigned long *ret_nr_writeback, 699 unsigned long *ret_nr_writeback,
700 unsigned long *ret_nr_immediate,
700 bool force_reclaim) 701 bool force_reclaim)
701{ 702{
702 LIST_HEAD(ret_pages); 703 LIST_HEAD(ret_pages);
@@ -707,6 +708,7 @@ static unsigned long shrink_page_list(struct list_head *page_list,
707 unsigned long nr_congested = 0; 708 unsigned long nr_congested = 0;
708 unsigned long nr_reclaimed = 0; 709 unsigned long nr_reclaimed = 0;
709 unsigned long nr_writeback = 0; 710 unsigned long nr_writeback = 0;
711 unsigned long nr_immediate = 0;
710 712
711 cond_resched(); 713 cond_resched();
712 714
@@ -773,8 +775,8 @@ static unsigned long shrink_page_list(struct list_head *page_list,
773 * IO can complete. Waiting on the page itself risks an 775 * IO can complete. Waiting on the page itself risks an
774 * indefinite stall if it is impossible to writeback the 776 * indefinite stall if it is impossible to writeback the
775 * page due to IO error or disconnected storage so instead 777 * page due to IO error or disconnected storage so instead
776 * block for HZ/10 or until some IO completes then clear the 778 * note that the LRU is being scanned too quickly and the
777 * ZONE_WRITEBACK flag to recheck if the condition exists. 779 * caller can stall after page list has been processed.
778 * 780 *
779 * 2) Global reclaim encounters a page, memcg encounters a 781 * 2) Global reclaim encounters a page, memcg encounters a
780 * page that is not marked for immediate reclaim or 782 * page that is not marked for immediate reclaim or
@@ -804,10 +806,8 @@ static unsigned long shrink_page_list(struct list_head *page_list,
804 if (current_is_kswapd() && 806 if (current_is_kswapd() &&
805 PageReclaim(page) && 807 PageReclaim(page) &&
806 zone_is_reclaim_writeback(zone)) { 808 zone_is_reclaim_writeback(zone)) {
807 unlock_page(page); 809 nr_immediate++;
808 congestion_wait(BLK_RW_ASYNC, HZ/10); 810 goto keep_locked;
809 zone_clear_flag(zone, ZONE_WRITEBACK);
810 goto keep;
811 811
812 /* Case 2 above */ 812 /* Case 2 above */
813 } else if (global_reclaim(sc) || 813 } else if (global_reclaim(sc) ||
@@ -1033,6 +1033,7 @@ keep:
1033 mem_cgroup_uncharge_end(); 1033 mem_cgroup_uncharge_end();
1034 *ret_nr_unqueued_dirty += nr_unqueued_dirty; 1034 *ret_nr_unqueued_dirty += nr_unqueued_dirty;
1035 *ret_nr_writeback += nr_writeback; 1035 *ret_nr_writeback += nr_writeback;
1036 *ret_nr_immediate += nr_immediate;
1036 return nr_reclaimed; 1037 return nr_reclaimed;
1037} 1038}
1038 1039
@@ -1044,7 +1045,7 @@ unsigned long reclaim_clean_pages_from_list(struct zone *zone,
1044 .priority = DEF_PRIORITY, 1045 .priority = DEF_PRIORITY,
1045 .may_unmap = 1, 1046 .may_unmap = 1,
1046 }; 1047 };
1047 unsigned long ret, dummy1, dummy2; 1048 unsigned long ret, dummy1, dummy2, dummy3;
1048 struct page *page, *next; 1049 struct page *page, *next;
1049 LIST_HEAD(clean_pages); 1050 LIST_HEAD(clean_pages);
1050 1051
@@ -1057,7 +1058,7 @@ unsigned long reclaim_clean_pages_from_list(struct zone *zone,
1057 1058
1058 ret = shrink_page_list(&clean_pages, zone, &sc, 1059 ret = shrink_page_list(&clean_pages, zone, &sc,
1059 TTU_UNMAP|TTU_IGNORE_ACCESS, 1060 TTU_UNMAP|TTU_IGNORE_ACCESS,
1060 &dummy1, &dummy2, true); 1061 &dummy1, &dummy2, &dummy3, true);
1061 list_splice(&clean_pages, page_list); 1062 list_splice(&clean_pages, page_list);
1062 __mod_zone_page_state(zone, NR_ISOLATED_FILE, -ret); 1063 __mod_zone_page_state(zone, NR_ISOLATED_FILE, -ret);
1063 return ret; 1064 return ret;
@@ -1353,6 +1354,7 @@ shrink_inactive_list(unsigned long nr_to_scan, struct lruvec *lruvec,
1353 unsigned long nr_taken; 1354 unsigned long nr_taken;
1354 unsigned long nr_unqueued_dirty = 0; 1355 unsigned long nr_unqueued_dirty = 0;
1355 unsigned long nr_writeback = 0; 1356 unsigned long nr_writeback = 0;
1357 unsigned long nr_immediate = 0;
1356 isolate_mode_t isolate_mode = 0; 1358 isolate_mode_t isolate_mode = 0;
1357 int file = is_file_lru(lru); 1359 int file = is_file_lru(lru);
1358 struct zone *zone = lruvec_zone(lruvec); 1360 struct zone *zone = lruvec_zone(lruvec);
@@ -1394,7 +1396,8 @@ shrink_inactive_list(unsigned long nr_to_scan, struct lruvec *lruvec,
1394 return 0; 1396 return 0;
1395 1397
1396 nr_reclaimed = shrink_page_list(&page_list, zone, sc, TTU_UNMAP, 1398 nr_reclaimed = shrink_page_list(&page_list, zone, sc, TTU_UNMAP,
1397 &nr_unqueued_dirty, &nr_writeback, false); 1399 &nr_unqueued_dirty, &nr_writeback, &nr_immediate,
1400 false);
1398 1401
1399 spin_lock_irq(&zone->lru_lock); 1402 spin_lock_irq(&zone->lru_lock);
1400 1403
@@ -1447,14 +1450,28 @@ shrink_inactive_list(unsigned long nr_to_scan, struct lruvec *lruvec,
1447 } 1450 }
1448 1451
1449 /* 1452 /*
1450 * Similarly, if many dirty pages are encountered that are not 1453 * memcg will stall in page writeback so only consider forcibly
1451 * currently being written then flag that kswapd should start 1454 * stalling for global reclaim
1452 * writing back pages and stall to give a chance for flushers
1453 * to catch up.
1454 */ 1455 */
1455 if (global_reclaim(sc) && nr_unqueued_dirty == nr_taken) { 1456 if (global_reclaim(sc)) {
1456 congestion_wait(BLK_RW_ASYNC, HZ/10); 1457 /*
1457 zone_set_flag(zone, ZONE_TAIL_LRU_DIRTY); 1458 * If dirty pages are scanned that are not queued for IO, it
1459 * implies that flushers are not keeping up. In this case, flag
1460 * the zone ZONE_TAIL_LRU_DIRTY and kswapd will start writing
1461 * pages from reclaim context. It will forcibly stall in the
1462 * next check.
1463 */
1464 if (nr_unqueued_dirty == nr_taken)
1465 zone_set_flag(zone, ZONE_TAIL_LRU_DIRTY);
1466
1467 /*
1468 * In addition, if kswapd scans pages marked marked for
1469 * immediate reclaim and under writeback (nr_immediate), it
1470 * implies that pages are cycling through the LRU faster than
1471 * they are written so also forcibly stall.
1472 */
1473 if (nr_unqueued_dirty == nr_taken || nr_immediate)
1474 congestion_wait(BLK_RW_ASYNC, HZ/10);
1458 } 1475 }
1459 1476
1460 trace_mm_vmscan_lru_shrink_inactive(zone->zone_pgdat->node_id, 1477 trace_mm_vmscan_lru_shrink_inactive(zone->zone_pgdat->node_id,