]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
mm: add swappiness=max arg to memory.reclaim for only anon reclaim
authorZhongkun He <hezhongkun.hzk@bytedance.com>
Mon, 21 Apr 2025 09:13:28 +0000 (17:13 +0800)
committerAndrew Morton <akpm@linux-foundation.org>
Tue, 13 May 2025 06:50:35 +0000 (23:50 -0700)
Patch series "add max arg to swappiness in memory.reclaim and lru_gen", v4.

This patchset adds max arg to swappiness in memory.reclaim and lru_gen for
anon only proactive memory reclaim.

With commit <68cd9050d871> ("mm: add swappiness= arg to memory.reclaim")
we can submit an additional swappiness=<val> argument to memory.reclaim.
It is very useful because we can dynamically adjust the reclamation ratio
based on the anonymous folios and file folios of each cgroup.  For
example,when swappiness is set to 0, we only reclaim from file folios.
But we can not relciam memory just from anon folios.

This patchset introduces a new macro, SWAPPINESS_ANON_ONLY, defined as
MAX_SWAPPINESS + 1, represent the max arg semantics.  It specifically
indicates that reclamation should occur only from anonymous pages.

Patch 1 adds swappiness=max arg to memory.reclaim suggested-by: Yosry
Ahmed

Patch 2 add more comments for cache_trim_mode from Johannes Weiner in [1].

Patch 3 add max arg to lru_gen for proactive memory reclaim in MGLRU.  The
MGLRU already supports reclaiming exclusively from anonymous pages.  This
patch formalizes that behavior by introducing a max parameter to represent
the corresponding semantics.

Patch 4 using SWAPPINESS_ANON_ONLY in MGLRU Using SWAPPINESS_ANON_ONLY
instead of MAX_SWAPPINESS + 1 to indicate reclaiming only from anonymous
pages makes the code more readable and explicit

Here is the previous discussion:
https://lore.kernel.org/all/20250314033350.1156370-1-hezhongkun.hzk@bytedance.com/
https://lore.kernel.org/all/20250312094337.2296278-1-hezhongkun.hzk@bytedance.com/
https://lore.kernel.org/all/20250318135330.3358345-1-hezhongkun.hzk@bytedance.com/

This patch (of 4):

With commit <68cd9050d871> ("mm: add swappiness= arg to memory.reclaim")
we can submit an additional swappiness=<val> argument to memory.reclaim.
It is very useful because we can dynamically adjust the reclamation ratio
based on the anonymous folios and file folios of each cgroup.  For
example,when swappiness is set to 0, we only reclaim from file folios.

However,we have also encountered a new issue: when swappiness is set to
the MAX_SWAPPINESS, it may still only reclaim file folios.

So, we hope to add a new arg 'swappiness=max' in memory.reclaim where
proactive memory reclaim only reclaims from anonymous folios when
swappiness is set to max.  The swappiness semantics from a user
perspective remain unchanged.

For example, something like this:

echo "2M swappiness=max" > /sys/fs/cgroup/memory.reclaim

will perform reclaim on the rootcg with a swappiness setting of 'max' (a
new mode) regardless of the file folios.  Users have a more comprehensive
view of the application's memory distribution because there are many
metrics available.  For example, if we find that a certain cgroup has a
large number of inactive anon folios, we can reclaim only those and skip
file folios, because with the zram/zswap, the IO tradeoff that
cache_trim_mode or other file first logic is making doesn't hold - file
refaults will cause IO, whereas anon decompression will not.

With this patch, the swappiness argument of memory.reclaim has a new
mode 'max', means reclaiming just from anonymous folios both in traditional
LRU and MGLRU.

Link: https://lkml.kernel.org/r/cover.1745225696.git.hezhongkun.hzk@bytedance.com
Link: https://lore.kernel.org/all/20250314141833.GA1316033@cmpxchg.org/
Link: https://lkml.kernel.org/r/519e12b9b1f8c31a01e228c8b4b91a2419684f77.1745225696.git.hezhongkun.hzk@bytedance.com
Signed-off-by: Zhongkun He <hezhongkun.hzk@bytedance.com>
Suggested-by: Yosry Ahmed <yosry.ahmed@linux.dev>
Acked-by: Muchun Song <muchun.song@linux.dev>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Yu Zhao <yuzhao@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Documentation/admin-guide/cgroup-v2.rst
include/linux/swap.h
mm/memcontrol.c
mm/vmscan.c

index d537f3d3fed9876d9d2619a00295a65ad11beb59..acf855851c03c18150fbe8cf25b542ef780cd611 100644 (file)
@@ -1372,6 +1372,9 @@ The following nested keys are defined.
        same semantics as vm.swappiness applied to memcg reclaim with
        all the existing limitations and potential future extensions.
 
+       The valid range for swappiness is [0-200, max], setting
+       swappiness=max exclusively reclaims anonymous memory.
+
   memory.peak
        A read-write single value file which exists on non-root cgroups.
 
index 4e4e27d3ce3ddbcd54127bca222fecc86b32b16d..bc0e1c275fc0478e55eb326ed8d273300d86deb0 100644 (file)
@@ -414,6 +414,10 @@ extern unsigned long try_to_free_pages(struct zonelist *zonelist, int order,
 #define MEMCG_RECLAIM_PROACTIVE (1 << 2)
 #define MIN_SWAPPINESS 0
 #define MAX_SWAPPINESS 200
+
+/* Just recliam from anon folios in proactive memory reclaim */
+#define SWAPPINESS_ANON_ONLY (MAX_SWAPPINESS + 1)
+
 extern unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *memcg,
                                                  unsigned long nr_pages,
                                                  gfp_t gfp_mask,
index d3b6f50e00d47fcdf26d199e7daa7cc526288147..4108ff00124bb5b60131f7e9a95512dfd2f16087 100644 (file)
@@ -4474,11 +4474,13 @@ static ssize_t memory_oom_group_write(struct kernfs_open_file *of,
 
 enum {
        MEMORY_RECLAIM_SWAPPINESS = 0,
+       MEMORY_RECLAIM_SWAPPINESS_MAX,
        MEMORY_RECLAIM_NULL,
 };
 
 static const match_table_t tokens = {
        { MEMORY_RECLAIM_SWAPPINESS, "swappiness=%d"},
+       { MEMORY_RECLAIM_SWAPPINESS_MAX, "swappiness=max"},
        { MEMORY_RECLAIM_NULL, NULL },
 };
 
@@ -4512,6 +4514,9 @@ static ssize_t memory_reclaim(struct kernfs_open_file *of, char *buf,
                        if (swappiness < MIN_SWAPPINESS || swappiness > MAX_SWAPPINESS)
                                return -EINVAL;
                        break;
+               case MEMORY_RECLAIM_SWAPPINESS_MAX:
+                       swappiness = SWAPPINESS_ANON_ONLY;
+                       break;
                default:
                        return -EINVAL;
                }
index a4fbd52a82d45a939ccf87d36c2458f893da83a8..495889f621b5598d48a3f80213c19fee3b3f820d 100644 (file)
@@ -2509,6 +2509,13 @@ static void get_scan_count(struct lruvec *lruvec, struct scan_control *sc,
                goto out;
        }
 
+       /* Proactive reclaim initiated by userspace for anonymous memory only */
+       if (swappiness == SWAPPINESS_ANON_ONLY) {
+               WARN_ON_ONCE(!sc->proactive);
+               scan_balance = SCAN_ANON;
+               goto out;
+       }
+
        /*
         * Do not apply any pressure balancing cleverness when the
         * system is close to OOM, scan both anon and file equally