From: ZhangPeng zhangpeng362@huawei.com
hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I6CAIM
--------------------------------
In some features of userfaultfd, vma->vm_userfaultfd_ctx.ctx may be NULL but VM_USWAP is not cleared. No longer check whether vma->vm_flags has VM_USWAP. Just remove the flag.
Signed-off-by: ZhangPeng zhangpeng362@huawei.com --- fs/userfaultfd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c index ec6e71ac66ad..dfa1a638640c 100644 --- a/fs/userfaultfd.c +++ b/fs/userfaultfd.c @@ -873,12 +873,12 @@ static int userfaultfd_release(struct inode *inode, struct file *file) prev = NULL; for (vma = mm->mmap; vma; vma = vma->vm_next) { userfault_flags = VM_UFFD_MISSING | VM_UFFD_WP; -#ifdef CONFIG_USERSWAP - uswap_release(&userfault_flags); -#endif cond_resched(); BUG_ON(!!vma->vm_userfaultfd_ctx.ctx ^ !!(vma->vm_flags & userfault_flags)); +#ifdef CONFIG_USERSWAP + uswap_release(&userfault_flags); +#endif if (vma->vm_userfaultfd_ctx.ctx != ctx) { prev = vma; continue;
From: ZhangPeng zhangpeng362@huawei.com
hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I6CAIM
--------------------------------
If the swapped-out memory is large, such as tens of gigabytes, we will allocate a large management structure, which may be tens of megabytes or hundreds of megabytes. So if we use kmalloc to allocate management structures it may fail. Fix this by changing kmalloc to kvzalloc and kfree to kvfree.
Signed-off-by: ZhangPeng zhangpeng362@huawei.com --- mm/userswap.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/mm/userswap.c b/mm/userswap.c index a8dc4695f8d0..f0ae208c3bdb 100644 --- a/mm/userswap.c +++ b/mm/userswap.c @@ -86,7 +86,7 @@ static unsigned long pages_can_be_swapped(struct mm_struct *mm, *ppages = NULL;
- pages = kmalloc(sizeof(struct page *) * (len / PAGE_SIZE), GFP_KERNEL); + pages = kvzalloc(sizeof(struct page *) * (len / PAGE_SIZE), GFP_KERNEL); if (!pages) return -ENOMEM;
@@ -153,7 +153,7 @@ static unsigned long pages_can_be_swapped(struct mm_struct *mm, out_err: for (i = 0; i < page_num; i++) put_page(pages[i]); - kfree(pages); + kvfree(pages); return ret; }
@@ -299,10 +299,9 @@ static unsigned long do_user_swap(struct mm_struct *mm, unsigned long i = 0, j; int ret;
- ptes = kmalloc(sizeof(pte_t) * (len / PAGE_SIZE), GFP_KERNEL); + ptes = kvzalloc(sizeof(pte_t) * (len / PAGE_SIZE), GFP_KERNEL); if (!ptes) return -ENOMEM; - memset(ptes, 0, sizeof(pte_t) * (len / PAGE_SIZE)); lru_add_drain(); for (j = 0; j < len; j += PAGE_SIZE) { page = pages[i]; @@ -350,12 +349,12 @@ static unsigned long do_user_swap(struct mm_struct *mm,
if (pages_dirty) new_addr_start = new_addr_start | USWAP_PAGES_DIRTY; - kfree(ptes); + kvfree(ptes); return new_addr_start;
out_recover: uswapout_recover(mm, old_addr_start, i, pages, new_addr_start, ptes); - kfree(ptes); + kvfree(ptes); return ret; }
@@ -401,7 +400,7 @@ unsigned long uswap_mremap(unsigned long old_addr, unsigned long old_len, for (i = 0; i < len / PAGE_SIZE; i++) if (pages[i]) put_page(pages[i]); - kfree(pages); + kvfree(pages); return ret; }