aboutsummaryrefslogtreecommitdiffstats
path: root/mm/vmscan.c
diff options
context:
space:
mode:
authorMel Gorman <mgorman@suse.de>2013-07-03 18:01:47 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-07-03 19:07:28 -0400
commit2ab44f434586b8ccb11f781b4c2730492e6628f5 (patch)
tree5ff85d452c1fe1b34e04e3238c2de36e39203bcf /mm/vmscan.c
parentb8e83b942a16eb73e63406592d3178207a4f07a1 (diff)
mm: vmscan: decide whether to compact the pgdat based on reclaim progress
In the past, kswapd makes a decision on whether to compact memory after the pgdat was considered balanced. This more or less worked but it is late to make such a decision and does not fit well now that kswapd makes a decision whether to exit the zone scanning loop depending on reclaim progress. This patch will compact a pgdat if at least the requested number of pages were reclaimed from unbalanced zones for a given priority. If any zone is currently balanced, kswapd will not call compaction as it is expected the necessary pages are already available. Signed-off-by: Mel Gorman <mgorman@suse.de> Acked-by: Johannes Weiner <hannes@cmpxchg.org> Reviewed-by: Michal Hocko <mhocko@suse.cz> Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Cc: Rik van Riel <riel@redhat.com> Cc: Jiri Slaby <jslaby@suse.cz> Cc: Valdis Kletnieks <Valdis.Kletnieks@vt.edu> Tested-by: Zlatko Calusic <zcalusic@bitsync.net> Cc: dormando <dormando@rydia.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/vmscan.c')
-rw-r--r--mm/vmscan.c59
1 files changed, 30 insertions, 29 deletions
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 1c10ee512215..cd0980393bac 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -2661,7 +2661,8 @@ static bool prepare_kswapd_sleep(pg_data_t *pgdat, int order, long remaining,
2661 */ 2661 */
2662static bool kswapd_shrink_zone(struct zone *zone, 2662static bool kswapd_shrink_zone(struct zone *zone,
2663 struct scan_control *sc, 2663 struct scan_control *sc,
2664 unsigned long lru_pages) 2664 unsigned long lru_pages,
2665 unsigned long *nr_attempted)
2665{ 2666{
2666 unsigned long nr_slab; 2667 unsigned long nr_slab;
2667 struct reclaim_state *reclaim_state = current->reclaim_state; 2668 struct reclaim_state *reclaim_state = current->reclaim_state;
@@ -2677,6 +2678,9 @@ static bool kswapd_shrink_zone(struct zone *zone,
2677 nr_slab = shrink_slab(&shrink, sc->nr_scanned, lru_pages); 2678 nr_slab = shrink_slab(&shrink, sc->nr_scanned, lru_pages);
2678 sc->nr_reclaimed += reclaim_state->reclaimed_slab; 2679 sc->nr_reclaimed += reclaim_state->reclaimed_slab;
2679 2680
2681 /* Account for the number of pages attempted to reclaim */
2682 *nr_attempted += sc->nr_to_reclaim;
2683
2680 if (nr_slab == 0 && !zone_reclaimable(zone)) 2684 if (nr_slab == 0 && !zone_reclaimable(zone))
2681 zone->all_unreclaimable = 1; 2685 zone->all_unreclaimable = 1;
2682 2686
@@ -2724,7 +2728,9 @@ static unsigned long balance_pgdat(pg_data_t *pgdat, int order,
2724 2728
2725 do { 2729 do {
2726 unsigned long lru_pages = 0; 2730 unsigned long lru_pages = 0;
2731 unsigned long nr_attempted = 0;
2727 bool raise_priority = true; 2732 bool raise_priority = true;
2733 bool pgdat_needs_compaction = (order > 0);
2728 2734
2729 sc.nr_reclaimed = 0; 2735 sc.nr_reclaimed = 0;
2730 2736
@@ -2774,7 +2780,21 @@ static unsigned long balance_pgdat(pg_data_t *pgdat, int order,
2774 for (i = 0; i <= end_zone; i++) { 2780 for (i = 0; i <= end_zone; i++) {
2775 struct zone *zone = pgdat->node_zones + i; 2781 struct zone *zone = pgdat->node_zones + i;
2776 2782
2783 if (!populated_zone(zone))
2784 continue;
2785
2777 lru_pages += zone_reclaimable_pages(zone); 2786 lru_pages += zone_reclaimable_pages(zone);
2787
2788 /*
2789 * If any zone is currently balanced then kswapd will
2790 * not call compaction as it is expected that the
2791 * necessary pages are already available.
2792 */
2793 if (pgdat_needs_compaction &&
2794 zone_watermark_ok(zone, order,
2795 low_wmark_pages(zone),
2796 *classzone_idx, 0))
2797 pgdat_needs_compaction = false;
2778 } 2798 }
2779 2799
2780 /* 2800 /*
@@ -2843,7 +2863,8 @@ static unsigned long balance_pgdat(pg_data_t *pgdat, int order,
2843 * already being scanned that high 2863 * already being scanned that high
2844 * watermark would be met at 100% efficiency. 2864 * watermark would be met at 100% efficiency.
2845 */ 2865 */
2846 if (kswapd_shrink_zone(zone, &sc, lru_pages)) 2866 if (kswapd_shrink_zone(zone, &sc, lru_pages,
2867 &nr_attempted))
2847 raise_priority = false; 2868 raise_priority = false;
2848 } 2869 }
2849 2870
@@ -2896,6 +2917,13 @@ static unsigned long balance_pgdat(pg_data_t *pgdat, int order,
2896 break; 2917 break;
2897 2918
2898 /* 2919 /*
2920 * Compact if necessary and kswapd is reclaiming at least the
2921 * high watermark number of pages as requsted
2922 */
2923 if (pgdat_needs_compaction && sc.nr_reclaimed > nr_attempted)
2924 compact_pgdat(pgdat, order);
2925
2926 /*
2899 * Raise priority if scanning rate is too low or there was no 2927 * Raise priority if scanning rate is too low or there was no
2900 * progress in reclaiming pages 2928 * progress in reclaiming pages
2901 */ 2929 */
@@ -2904,33 +2932,6 @@ static unsigned long balance_pgdat(pg_data_t *pgdat, int order,
2904 } while (sc.priority >= 0 && 2932 } while (sc.priority >= 0 &&
2905 !pgdat_balanced(pgdat, order, *classzone_idx)); 2933 !pgdat_balanced(pgdat, order, *classzone_idx));
2906 2934
2907 /*
2908 * If kswapd was reclaiming at a higher order, it has the option of
2909 * sleeping without all zones being balanced. Before it does, it must
2910 * ensure that the watermarks for order-0 on *all* zones are met and
2911 * that the congestion flags are cleared. The congestion flag must
2912 * be cleared as kswapd is the only mechanism that clears the flag
2913 * and it is potentially going to sleep here.
2914 */
2915 if (order) {
2916 int zones_need_compaction = 1;
2917
2918 for (i = 0; i <= end_zone; i++) {
2919 struct zone *zone = pgdat->node_zones + i;
2920
2921 if (!populated_zone(zone))
2922 continue;
2923
2924 /* Check if the memory needs to be defragmented. */
2925 if (zone_watermark_ok(zone, order,
2926 low_wmark_pages(zone), *classzone_idx, 0))
2927 zones_need_compaction = 0;
2928 }
2929
2930 if (zones_need_compaction)
2931 compact_pgdat(pgdat, order);
2932 }
2933
2934out: 2935out:
2935 /* 2936 /*
2936 * Return the order we were reclaiming at so prepare_kswapd_sleep() 2937 * Return the order we were reclaiming at so prepare_kswapd_sleep()