• Roman Gushchin's avatar
    mm: memcg/slab: optimize objcg stock draining · 3de7d4f2
    Roman Gushchin authored
    Imran Khan reported a 16% regression in hackbench results caused by the
    commit f2fe7b09 ("mm: memcg/slab: charge individual slab objects
    instead of pages").  The regression is noticeable in the case of a
    consequent allocation of several relatively large slab objects, e.g.
    skb's.  As soon as the amount of stocked bytes exceeds PAGE_SIZE,
    drain_obj_stock() and __memcg_kmem_uncharge() are called, and it leads
    to a number of atomic operations in page_counter_uncharge().
    
    The corresponding call graph is below (provided by Imran Khan):
    
      |__alloc_skb
      |    |
      |    |__kmalloc_reserve.isra.61
      |    |    |
      |    |    |__kmalloc_node_track_caller
      |    |    |    |
      |    |    |    |slab_pre_alloc_hook.constprop.88
      |    |    |     obj_cgroup_charge
      |    |    |    |    |
      |    |    |    |    |__memcg_kmem_charge
      |    |    |    |    |    |
      |    |    |    |    |    |page_counter_try_charge
      |    |    |    |    |
      |    |    |    |    |refill_obj_stock
      |    |    |    |    |    |
      |    |    |    |    |    |drain_obj_stock.isra.68
      |    |    |    |    |    |    |
      |    |    |    |    |    |    |__memcg_kmem_uncharge
      |    |    |    |    |    |    |    |
      |    |    |    |    |    |    |    |page_counter_uncharge
      |    |    |    |    |    |    |    |    |
      |    |    |    |    |    |    |    |    |page_counter_cancel
      |    |    |    |
      |    |    |    |
      |    |    |    |__slab_alloc
      |    |    |    |    |
      |    |    |    |    |___slab_alloc
      |    |    |    |    |
      |    |    |    |slab_post_alloc_hook
    
    Instead of directly uncharging the accounted kernel memory, it's
    possible to refill the generic page-sized per-cpu stock instead.  It's a
    much faster operation, especially on a default hierarchy.  As a bonus,
    __memcg_kmem_uncharge_page() will also get faster, so the freeing of
    page-sized kernel allocations (e.g.  large kmallocs) will become faster.
    
    A similar change has been done earlier for the socket memory by the
    commit 475d0487 ("mm: memcontrol: use per-cpu stocks for socket
    memory uncharging").
    
    Link: https://lkml.kernel.org/r/20210106042239.2860107-1-guro@fb.com
    Fixes: f2fe7b09 ("mm: memcg/slab: charge individual slab objects instead of pages")
    Signed-off-by: default avatarRoman Gushchin <guro@fb.com>
    Reported-by: default avatarImran Khan <imran.f.khan@oracle.com>
    Tested-by: default avatarImran Khan <imran.f.khan@oracle.com>
    Reviewed-by: default avatarShakeel Butt <shakeelb@google.com>
    Reviewed-by: default avatarMichal Koutn <mkoutny@suse.com>
    Cc: Michal Koutný <mkoutny@suse.com>
    Cc: Johannes Weiner <hannes@cmpxchg.org>
    Cc: <stable@vger.kernel.org>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    3de7d4f2
memcontrol.c 190 KB