Skip to content
  • Johannes Weiner's avatar
    mm: memcg: rework and document OOM waiting and wakeup · fb2a6fc5
    Johannes Weiner authored
    
    
    The memcg OOM handler open-codes a sleeping lock for OOM serialization
    (trylock, wait, repeat) because the required locking is so specific to
    memcg hierarchies.  However, it would be nice if this construct would be
    clearly recognizable and not be as obfuscated as it is right now.  Clean
    up as follows:
    
    1. Remove the return value of mem_cgroup_oom_unlock()
    
    2. Rename mem_cgroup_oom_lock() to mem_cgroup_oom_trylock().
    
    3. Pull the prepare_to_wait() out of the memcg_oom_lock scope.  This
       makes it more obvious that the task has to be on the waitqueue
       before attempting to OOM-trylock the hierarchy, to not miss any
       wakeups before going to sleep.  It just didn't matter until now
       because it was all lumped together into the global memcg_oom_lock
       spinlock section.
    
    4. Pull the mem_cgroup_oom_notify() out of the memcg_oom_lock scope.
       It is proctected by the hierarchical OOM-lock.
    
    5. The memcg_oom_lock spinlock is only required to propagate the OOM
       lock in any given hierarchy atomically.  Restrict its scope to
       mem_cgroup_oom_(trylock|unlock).
    
    6. Do not wake up the waitqueue unconditionally at the end of the
       function.  Only the lockholder has to wake up the next in line
       after releasing the lock.
    
       Note that the lockholder kicks off the OOM-killer, which in turn
       leads to wakeups from the uncharges of the exiting task.  But a
       contender is not guaranteed to see them if it enters the OOM path
       after the OOM kills but before the lockholder releases the lock.
       Thus there has to be an explicit wakeup after releasing the lock.
    
    7. Put the OOM task on the waitqueue before marking the hierarchy as
       under OOM as that is the point where we start to receive wakeups.
       No point in listening before being on the waitqueue.
    
    8. Likewise, unmark the hierarchy before finishing the sleep, for
       symmetry.
    
    Signed-off-by: default avatarJohannes Weiner <hannes@cmpxchg.org>
    Acked-by: default avatarMichal Hocko <mhocko@suse.cz>
    Cc: David Rientjes <rientjes@google.com>
    Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
    Cc: azurIt <azurit@pobox.sk>
    Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    fb2a6fc5