mirror of
https://github.com/rd-stuffs/msm-4.14.git
synced 2025-02-20 11:45:48 +08:00
mm: Increment kswapd_waiters for throttled direct reclaimers
Throttled direct reclaimers will wake up kswapd and wait for kswapd to satisfy their page allocation request, even when the failed allocation lacks the __GFP_KSWAPD_RECLAIM flag in its gfp mask. As a result, kswapd may think that there are no waiters and thus exit prematurely, causing throttled direct reclaimers lacking __GFP_KSWAPD_RECLAIM to stall on waiting for kswapd to wake them up. Incrementing the kswapd_waiters counter when such direct reclaimers become throttled fixes the problem. Signed-off-by: Sultan Alsawaf <sultan@kerneltoast.com> Signed-off-by: Forenche <prahul2003@gmail.com>
This commit is contained in:
parent
4e5a138e49
commit
a4c99fe0d0
16
mm/vmscan.c
16
mm/vmscan.c
@ -3003,7 +3003,7 @@ retry:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool allow_direct_reclaim(pg_data_t *pgdat)
|
||||
static bool allow_direct_reclaim(pg_data_t *pgdat, bool using_kswapd)
|
||||
{
|
||||
struct zone *zone;
|
||||
unsigned long pfmemalloc_reserve = 0;
|
||||
@ -3032,6 +3032,10 @@ static bool allow_direct_reclaim(pg_data_t *pgdat)
|
||||
|
||||
wmark_ok = free_pages > pfmemalloc_reserve / 2;
|
||||
|
||||
/* The throttled direct reclaimer is now a kswapd waiter */
|
||||
if (unlikely(!using_kswapd && !wmark_ok))
|
||||
atomic_long_inc(&kswapd_waiters);
|
||||
|
||||
/* kswapd must be awake if processes are being throttled */
|
||||
if (!wmark_ok && waitqueue_active(&pgdat->kswapd_wait)) {
|
||||
if (READ_ONCE(pgdat->kswapd_classzone_idx) > ZONE_NORMAL)
|
||||
@ -3097,7 +3101,7 @@ static bool throttle_direct_reclaim(gfp_t gfp_mask, struct zonelist *zonelist,
|
||||
|
||||
/* Throttle based on the first usable node */
|
||||
pgdat = zone->zone_pgdat;
|
||||
if (allow_direct_reclaim(pgdat))
|
||||
if (allow_direct_reclaim(pgdat, gfp_mask & __GFP_KSWAPD_RECLAIM))
|
||||
goto out;
|
||||
break;
|
||||
}
|
||||
@ -3119,16 +3123,18 @@ static bool throttle_direct_reclaim(gfp_t gfp_mask, struct zonelist *zonelist,
|
||||
*/
|
||||
if (!(gfp_mask & __GFP_FS)) {
|
||||
wait_event_interruptible_timeout(pgdat->pfmemalloc_wait,
|
||||
allow_direct_reclaim(pgdat), HZ);
|
||||
allow_direct_reclaim(pgdat, true), HZ);
|
||||
|
||||
goto check_pending;
|
||||
}
|
||||
|
||||
/* Throttle until kswapd wakes the process */
|
||||
wait_event_killable(zone->zone_pgdat->pfmemalloc_wait,
|
||||
allow_direct_reclaim(pgdat));
|
||||
allow_direct_reclaim(pgdat, true));
|
||||
|
||||
check_pending:
|
||||
if (unlikely(!(gfp_mask & __GFP_KSWAPD_RECLAIM)))
|
||||
atomic_long_dec(&kswapd_waiters);
|
||||
if (fatal_signal_pending(current))
|
||||
return true;
|
||||
|
||||
@ -3503,7 +3509,7 @@ static int balance_pgdat(pg_data_t *pgdat, int order, int classzone_idx)
|
||||
* able to safely make forward progress. Wake them
|
||||
*/
|
||||
if (waitqueue_active(&pgdat->pfmemalloc_wait) &&
|
||||
allow_direct_reclaim(pgdat))
|
||||
allow_direct_reclaim(pgdat, true))
|
||||
wake_up_all(&pgdat->pfmemalloc_wait);
|
||||
|
||||
/* Check if kswapd should be suspending */
|
||||
|
Loading…
x
Reference in New Issue
Block a user