- the incoming arg `nr_pages' should be used to determine if we're being
asked to free a specific number of pages, not `to_free'.
- local variable `to_free' is not appropriate for the determination of
whether we failed to bring all zones to appropriate free pages levels.
Fix this by correctly calculating `all_zones_ok' and then use
all_zones_ok to determine whether we need to throttle kswapd.
So the logic now is:
for (increasing priority) {
all_zones_ok = 1;
for (all zones) {
to_reclaim = number of pages to try to reclaim
from this zone;
max_scan = number of pages to scan in this pass
(gets larger as `priority' decreases)
/*
* set `reclaimed' to the number of pages which were
* actually freed up
*/
reclaimed = scan(max_scan pages);
reclaimed += shrink_slab();
to_free -= reclaimed; /* for the `nr_pages>0' case */
/*
* If this scan failed to reclaim `to_reclaim' or more
* pages, we're getting into trouble. Need to scan
* some more, and throttle kswapd. Note that this
* zone may now have sufficient free pages due to
* freeing activity by some other process. That's
* OK - we'll pick that info up on the next pass
* through the loop.
*/
if (reclaimed < to_reclaim)
all_zones_ok = 0;
}
if (to_free > 0)
continue; /* swsusp: need to do more work */
if (all_zones_ok)
break; /* kswapd is done */
/*
* OK, kswapd is getting into trouble. Take a nap, then take
* another pass across the zones.
*/
blk_congestion_wait();
}