From: Andrew Morton <akpm@linux-foundation.org>
To: mm-commits@vger.kernel.org,shakeel.butt@linux.dev,roman.gushchin@linux.dev,muchun.song@linux.dev,mhocko@kernel.org,hughd@google.com,hannes@cmpxchg.org,david@kernel.org,brauner@kernel.org,baolin.wang@linux.alibaba.com,zhengqi.arch@bytedance.com,akpm@linux-foundation.org
Subject: + mm-shmem-make-unused-huge-shrinker-memcg-aware.patch added to mm-new branch
Date: Fri, 28 Aug 2026 11:46:18 -0700 [thread overview]
Message-ID: <20260828184618.C5AAD1F000E9@smtp.kernel.org> (raw)
The patch titled
Subject: mm: shmem: make unused huge shrinker memcg aware
has been added to the -mm mm-new branch. Its filename is
mm-shmem-make-unused-huge-shrinker-memcg-aware.patch
This patch will shortly appear at
https://git.kernel.org/pub/scm/linux/kernel/git/akpm/25-new.git/tree/patches/mm-shmem-make-unused-huge-shrinker-memcg-aware.patch
This patch will later appear in the mm-new branch at
git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
Note, mm-new is a provisional staging ground for work-in-progress
patches, and acceptance into mm-new is a notification for others take
notice and to finish up reviews. Please do not hesitate to respond to
review feedback and post updated versions to replace or incrementally
fixup patches in mm-new.
The mm-new branch of mm.git is not included in linux-next
If a few days of testing in mm-new is successful, the patch will me moved
into mm.git's mm-unstable branch, which is included in linux-next
Before you just go and hit "reply", please:
a) Consider who else should be cc'ed
b) Prefer to cc a suitable mailing list as well
c) Ideally: find the original patch on the mailing list and do a
reply-to-all to that, adding suitable additional cc's
*** Remember to use Documentation/process/submit-checklist.rst when testing your code ***
The -mm tree is included into linux-next via various
branches at git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
and is updated there most days
------------------------------------------------------
From: Qi Zheng <zhengqi.arch@bytedance.com>
Subject: mm: shmem: make unused huge shrinker memcg aware
Date: Mon, 17 Aug 2026 17:03:28 +0800
The shmem unused huge shrinker keeps a per-superblock list of inodes whose
tail huge folio extends beyond i_size. Since that list is not memcg
aware, reclaim triggered by one memcg can scan inodes from the whole
superblock and split shmem huge folios charged to unrelated memcgs.
Convert the shrink list to a memcg-aware list_lru. Queue each inode on
the list_lru sublist matching the memcg and node of the current tail huge
folio, so non-root memcg reclaim only walks candidates charged to the
reclaiming memcg. Global reclaim, root memcg reclaim and shmem quota
reclaim keep global semantics.
Rather than pinning a struct mem_cgroup reference in shmem_inode_info,
store a struct obj_cgroup reference instead. The list_lru add and delete
paths resolve the current memcg from the objcg under RCU, so that memcg
offline and list_lru entry migration remain consistent: list_lru migrates
entries to the parent memcg sublist on offline, and obj_cgroup_memcg()
follows the same reparenting, ensuring the correct sublist is always found
at delete time. This avoids pinning a dying memcg through a long-lived
CSS reference.
The list_lru still tracks inodes while the actual split target is the
current tail huge folio, so validate the folio memcg/node during scan. If
the folio no longer matches the reclaim context or splitting cannot
proceed, requeue the inode according to the current tail folio; if the
inode is no longer shrinkable, drop the scan entry.
This can be tested with the shrinker debugfs interface by allocating 32
tmpfs tail THPs in each of two memcgs, then scanning the sb-tmpfs shrinker
with memcg A's cgroup id:
before A scan after A scan
base A=64M, B=64M A=64M, B=64M (per-memcg count is skipped)
patched A=64M, B=64M A=0, B=64M
Link: https://lore.kernel.org/94cc7fe1fd645254ae90effc1c0687678438d940.1786955972.git.zhengqi.arch@bytedance.com
Signed-off-by: Qi Zheng <zhengqi.arch@bytedance.com>
Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com>
Cc: Christian Brauner <brauner@kernel.org>
Cc: David Hildenbrand <david@kernel.org>
Cc: Hugh Dickins <hughd@google.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: Roman Gushchin <roman.gushchin@linux.dev>
Cc: Shakeel Butt <shakeel.butt@linux.dev>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---
include/linux/shmem_fs.h | 12 -
mm/shmem.c | 362 ++++++++++++++++++++++++++++---------
2 files changed, 289 insertions(+), 85 deletions(-)
--- a/include/linux/shmem_fs.h~mm-shmem-make-unused-huge-shrinker-memcg-aware
+++ a/include/linux/shmem_fs.h
@@ -11,6 +11,7 @@
#include <linux/fs_parser.h>
#include <linux/userfaultfd_k.h>
#include <linux/bits.h>
+#include <linux/list_lru.h>
/* inode in-kernel data */
@@ -54,6 +55,11 @@ struct shmem_inode_info {
struct dquot __rcu *i_dquot[MAXQUOTAS];
#endif
struct inode vfs_inode;
+
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+ struct obj_cgroup *shrinklist_objcg;
+ int shrinklist_nid;
+#endif
};
#define SHMEM_FL_USER_VISIBLE (FS_FL_USER_VISIBLE | FS_CASEFOLD_FL)
@@ -83,9 +89,9 @@ struct shmem_sb_info {
ino_t next_ino; /* The next per-sb inode number to use */
ino_t __percpu *ino_batch; /* The next per-cpu inode number to use */
struct mempolicy *mpol; /* default memory policy for mappings */
- spinlock_t shrinklist_lock; /* Protects shrinklist */
- struct list_head shrinklist; /* List of shinkable inodes */
- unsigned long shrinklist_len; /* Length of shrinklist */
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+ struct list_lru shrinklist; /* List of shrinkable inodes */
+#endif
struct shmem_quota_limits qlimits; /* Default quota limits */
struct simple_xattr_cache xa_cache;
};
--- a/mm/shmem.c~mm-shmem-make-unused-huge-shrinker-memcg-aware
+++ a/mm/shmem.c
@@ -725,51 +725,258 @@ static const char *shmem_format_huge(int
}
#endif
-static unsigned long shmem_unused_huge_shrink(struct shmem_sb_info *sbinfo,
- struct shrink_control *sc, unsigned long nr_to_free)
+static bool is_shmem_unused_huge_isolated(struct shmem_inode_info *info)
{
- LIST_HEAD(list), *pos, *next;
- struct inode *inode;
+
+ return info->shrinklist_nid == -1;
+}
+
+static void set_shmem_unused_huge_isolated(struct shmem_inode_info *info)
+{
+ info->shrinklist_nid = -1;
+}
+
+static struct obj_cgroup *shmem_get_and_clear_objcg(struct shmem_inode_info *info)
+{
+ struct obj_cgroup *objcg = info->shrinklist_objcg;
+
+ info->shrinklist_objcg = NULL;
+
+ return objcg;
+}
+
+#ifdef CONFIG_MEMCG
+static struct obj_cgroup *
+shmem_unused_huge_alloc_lru(struct shmem_sb_info *sbinfo, struct folio *folio,
+ gfp_t gfp)
+{
+ int ret;
+
+ ret = folio_memcg_list_lru_alloc(folio, &sbinfo->shrinklist, gfp);
+ if (ret)
+ return ERR_PTR(ret);
+
+ return get_obj_cgroup_from_folio(folio);
+}
+#else
+static struct obj_cgroup *
+shmem_unused_huge_alloc_lru(struct shmem_sb_info *sbinfo, struct folio *folio,
+ gfp_t gfp)
+{
+ return NULL;
+}
+#endif
+
+static void shmem_unused_huge_lru_add(struct shmem_sb_info *sbinfo,
+ struct list_head *item, int nid,
+ struct obj_cgroup *objcg)
+{
+ struct mem_cgroup *memcg;
+
+ rcu_read_lock();
+ memcg = obj_cgroup_memcg(objcg);
+ list_lru_add(&sbinfo->shrinklist, item, nid, memcg);
+ rcu_read_unlock();
+}
+
+static void shmem_unused_huge_lru_del(struct shmem_sb_info *sbinfo,
+ struct list_head *item, int nid,
+ struct obj_cgroup *objcg)
+{
+ struct mem_cgroup *memcg;
+
+ rcu_read_lock();
+ memcg = obj_cgroup_memcg(objcg);
+ list_lru_del(&sbinfo->shrinklist, item, nid, memcg);
+ rcu_read_unlock();
+}
+
+static void shmem_unused_huge_add(struct inode *inode, struct folio *folio,
+ gfp_t gfp)
+{
+ struct shmem_inode_info *info = SHMEM_I(inode);
+ struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb);
+ int nid = folio_nid(folio);
+ struct obj_cgroup *objcg = NULL, *old_objcg = NULL;
+
+ objcg = shmem_unused_huge_alloc_lru(sbinfo, folio, gfp);
+ if (IS_ERR(objcg))
+ return;
+
+ spin_lock(&info->lock);
+ if (!list_empty(&info->shrinklist)) {
+ /* isolated on scan list, let shrink handle it */
+ if (is_shmem_unused_huge_isolated(info))
+ goto unlock;
+
+ if (info->shrinklist_nid == nid &&
+ info->shrinklist_objcg == objcg)
+ goto unlock;
+
+ shmem_unused_huge_lru_del(sbinfo, &info->shrinklist,
+ info->shrinklist_nid,
+ info->shrinklist_objcg);
+ old_objcg = shmem_get_and_clear_objcg(info);
+ }
+
+ info->shrinklist_objcg = objcg;
+ info->shrinklist_nid = nid;
+ shmem_unused_huge_lru_add(sbinfo, &info->shrinklist, nid, objcg);
+ objcg = NULL;
+unlock:
+ spin_unlock(&info->lock);
+ obj_cgroup_put(old_objcg);
+ obj_cgroup_put(objcg);
+}
+
+static void shmem_unused_huge_del(struct inode *inode)
+{
+ struct shmem_inode_info *info = SHMEM_I(inode);
+ struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb);
+ struct obj_cgroup *objcg = NULL;
+
+ spin_lock(&info->lock);
+ if (!list_empty(&info->shrinklist)) {
+ shmem_unused_huge_lru_del(sbinfo, &info->shrinklist,
+ info->shrinklist_nid,
+ info->shrinklist_objcg);
+ objcg = shmem_get_and_clear_objcg(info);
+ }
+ spin_unlock(&info->lock);
+
+ obj_cgroup_put(objcg);
+}
+
+struct shmem_unused_huge_scan {
+ struct list_head list;
+ struct shrink_control *sc;
+};
+
+static enum lru_status shmem_unused_huge_isolate(struct list_head *item,
+ struct list_lru_one *lru,
+ void *arg)
+{
+ struct shmem_unused_huge_scan *scan = arg;
struct shmem_inode_info *info;
- struct folio *folio;
- unsigned long batch = sc ? sc->nr_to_scan : 128;
- unsigned long split = 0, freed = 0;
+ struct inode *inode;
+ struct obj_cgroup *objcg = NULL;
- if (list_empty(&sbinfo->shrinklist))
- return SHRINK_STOP;
+ info = list_entry(item, struct shmem_inode_info, shrinklist);
- spin_lock(&sbinfo->shrinklist_lock);
- list_for_each_safe(pos, next, &sbinfo->shrinklist) {
- info = list_entry(pos, struct shmem_inode_info, shrinklist);
+ /*
+ * Use trylock to avoid ABBA deadlock: add/del path takes info->lock
+ * before the list_lru bucket lock, while here the order is reversed.
+ */
+ if (!spin_trylock(&info->lock))
+ return LRU_SKIP;
- /* pin the inode */
- inode = igrab(&info->vfs_inode);
+ /* pin the inode */
+ inode = igrab(&info->vfs_inode);
+ /* inode is about to be evicted */
+ if (!inode) {
+ list_lru_isolate(lru, item);
+ objcg = shmem_get_and_clear_objcg(info);
+ spin_unlock(&info->lock);
+ obj_cgroup_put(objcg);
+ return LRU_REMOVED;
+ }
- /* inode is about to be evicted */
- if (!inode) {
- list_del_init(&info->shrinklist);
- goto next;
- }
+ list_lru_isolate(lru, item);
+ objcg = shmem_get_and_clear_objcg(info);
+ set_shmem_unused_huge_isolated(info);
+ list_add_tail(&info->shrinklist, &scan->list);
+ spin_unlock(&info->lock);
+ obj_cgroup_put(objcg);
- list_move(&info->shrinklist, &list);
-next:
- sbinfo->shrinklist_len--;
- if (!--batch)
- break;
+ return LRU_REMOVED;
+}
+
+static bool is_shmem_unused_huge_match(struct folio *folio,
+ struct shrink_control *sc)
+{
+ struct mem_cgroup *memcg = NULL;
+ bool match;
+
+ /* shmem quota reclaim has no NUMA node or memcg restriction */
+ if (!sc)
+ return true;
+
+ if (folio_nid(folio) != sc->nid)
+ return false;
+
+ /*
+ * Only non-root memcg reclaim needs to match the folio charge against
+ * sc->memcg. Skip the folio memcg check for global shrinker reclaim and
+ * root memcg reclaim.
+ */
+ if (!sc->memcg || mem_cgroup_is_root(sc->memcg))
+ return true;
+
+ memcg = get_mem_cgroup_from_folio(folio);
+ match = memcg == sc->memcg;
+ mem_cgroup_put(memcg);
+
+ return match;
+}
+
+static void shmem_unused_huge_drop(struct inode *inode)
+{
+ struct shmem_inode_info *info = SHMEM_I(inode);
+
+ spin_lock(&info->lock);
+ list_del_init(&info->shrinklist);
+ spin_unlock(&info->lock);
+}
+
+static void shmem_unused_huge_requeue(struct inode *inode, struct folio *folio)
+{
+ struct shmem_inode_info *info = SHMEM_I(inode);
+ struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb);
+ struct obj_cgroup *objcg;
+ int nid = folio_nid(folio);
+
+ objcg = shmem_unused_huge_alloc_lru(sbinfo, folio, GFP_NOWAIT);
+ if (IS_ERR(objcg)) {
+ shmem_unused_huge_drop(inode);
+ return;
}
- spin_unlock(&sbinfo->shrinklist_lock);
- list_for_each_safe(pos, next, &list) {
- pgoff_t next, end;
+ spin_lock(&info->lock);
+ /* Requeue the inode to shrinklist */
+ list_del_init(&info->shrinklist);
+ shmem_unused_huge_lru_add(sbinfo, &info->shrinklist, nid, objcg);
+ info->shrinklist_objcg = objcg;
+ info->shrinklist_nid = nid;
+ spin_unlock(&info->lock);
+}
+
+static unsigned long shmem_unused_huge_shrink(struct shmem_sb_info *sbinfo,
+ struct shrink_control *sc, unsigned long nr_to_free)
+{
+ struct shmem_unused_huge_scan scan;
+ struct inode *inode;
+ struct shmem_inode_info *info;
+ struct folio *folio;
+ struct list_head *pos, *next;
+ unsigned long split = 0, freed = 0;
+
+ INIT_LIST_HEAD(&scan.list);
+ scan.sc = sc;
+ if (sc)
+ list_lru_shrink_walk(&sbinfo->shrinklist, sc,
+ shmem_unused_huge_isolate, &scan);
+ else
+ list_lru_walk(&sbinfo->shrinklist, shmem_unused_huge_isolate,
+ &scan, 128);
+
+ list_for_each_safe(pos, next, &scan.list) {
+ pgoff_t folio_end, end;
loff_t i_size;
int ret;
info = list_entry(pos, struct shmem_inode_info, shrinklist);
inode = &info->vfs_inode;
- if (nr_to_free && freed >= nr_to_free)
- goto move_back;
-
i_size = i_size_read(inode);
folio = filemap_get_entry(inode->i_mapping, i_size / PAGE_SIZE);
if (!folio || xa_is_value(folio))
@@ -782,13 +989,19 @@ next:
}
/* Check if there is anything to gain from splitting */
- next = folio_next_index(folio);
+ folio_end = folio_next_index(folio);
end = shmem_fallocend(inode, DIV_ROUND_UP(i_size, PAGE_SIZE));
- if (end <= folio->index || end >= next) {
+ if (end <= folio->index || end >= folio_end) {
folio_put(folio);
goto drop;
}
+ if (!is_shmem_unused_huge_match(folio, scan.sc))
+ goto move_back;
+
+ if (nr_to_free && freed >= nr_to_free)
+ goto move_back;
+
/*
* Move the inode on the list back to shrinklist if we failed
* to lock the page at this time.
@@ -796,35 +1009,30 @@ next:
* Waiting for the lock may lead to deadlock in the
* reclaim path.
*/
- if (!folio_trylock(folio)) {
- folio_put(folio);
+ if (!folio_trylock(folio))
+ goto move_back;
+
+ if (!is_shmem_unused_huge_match(folio, scan.sc)) {
+ folio_unlock(folio);
goto move_back;
}
ret = split_folio(folio);
folio_unlock(folio);
- folio_put(folio);
/* If split failed move the inode on the list back to shrinklist */
if (ret)
goto move_back;
- freed += next - end;
+ freed += folio_end - end;
split++;
+ folio_put(folio);
drop:
- list_del_init(&info->shrinklist);
+ shmem_unused_huge_drop(inode);
goto put;
move_back:
- /*
- * Make sure the inode is either on the global list or deleted
- * from any local list before iput() since it could be deleted
- * in another thread once we put the inode (then the local list
- * is corrupted).
- */
- spin_lock(&sbinfo->shrinklist_lock);
- list_move(&info->shrinklist, &sbinfo->shrinklist);
- sbinfo->shrinklist_len++;
- spin_unlock(&sbinfo->shrinklist_lock);
+ shmem_unused_huge_requeue(inode, folio);
+ folio_put(folio);
put:
iput(inode);
}
@@ -837,7 +1045,7 @@ static long shmem_unused_huge_scan(struc
{
struct shmem_sb_info *sbinfo = SHMEM_SB(sb);
- if (!READ_ONCE(sbinfo->shrinklist_len))
+ if (!list_lru_shrink_count(&sbinfo->shrinklist, sc))
return SHRINK_STOP;
return shmem_unused_huge_shrink(sbinfo, sc, 0);
@@ -848,21 +1056,21 @@ static long shmem_unused_huge_count(stru
{
struct shmem_sb_info *sbinfo = SHMEM_SB(sb);
- /*
- * The per-superblock shrinklist is filesystem-global and does not
- * honour sc->memcg, so it is only meaningful on the global (kswapd or
- * root direct reclaim) shrink path. Skip the per-memcg iterations of
- * shrink_slab_memcg() to avoid queueing duplicate global work.
- */
- if (!mem_cgroup_shrink_is_root(sc))
- return 0;
-
- return READ_ONCE(sbinfo->shrinklist_len);
+ return list_lru_shrink_count(&sbinfo->shrinklist, sc);
}
#else /* !CONFIG_TRANSPARENT_HUGEPAGE */
#define shmem_huge SHMEM_HUGE_DENY
+static void shmem_unused_huge_add(struct inode *inode, struct folio *folio,
+ gfp_t gfp)
+{
+}
+
+static void shmem_unused_huge_del(struct inode *inode)
+{
+}
+
static unsigned long shmem_unused_huge_shrink(struct shmem_sb_info *sbinfo,
struct shrink_control *sc, unsigned long nr_to_free)
{
@@ -1418,14 +1626,7 @@ static void shmem_evict_inode(struct ino
inode->i_size = 0;
mapping_set_exiting(inode->i_mapping);
shmem_truncate_range(inode, 0, (loff_t)-1);
- if (!list_empty(&info->shrinklist)) {
- spin_lock(&sbinfo->shrinklist_lock);
- if (!list_empty(&info->shrinklist)) {
- list_del_init(&info->shrinklist);
- sbinfo->shrinklist_len--;
- }
- spin_unlock(&sbinfo->shrinklist_lock);
- }
+ shmem_unused_huge_del(inode);
while (!list_empty(&info->swaplist)) {
/* Wait while shmem_unuse() is scanning this inode... */
wait_var_event(&info->stop_eviction,
@@ -2573,25 +2774,12 @@ clear:
*/
if (alloced && folio_test_large(folio) &&
DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE) < folio_next_index(folio)) {
- struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb);
- struct shmem_inode_info *info = SHMEM_I(inode);
/*
* Part of the large folio is beyond i_size: subject
* to shrink under memory pressure.
*/
- spin_lock(&sbinfo->shrinklist_lock);
- /*
- * _careful to defend against unlocked access to
- * ->shrink_list in shmem_unused_huge_shrink()
- */
- if (list_empty_careful(&info->shrinklist)) {
- list_add_tail(&info->shrinklist,
- &sbinfo->shrinklist);
- sbinfo->shrinklist_len++;
- }
- spin_unlock(&sbinfo->shrinklist_lock);
+ shmem_unused_huge_add(inode, folio, gfp);
}
-
out:
*foliop = folio;
return 0;
@@ -3068,6 +3256,10 @@ static struct inode *__shmem_get_inode(s
if (info->fsflags)
shmem_set_inode_flags(inode, info->fsflags, NULL);
INIT_LIST_HEAD(&info->shrinklist);
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+ info->shrinklist_objcg = NULL;
+ info->shrinklist_nid = -1;
+#endif
INIT_LIST_HEAD(&info->swaplist);
cache_no_acl(inode);
if (sbinfo->noswap)
@@ -4943,6 +5135,9 @@ static void shmem_put_super(struct super
#endif
free_percpu(sbinfo->ino_batch);
percpu_counter_destroy(&sbinfo->used_blocks);
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+ list_lru_destroy(&sbinfo->shrinklist);
+#endif
mpol_put(sbinfo->mpol);
#ifdef CONFIG_TMPFS_XATTR
simple_xattr_cache_cleanup(&sbinfo->xa_cache);
@@ -5037,8 +5232,11 @@ static int shmem_fill_super(struct super
raw_spin_lock_init(&sbinfo->stat_lock);
if (percpu_counter_init(&sbinfo->used_blocks, 0, GFP_KERNEL))
goto failed;
- spin_lock_init(&sbinfo->shrinklist_lock);
- INIT_LIST_HEAD(&sbinfo->shrinklist);
+
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+ if (list_lru_init_memcg(&sbinfo->shrinklist, sb->s_shrink))
+ goto failed;
+#endif
sb->s_maxbytes = MAX_LFS_FILESIZE;
sb->s_blocksize = PAGE_SIZE;
_
Patches currently in -mm which might be from zhengqi.arch@bytedance.com are
fs-fix-missed-removal-of-super_fs_objects_eligible.patch
mm-memcontrol-make-obj_cgroup_memcg-handle-null-objcg.patch
mm-shmem-move-unused-huge-shrinklist-queuing-past-the-truncation-check.patch
mm-shmem-make-unused-huge-shrinker-memcg-aware.patch
reply other threads:[~2026-08-28 18:46 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260828184618.C5AAD1F000E9@smtp.kernel.org \
--to=akpm@linux-foundation.org \
--cc=baolin.wang@linux.alibaba.com \
--cc=brauner@kernel.org \
--cc=david@kernel.org \
--cc=hannes@cmpxchg.org \
--cc=hughd@google.com \
--cc=mhocko@kernel.org \
--cc=mm-commits@vger.kernel.org \
--cc=muchun.song@linux.dev \
--cc=roman.gushchin@linux.dev \
--cc=shakeel.butt@linux.dev \
--cc=zhengqi.arch@bytedance.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.