• Roman Gushchin's avatar
    mm: memcontrol: avoid workload stalls when lowering memory.high · 536d3bf2
    Roman Gushchin authored
    Memory.high limit is implemented in a way such that the kernel penalizes
    all threads which are allocating a memory over the limit.  Forcing all
    threads into the synchronous reclaim and adding some artificial delays
    allows to slow down the memory consumption and potentially give some time
    for userspace oom handlers/resource control agents to react.
    
    It works nicely if the memory usage is hitting the limit from below,
    however it works sub-optimal if a user adjusts memory.high to a value way
    below the current memory usage.  It basically forces all workload threads
    (doing any memory allocations) into the synchronous reclaim and sleep.
    This makes the workload completely unresponsive for a long period of time
    and can also lead to a system-wide contention on lru locks.  It can happen
    even if the workload is not actually tight on memory and has, for example,
    a ton of cold pagecache.
    
    In the current implementation writing to memory.high causes an atomic
    update of page counter's high value followed by an attempt to reclaim
    enough memory to fit into the new limit.  To fix the problem described
    above, all we need is to change the order of execution: try to push the
    memory usage under the limit first, and only then set the new high limit.
    Reported-by: default avatarDomas Mituzas <domas@fb.com>
    Signed-off-by: default avatarRoman Gushchin <guro@fb.com>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Reviewed-by: default avatarShakeel Butt <shakeelb@google.com>
    Acked-by: default avatarMichal Hocko <mhocko@suse.com>
    Cc: Johannes Weiner <hannes@cmpxchg.org>
    Cc: Tejun Heo <tj@kernel.org>
    Cc: Chris Down <chris@chrisdown.name>
    Link: http://lkml.kernel.org/r/20200709194718.189231-1-guro@fb.comSigned-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    536d3bf2
memcontrol.c 189 KB