diff options
-rw-r--r-- | mm/vmscan.c | 49 |
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, |