ascend inclusion category: Feature bugzilla: https://gitee.com/openeuler/kernel/issues/I8LNGH
---------------------------------------------
Change the mmap_base in mm_struct and check the limit in get_unmapped_area.
The vma mapped from sharepool cannot merge because the sp_area cannot merge. Check this in is_mergeable_vma() instead of vma_merge().
Signed-off-by: Wang Wensheng wangwensheng4@huawei.com --- include/linux/share_pool.h | 11 +++++++++++ mm/mmap.c | 7 +++++++ mm/util.c | 4 ++++ 3 files changed, 22 insertions(+)
diff --git a/include/linux/share_pool.h b/include/linux/share_pool.h index 1333b9994242..6da32aef6886 100644 --- a/include/linux/share_pool.h +++ b/include/linux/share_pool.h @@ -130,6 +130,13 @@ static inline void sp_area_work_around(struct vm_unmapped_area_info *info) info->high_limit = min(info->high_limit, MMAP_SHARE_POOL_START); }
+extern void __sp_area_drop(struct vm_area_struct *vma); +static inline void sp_area_drop(struct vm_area_struct *vma) +{ + if (sp_is_enabled()) + __sp_area_drop(vma); +} + static inline bool sp_check_vm_share_pool(unsigned long vm_flags) { if (sp_is_enabled() && (vm_flags & VM_SHARE_POOL)) @@ -181,6 +188,10 @@ static inline int mg_sp_id_of_current(void) return -EPERM; }
+static inline void sp_area_drop(struct vm_area_struct *vma) +{ +} + static inline int mg_sp_walk_page_range(unsigned long uva, unsigned long size, struct task_struct *tsk, struct sp_walk_data *sp_walk_data) { diff --git a/mm/mmap.c b/mm/mmap.c index df2624e48119..ff9d9a8d25ce 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -47,6 +47,7 @@ #include <linux/oom.h> #include <linux/sched/mm.h> #include <linux/ksm.h> +#include <linux/share_pool.h>
#include <linux/uaccess.h> #include <asm/cacheflush.h> @@ -142,6 +143,7 @@ static void remove_vma(struct vm_area_struct *vma, bool unreachable) if (vma->vm_file) fput(vma->vm_file); mpol_put(vma_policy(vma)); + sp_area_drop(vma); if (unreachable) __vm_area_free(vma); else @@ -740,6 +742,10 @@ static inline bool is_mergeable_vma(struct vm_area_struct *vma, return false; if (!anon_vma_name_eq(anon_vma_name(vma), anon_name)) return false; + /* don't merge this kind of vma as sp_area couldn't be merged */ + if (sp_check_vm_share_pool(vm_flags)) + return false; + return true; }
@@ -1680,6 +1686,7 @@ unsigned long vm_unmapped_area(struct vm_unmapped_area_info *info) { unsigned long addr;
+ sp_area_work_around(info); if (info->flags & VM_UNMAPPED_AREA_TOPDOWN) addr = unmapped_area_topdown(info); else diff --git a/mm/util.c b/mm/util.c index be798981acc7..90250cbc82fe 100644 --- a/mm/util.c +++ b/mm/util.c @@ -23,6 +23,7 @@ #include <linux/processor.h> #include <linux/sizes.h> #include <linux/compat.h> +#include <linux/share_pool.h>
#include <linux/uaccess.h>
@@ -439,6 +440,9 @@ static unsigned long mmap_base(unsigned long rnd, struct rlimit *rlim_stack) else if (gap > MAX_GAP) gap = MAX_GAP;
+ if (sp_is_enabled()) + return ALIGN_DOWN(MMAP_SHARE_POOL_START - rnd, PAGE_SIZE); + return PAGE_ALIGN(STACK_TOP - gap - rnd); #endif }