Commit bbdb396a60b2ebf7de3b717991e5d3e28c8b7bbd
Committed by
Linus Torvalds
1 parent
3bb1a852ab
Exists in
master
and in
7 other branches
[PATCH] Use min of two prio settings in calculating distress for reclaim
If try_to_free_pages / balance_pgdat are called with a gfp_mask specifying GFP_IO and/or GFP_FS, they will reclaim the requisite number of pages, and the reset prev_priority to DEF_PRIORITY (or to some other high (ie: unurgent) value). However, another reclaimer without those gfp_mask flags set (say, GFP_NOIO) may still be struggling to reclaim pages. The concurrent overwrite of zone->prev_priority will cause this GFP_NOIO thread to unexpectedly cease deactivating mapped pages, thus causing reclaim difficulties. Fix this is to key the distress calculation not off zone->prev_priority, but also take into account the local caller's priority by using min(zone->prev_priority, sc->priority) Signed-off-by: Martin J. Bligh <mbligh@google.com> Cc: Nick Piggin <nickpiggin@yahoo.com.au> Cc: <stable@kernel.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Showing 1 changed file with 4 additions and 4 deletions Side-by-side Diff
mm/vmscan.c
... | ... | @@ -760,7 +760,7 @@ |
760 | 760 | * But we had to alter page->flags anyway. |
761 | 761 | */ |
762 | 762 | static void shrink_active_list(unsigned long nr_pages, struct zone *zone, |
763 | - struct scan_control *sc) | |
763 | + struct scan_control *sc, int priority) | |
764 | 764 | { |
765 | 765 | unsigned long pgmoved; |
766 | 766 | int pgdeactivate = 0; |
... | ... | @@ -784,7 +784,7 @@ |
784 | 784 | * `distress' is a measure of how much trouble we're having |
785 | 785 | * reclaiming pages. 0 -> no problems. 100 -> great trouble. |
786 | 786 | */ |
787 | - distress = 100 >> zone->prev_priority; | |
787 | + distress = 100 >> min(zone->prev_priority, priority); | |
788 | 788 | |
789 | 789 | /* |
790 | 790 | * The point of this algorithm is to decide when to start |
... | ... | @@ -936,7 +936,7 @@ |
936 | 936 | nr_to_scan = min(nr_active, |
937 | 937 | (unsigned long)sc->swap_cluster_max); |
938 | 938 | nr_active -= nr_to_scan; |
939 | - shrink_active_list(nr_to_scan, zone, sc); | |
939 | + shrink_active_list(nr_to_scan, zone, sc, priority); | |
940 | 940 | } |
941 | 941 | |
942 | 942 | if (nr_inactive) { |
... | ... | @@ -1384,7 +1384,7 @@ |
1384 | 1384 | if (zone->nr_scan_active >= nr_pages || pass > 3) { |
1385 | 1385 | zone->nr_scan_active = 0; |
1386 | 1386 | nr_to_scan = min(nr_pages, zone->nr_active); |
1387 | - shrink_active_list(nr_to_scan, zone, sc); | |
1387 | + shrink_active_list(nr_to_scan, zone, sc, prio); | |
1388 | 1388 | } |
1389 | 1389 | } |
1390 | 1390 |