• Muchun Song's avatar
    mm: memcontrol: use obj_cgroup APIs to charge kmem pages · b4e0b68f
    Muchun Song authored
    Since Roman's series "The new cgroup slab memory controller" applied.
    All slab objects are charged via the new APIs of obj_cgroup.  The new
    APIs introduce a struct obj_cgroup to charge slab objects.  It prevents
    long-living objects from pinning the original memory cgroup in the
    memory.  But there are still some corner objects (e.g.  allocations
    larger than order-1 page on SLUB) which are not charged via the new
    APIs.  Those objects (include the pages which are allocated from buddy
    allocator directly) are charged as kmem pages which still hold a
    reference to the memory cgroup.
    
    We want to reuse the obj_cgroup APIs to charge the kmem pages.  If we do
    that, we should store an object cgroup pointer to page->memcg_data for
    the kmem pages.
    
    Finally, page->memcg_data will have 3 different meanings.
    
      1) For the slab pages, page->memcg_data points to an object cgroups
         vector.
    
      2) For the kmem pages (exclude the slab pages), page->memcg_data
         points to an object cgroup.
    
      3) For the user pages (e.g. the LRU pages), page->memcg_data points
         to a memory cgroup.
    
    We do not change the behavior of page_memcg() and page_memcg_rcu().  They
    are also suitable for LRU pages and kmem pages.  Why?
    
    Because memory allocations pinning memcgs for a long time - it exists at a
    larger scale and is causing recurring problems in the real world: page
    cache doesn't get reclaimed for a long time, or is used by the second,
    third, fourth, ...  instance of the same job that was restarted into a new
    cgroup every time.  Unreclaimable dying cgroups pile up, waste memory, and
    make page reclaim very inefficient.
    
    We can convert LRU pages and most other raw memcg pins to the objcg
    direction to fix this problem, and then the page->memcg will always point
    to an object cgroup pointer.  At that time, LRU pages and kmem pages will
    be treated the same.  The implementation of page_memcg() will remove the
    kmem page check.
    
    This patch aims to charge the kmem pages by using the new APIs of
    obj_cgroup.  Finally, the page->memcg_data of the kmem page points to an
    object cgroup.  We can use the __page_objcg() to get the object cgroup
    associated with a kmem page.  Or we can use page_memcg() to get the memory
    cgroup associated with a kmem page, but caller must ensure that the
    returned memcg won't be released (e.g.  acquire the rcu_read_lock or
    css_set_lock).
    
      Link: https://lkml.kernel.org/r/20210401030141.37061-1-songmuchun@bytedance.com
    
    Link: https://lkml.kernel.org/r/20210319163821.20704-6-songmuchun@bytedance.comSigned-off-by: default avatarMuchun Song <songmuchun@bytedance.com>
    Acked-by: default avatarJohannes Weiner <hannes@cmpxchg.org>
    Reviewed-by: default avatarShakeel Butt <shakeelb@google.com>
    Acked-by: default avatarRoman Gushchin <guro@fb.com>
    Reviewed-by: default avatarMiaohe Lin <linmiaohe@huawei.com>
    Cc: Michal Hocko <mhocko@kernel.org>
    Cc: Vladimir Davydov <vdavydov.dev@gmail.com>
    Cc: Xiongchun Duan <duanxiongchun@bytedance.com>
    Cc: Christian Borntraeger <borntraeger@de.ibm.com>
    [songmuchun@bytedance.com: fix forget to obtain the ref to objcg in split_page_memcg]
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    b4e0b68f
memcontrol.c 190 KB