Re: How to handle TIF_MEMDIE stalls?

Tetsuo Handa
2015-03-04T12:41:13Z

Dave Chinner wrote:
> On Fri, Feb 27, 2015 at 09:42:55PM +0900, Tetsuo Handa wrote:
> > If kswapd0 is blocked forever at e.g. mutex_lock() inside shrinker
> > functions, who else can make forward progress?
>
> You can't get into these filesystem shrinkers when you do GFP_NOIO
> allocations, as the IO path does.
>
> > Shouldn't we avoid calling functions which could potentially block for
> > unpredictable duration (e.g. unkillable locks and/or completion) from
> > shrinker functions?
>
> No, because otherwise we can't throttle allocation and reclaim to
> the rate at which IO can clean dirty objects. i.e. we do this for
> the same reason we throttle page cache dirtying to the rate at which
> we can clean dirty pages....

I'm misunderstanding something. The description for kswapd() function
in mm/vmscan.c says "This basically trickles out pages so that we have
_some_ free memory available even if there is no other activity that frees
anything up".

Forever blocking kswapd0 somewhere inside filesystem shrinker functions is
equivalent with removing kswapd() function because it also prevents non
filesystem shrinker functions from being called by kswapd0, doesn't it?
Then, the description will become "We won't have _some_ free memory available
if there is no other activity that frees anything up", won't it?

Does kswapd0 exist only for reducing the delay caused by reclaiming
synchronously? Disabling kswapd0 affects nothing about functionality?
The system can make forward progress even if nobody can call non filesystem
shrinkers, can't it?

If yes, then why do we need to make special handling for
excluding kswapd0 at

while (unlikely(too_many_isolated(zone, file, sc))) {
congestion_wait(BLK_RW_ASYNC, HZ/10);

/* We are about to die and free our memory. Return now. */
if (fatal_signal_pending(current))
return SWAP_CLUSTER_MAX;
}

loop inside shrink_inactive_list() ?

I can't understand the difference between "kswapd0 sleeping forever at
too_many_isolated() loop inside shrink_inactive_list()" and "kswapd0
sleeping forever at mutex_lock() inside xfs_reclaim_inodes_ag()".