From e270a13cfd00103b233cea47cdbc898813ec9249 Mon Sep 17 00:00:00 2001 From: ZhangPeng Date: Tue, 13 Jun 2023 17:09:57 +0800 Subject: [PATCH 1/2] userswap: fix BUG_ON in userfaultfd_release() 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 (cherry picked from commit 9f98927f9e4b746006fd0449d36d4df73fc6f1b7) --- fs/userfaultfd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c index c8ec0227f340..216a968eb785 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; -- Gitee From 1f2b780e20b3a641116a30d064b394f6a32c1540 Mon Sep 17 00:00:00 2001 From: ZhangPeng Date: Tue, 13 Jun 2023 17:09:58 +0800 Subject: [PATCH 2/2] userswap: fix kmalloc ENOMEM failed for a large memory 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 (cherry picked from commit 6935faf1f3972e0179c4a1b020f2ad3207cef0fa) --- mm/userswap.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/mm/userswap.c b/mm/userswap.c index 2d47f6ed9f91..32cee1a21767 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; @@ -151,7 +151,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; } @@ -291,10 +291,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]; @@ -338,12 +337,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; } @@ -388,7 +387,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; } -- Gitee