• Roman Gushchin's avatar
    mm, memcg: rework remote charging API to support nesting · b87d8cef
    Roman Gushchin authored
    Currently the remote memcg charging API consists of two functions:
    memalloc_use_memcg() and memalloc_unuse_memcg(), which set and clear the
    memcg value, which overwrites the memcg of the current task.
    
      memalloc_use_memcg(target_memcg);
      <...>
      memalloc_unuse_memcg();
    
    It works perfectly for allocations performed from a normal context,
    however an attempt to call it from an interrupt context or just nest two
    remote charging blocks will lead to an incorrect accounting.  On exit from
    the inner block the active memcg will be cleared instead of being
    restored.
    
      memalloc_use_memcg(target_memcg);
    
      memalloc_use_memcg(target_memcg_2);
        <...>
        memalloc_unuse_memcg();
    
        Error: allocation here are charged to the memcg of the current
        process instead of target_memcg.
    
      memalloc_unuse_memcg();
    
    This patch extends the remote charging API by switching to a single
    function: struct mem_cgroup *set_active_memcg(struct mem_cgroup *memcg),
    which sets the new value and returns the old one.  So a remote charging
    block will look like:
    
      old_memcg = set_active_memcg(target_memcg);
      <...>
      set_active_memcg(old_memcg);
    
    This patch is heavily based on the patch by Johannes Weiner, which can be
    found here: https://lkml.org/lkml/2020/5/28/806
    
     .
    
    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>
    Cc: Johannes Weiner <hannes@cmpxchg.org>
    Cc: Dan Schatzberg <dschatzberg@fb.com>
    Link: https://lkml.kernel.org/r/20200821212056.3769116-1-guro@fb.com
    
    
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    b87d8cef