[PATCH 01 of 13] limit shrink zone scanning

Andrea Arcangeli
2008-01-08T07:50:32Z

# Date 1199469588 -3600
# Node ID 31ccca6f0b3ee1b340b9d32c0231eb1f957ee1ad
# Parent e28e1be3fae5183e3e36e32e3feb9a59ec59c825
limit shrink zone scanning

Assume two tasks adds to nr_scan_*active at the same time (first line of the
old buggy code), they'll effectively double their scan rate, for no good
reason. What can happen is that instead of scanning nr_entries each, they'll
scan nr_entries*2 each. The more CPUs the bigger the race and the higher the
multiplication effect and the harder it will be to detect oom. This puts a cap
on the amount of work that it makes sense to do in case the race triggers.

Signed-off-by: Andrea Arcangeli <andrea@suse.de>

diff --git a/mm/vmscan.c b/mm/vmscan.c
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -1114,7 +1114,7 @@ static unsigned long shrink_zone(int pri
*/
zone->nr_scan_active +=
(zone_page_state(zone, NR_ACTIVE) >> priority) + 1;
- nr_active = zone->nr_scan_active;
+ nr_active = min(zone->nr_scan_active, zone_page_state(zone, NR_ACTIVE));
if (nr_active >= sc->swap_cluster_max)
zone->nr_scan_active = 0;
else
@@ -1122,7 +1122,7 @@ static unsigned long shrink_zone(int pri

zone->nr_scan_inactive +=
(zone_page_state(zone, NR_INACTIVE) >> priority) + 1;
- nr_inactive = zone->nr_scan_inactive;
+ nr_inactive = min(zone->nr_scan_inactive, zone_page_state(zone, NR_INACTIVE));
if (nr_inactive >= sc->swap_cluster_max)
zone->nr_scan_inactive = 0;
else