• Chengming Zhou's avatar
    mm/zswap: global lru and shrinker shared by all zswap_pools · bf9b7df2
    Chengming Zhou authored
    Patch series "mm/zswap: optimize for dynamic zswap_pools", v3.
    
    Dynamic pool creation has been supported for a long time, which maybe not
    used so much in practice.  But with the per-memcg lru merged, the current
    structure of zswap_pool's lru and shrinker become less optimal.
    
    In the current structure, each zswap_pool has its own lru, shrinker and
    shrink_work, but only the latest zswap_pool will be the current used.
    
    1. When memory has pressure, all shrinkers of zswap_pools will try to
       shrink its lru list, there is no order between them.
    
    2. When zswap limit hit, only the last zswap_pool's shrink_work will
       try to shrink its own lru, which is inefficient.
    
    A more natural way is to have a global zswap lru shared between all
    zswap_pools, and so is the shrinker. The code becomes much simpler too.
    
    Another optimization is changing zswap_pool kref to percpu_ref, which will
    be taken reference by every zswap entry.  So the scalability is better.
    
    Testing kernel build (32 threads) in tmpfs with memory.max=2GB.  (zswap
    shrinker and writeback enabled with one 50GB swapfile, on a 128 CPUs
    x86-64 machine, below is the average of 5 runs)
    
            mm-unstable  zswap-global-lru
    real    63.20        63.12
    user    1061.75      1062.95
    sys     268.74       264.44
    
    
    This patch (of 3):
    
    Dynamic zswap_pool creation may create/reuse to have multiple zswap_pools
    in a list, only the first will be current used.
    
    Each zswap_pool has its own lru and shrinker, which is not necessary and
    has its problem:
    
    1. When memory has pressure, all shrinker of zswap_pools will
       try to shrink its own lru, there is no order between them.
    
    2. When zswap limit hit, only the last zswap_pool's shrink_work
       will try to shrink its lru list. The rationale here was to
       try and empty the old pool first so that we can completely
       drop it. However, since we only support exclusive loads now,
       the LRU ordering should be entirely decided by the order of
       stores, so the oldest entries on the LRU will naturally be
       from the oldest pool.
    
    Anyway, having a global lru and shrinker shared by all zswap_pools is
    better and efficient.
    
    Link: https://lkml.kernel.org/r/20240210-zswap-global-lru-v3-0-200495333595@bytedance.com
    Link: https://lkml.kernel.org/r/20240210-zswap-global-lru-v3-1-200495333595@bytedance.comSigned-off-by: default avatarChengming Zhou <zhouchengming@bytedance.com>
    Acked-by: default avatarYosry Ahmed <yosryahmed@google.com>
    Cc: Johannes Weiner <hannes@cmpxchg.org>
    Cc: Nhat Pham <nphamcs@gmail.com>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    bf9b7df2
zswap.c 48.5 KB