Address-space teardown on process exit runs synchronously in the dying
task's context: exit_mm() -> mmput() -> __mmput() -> exit_mmap() walks
page tables, updates rmap, frees the RSS and drops file refs, all on the
exiting CPU.
Add the scaffolding to later move __mmput() off-CPU for large exiting
address spaces, with no functional change in this patch:
- new config ASYNC_MM_TEARDOWN (bool, depends on MMU, default n)
- struct mm_struct::async_reap_node (llist_node), CONFIG-gated, with
an explicit <linux/llist.h> include (it was only ever available
transitively via spinlock.h)
- mmput_exit() declaration, with a static inline fallback that is a
plain mmput
When the config is disabled mmput_exit() compiles to mmput() with zero
delta, so nothing changes until the kthread and dispatch land.
Signed-off-by: Aditya Sharma <[email protected]>
---
include/linux/mm_types.h | 4 ++++
include/linux/sched/mm.h | 6 ++++++
mm/Kconfig | 11 +++++++++++
3 files changed, 21 insertions(+)
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index 939b5ea8c..fffa285ef 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -7,6 +7,7 @@
#include <linux/auxvec.h>
#include <linux/kref.h>
#include <linux/list.h>
+#include <linux/llist.h>
#include <linux/spinlock.h>
#include <linux/rbtree.h>
#include <linux/maple_tree.h>
@@ -1367,6 +1368,9 @@ struct mm_struct {
atomic_long_t hugetlb_usage;
#endif
struct work_struct async_put_work;
+#ifdef CONFIG_ASYNC_MM_TEARDOWN
+ struct llist_node async_reap_node;
+#endif /* CONFIG_ASYNC_MM_TEARDOWN */
#ifdef CONFIG_IOMMU_MM_DATA
struct iommu_mm_data *iommu_mm;
diff --git a/include/linux/sched/mm.h b/include/linux/sched/mm.h
index 10be8a54b..20aeb1d7e 100644
--- a/include/linux/sched/mm.h
+++ b/include/linux/sched/mm.h
@@ -147,6 +147,12 @@ extern void mmput(struct mm_struct *);
void mmput_async(struct mm_struct *);
#endif
+#ifdef CONFIG_ASYNC_MM_TEARDOWN
+void mmput_exit(struct mm_struct *);
+#else
+static inline void mmput_exit(struct mm_struct *mm) { mmput(mm); }
+#endif
+
/* Grab a reference to a task's mm, if it is not already going away */
extern struct mm_struct *get_task_mm(struct task_struct *task);
/*
diff --git a/mm/Kconfig b/mm/Kconfig
index c52ab6afc..296b16ad4 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -1500,6 +1500,17 @@ config LAZY_MMU_MODE_KUNIT_TEST
If unsure, say N.
+config ASYNC_MM_TEARDOWN
+ bool "Async off-CPU address space teardown on exit"
+ depends on MMU
+ default n
+ help
+ Defer the address space teardown (exit_mmap()) of large exiting
processes
+ to a kernel thread instead of running it on the exiting CPU. The
feature
+ is off by default.
+
+ If unsure, say N.
+
source "mm/damon/Kconfig"
endmenu
--
2.34.1