euleros inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I8NXQM
------------------------------
We record the pid of dump tasks in the reserved memory, and reserve the pids before init task start. In the recover process, free the reserved pids and realloc them for use.
Signed-off-by: Jingxian He hejingxian@huawei.com Signed-off-by: Liu Chao liuchao173@huawei.com --- arch/arm64/configs/openeuler_defconfig | 1 + include/linux/pin_mem.h | 15 ++++++++ kernel/pid.c | 4 +++ mm/Kconfig | 10 ++++++ mm/pin_mem.c | 48 ++++++++++++++++++++++++++ 5 files changed, 78 insertions(+)
diff --git a/arch/arm64/configs/openeuler_defconfig b/arch/arm64/configs/openeuler_defconfig index 63b04ad521ca..c250f606d496 100644 --- a/arch/arm64/configs/openeuler_defconfig +++ b/arch/arm64/configs/openeuler_defconfig @@ -1099,6 +1099,7 @@ CONFIG_VM_EVENT_COUNTERS=y # CONFIG_DMAPOOL_TEST is not set CONFIG_ARCH_HAS_PTE_SPECIAL=y CONFIG_PIN_MEMORY=y +CONFIG_PID_RESERVE=y CONFIG_MEMFD_CREATE=y CONFIG_SECRETMEM=y # CONFIG_ANON_VMA_NAME is not set diff --git a/include/linux/pin_mem.h b/include/linux/pin_mem.h index 614e1122d7de..c4b0c55a36ef 100644 --- a/include/linux/pin_mem.h +++ b/include/linux/pin_mem.h @@ -99,4 +99,19 @@ static inline void request_pin_mem_res(struct resource *res) {} static inline void init_reserve_page_map(void) {}
#endif /* CONFIG_PIN_MEMORY */ + +#ifdef CONFIG_PID_RESERVE + +extern void free_reserved_pid(struct idr *idr, int pid); + +extern void reserve_pids(struct idr *idr, int pid_max); + +#else + +static inline void free_reserved_pid(struct idr *idr, int pid) {} + +static inline void reserve_pids(struct idr *idr, int pid_max) {} + +#endif /* CONFIG_PID_RESERVE */ + #endif /* _LINUX_PIN_MEMORY_H */ diff --git a/kernel/pid.c b/kernel/pid.c index 6500ef956f2f..9b229c44db1f 100644 --- a/kernel/pid.c +++ b/kernel/pid.c @@ -44,6 +44,7 @@ #include <linux/idr.h> #include <net/sock.h> #include <uapi/linux/pidfd.h> +#include <linux/pin_mem.h>
struct pid init_struct_pid = { .count = REFCOUNT_INIT(1), @@ -212,6 +213,7 @@ struct pid *alloc_pid(struct pid_namespace *ns, pid_t *set_tid, spin_lock_irq(&pidmap_lock);
if (tid) { + free_reserved_pid(&tmp->idr, tid); nr = idr_alloc(&tmp->idr, NULL, tid, tid + 1, GFP_ATOMIC); /* @@ -664,6 +666,8 @@ void __init pid_idr_init(void) __alignof__(struct pid), SLAB_HWCACHE_ALIGN | SLAB_PANIC | SLAB_ACCOUNT, NULL); + + reserve_pids(&init_pid_ns.idr, pid_max); }
static struct file *__pidfd_fget(struct task_struct *task, int fd) diff --git a/mm/Kconfig b/mm/Kconfig index a96959c8b404..2e4885d74ca4 100644 --- a/mm/Kconfig +++ b/mm/Kconfig @@ -1173,6 +1173,16 @@ config PIN_MEMORY the corresponding physical pages mapping info in checkpoint, and remap the physical pages to restore tasks in restore.
+config PID_RESERVE + bool "Support for reserve pid" + depends on PIN_MEMORY + help + Say y here to enable the pid reserved feature for checkpoint. + and restore. + We record the pid of dump task in the reserve memory, + and reserve the pids before init task start. In restore process, + free the reserved pids and realloc them for use. + config KMAP_LOCAL bool
diff --git a/mm/pin_mem.c b/mm/pin_mem.c index 88f30e8b66bf..f4b631444ad4 100644 --- a/mm/pin_mem.c +++ b/mm/pin_mem.c @@ -1144,3 +1144,51 @@ void init_reserve_page_map(void) }
#endif /* CONFIG_PIN_MEMORY */ + +#ifdef CONFIG_PID_RESERVE +struct idr *reserve_idr; + +void free_reserved_pid(struct idr *idr, int pid) +{ + unsigned int index; + struct page_map_info *pmi; + + if (!max_pin_pid_num || idr != reserve_idr) + return; + + for (index = 0; index < pin_pid_num; index++) { + pmi = &(user_space_reserve_start[index]); + if (pmi->pid == pid && pmi->pid_reserved) { + idr_remove(idr, pid); + return; + } + } +} + +/* reserve pids for check point tasks which pinned memory */ +void reserve_pids(struct idr *idr, int pid_max) +{ + int alloc_pid; + unsigned int index; + struct page_map_info *pmi; + + if (!pin_pid_num || !max_pin_pid_num) + return; + + reserve_idr = idr; + + for (index = 0; index < pin_pid_num; index++) { + pmi = &(user_space_reserve_start[index]); + pmi->pid_reserved = true; + alloc_pid = idr_alloc(idr, NULL, pmi->pid, pid_max, GFP_ATOMIC); + if (alloc_pid != pmi->pid) { + if (alloc_pid > 0) + idr_remove(idr, alloc_pid); + pr_warn("Reserve pid (%d) fail, real pid is %d.\n", alloc_pid, pmi->pid); + pmi->pid_reserved = false; + continue; + } + } +} + +#endif /* CONFIG_PID_RESERVE */