Merge "mm: correct ALLOC_WMARK_MIN flag check for atomic allocations"

This commit is contained in:
qctecmdr 2020-04-11 13:28:33 -07:00 • committed by Gerrit - the friendly Code Review server
commit e814c38deb

View file

@ -2373,11 +2373,38 @@ static bool can_steal_fallback(unsigned int order, int start_mt)
return false;
}
static bool boost_eligible(struct zone *z)
{
unsigned long high_wmark, threshold;
unsigned long reclaim_eligible, free_pages;
high_wmark = z->_watermark[WMARK_HIGH];
reclaim_eligible = zone_page_state_snapshot(z, NR_ZONE_INACTIVE_FILE) +
zone_page_state_snapshot(z, NR_ZONE_ACTIVE_FILE);
free_pages = zone_page_state(z, NR_FREE_PAGES) -
zone_page_state(z, NR_FREE_CMA_PAGES);
threshold = high_wmark + (2 * mult_frac(high_wmark,
watermark_boost_factor, 10000));
/*
* Don't boost watermark If we are already low on memory where the
* boosting can simply put the watermarks at higher levels for a
* longer duration of time and thus the other users relied on the
* watermarks are forced to choose unintended decissions. If memory
* is so low, kswapd in normal mode should help.
*/
if (reclaim_eligible < threshold && free_pages < threshold)
return false;
return true;
}
static inline void boost_watermark(struct zone *zone)
{
unsigned long max_boost;
if (!watermark_boost_factor)
if (!watermark_boost_factor || !boost_eligible(zone))
return;
max_boost = mult_frac(zone->_watermark[WMARK_HIGH],
@ -3744,6 +3771,20 @@ retry:
}
mark = wmark_pages(zone, alloc_flags & ALLOC_WMARK_MASK);
/*
* Allow high, atomic, harder order-0 allocation requests
* to skip the ->watermark_boost for min watermark check.
* In doing so, check for:
* 1) ALLOC_WMARK_MIN - Allow to wake up kswapd in the
* slow path.
* 2) ALLOC_HIGH - Allow high priority requests.
* 3) ALLOC_HARDER - Allow (__GFP_ATOMIC && !__GFP_NOMEMALLOC),
* of the others.
*/
if (unlikely(!order && !(alloc_flags & ALLOC_WMARK_MASK) &&
(alloc_flags & (ALLOC_HARDER | ALLOC_HIGH)))) {
mark = zone->_watermark[WMARK_MIN];
}
if (!zone_watermark_fast(zone, order, mark,
ac_classzone_idx(ac), alloc_flags)) {
int ret;