Commit 0169fd51 authored by ZhangPeng's avatar ZhangPeng Committed by Andrew Morton

userfaultfd: convert mfill_atomic_hugetlb() to use a folio

Convert hugetlb_mfill_atomic_pte() to take in a folio pointer instead of
a page pointer.

Convert mfill_atomic_hugetlb() to use a folio.

Link: https://lkml.kernel.org/r/20230410133932.32288-5-zhangpeng362@huawei.comSigned-off-by: default avatarZhangPeng <zhangpeng362@huawei.com>
Reviewed-by: default avatarSidhartha Kumar <sidhartha.kumar@oracle.com>
Reviewed-by: default avatarMike Kravetz <mike.kravetz@oracle.com>
Cc: Kefeng Wang <wangkefeng.wang@huawei.com>
Cc: Matthew Wilcox <willy@infradead.org>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: Nanyong Sun <sunnanyong@huawei.com>
Cc: Vishal Moola (Oracle) <vishal.moola@gmail.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
parent e87340ca
...@@ -163,7 +163,7 @@ int hugetlb_mfill_atomic_pte(pte_t *dst_pte, ...@@ -163,7 +163,7 @@ int hugetlb_mfill_atomic_pte(pte_t *dst_pte,
unsigned long dst_addr, unsigned long dst_addr,
unsigned long src_addr, unsigned long src_addr,
uffd_flags_t flags, uffd_flags_t flags,
struct page **pagep); struct folio **foliop);
#endif /* CONFIG_USERFAULTFD */ #endif /* CONFIG_USERFAULTFD */
bool hugetlb_reserve_pages(struct inode *inode, long from, long to, bool hugetlb_reserve_pages(struct inode *inode, long from, long to,
struct vm_area_struct *vma, struct vm_area_struct *vma,
...@@ -397,7 +397,7 @@ static inline int hugetlb_mfill_atomic_pte(pte_t *dst_pte, ...@@ -397,7 +397,7 @@ static inline int hugetlb_mfill_atomic_pte(pte_t *dst_pte,
unsigned long dst_addr, unsigned long dst_addr,
unsigned long src_addr, unsigned long src_addr,
uffd_flags_t flags, uffd_flags_t flags,
struct page **pagep) struct folio **foliop)
{ {
BUG(); BUG();
return 0; return 0;
......
...@@ -6178,7 +6178,7 @@ int hugetlb_mfill_atomic_pte(pte_t *dst_pte, ...@@ -6178,7 +6178,7 @@ int hugetlb_mfill_atomic_pte(pte_t *dst_pte,
unsigned long dst_addr, unsigned long dst_addr,
unsigned long src_addr, unsigned long src_addr,
uffd_flags_t flags, uffd_flags_t flags,
struct page **pagep) struct folio **foliop)
{ {
struct mm_struct *dst_mm = dst_vma->vm_mm; struct mm_struct *dst_mm = dst_vma->vm_mm;
bool is_continue = uffd_flags_mode_is(flags, MFILL_ATOMIC_CONTINUE); bool is_continue = uffd_flags_mode_is(flags, MFILL_ATOMIC_CONTINUE);
...@@ -6201,8 +6201,8 @@ int hugetlb_mfill_atomic_pte(pte_t *dst_pte, ...@@ -6201,8 +6201,8 @@ int hugetlb_mfill_atomic_pte(pte_t *dst_pte,
if (IS_ERR(folio)) if (IS_ERR(folio))
goto out; goto out;
folio_in_pagecache = true; folio_in_pagecache = true;
} else if (!*pagep) { } else if (!*foliop) {
/* If a page already exists, then it's UFFDIO_COPY for /* If a folio already exists, then it's UFFDIO_COPY for
* a non-missing case. Return -EEXIST. * a non-missing case. Return -EEXIST.
*/ */
if (vm_shared && if (vm_shared &&
...@@ -6237,33 +6237,33 @@ int hugetlb_mfill_atomic_pte(pte_t *dst_pte, ...@@ -6237,33 +6237,33 @@ int hugetlb_mfill_atomic_pte(pte_t *dst_pte,
ret = -ENOMEM; ret = -ENOMEM;
goto out; goto out;
} }
*pagep = &folio->page; *foliop = folio;
/* Set the outparam pagep and return to the caller to /* Set the outparam foliop and return to the caller to
* copy the contents outside the lock. Don't free the * copy the contents outside the lock. Don't free the
* page. * folio.
*/ */
goto out; goto out;
} }
} else { } else {
if (vm_shared && if (vm_shared &&
hugetlbfs_pagecache_present(h, dst_vma, dst_addr)) { hugetlbfs_pagecache_present(h, dst_vma, dst_addr)) {
put_page(*pagep); folio_put(*foliop);
ret = -EEXIST; ret = -EEXIST;
*pagep = NULL; *foliop = NULL;
goto out; goto out;
} }
folio = alloc_hugetlb_folio(dst_vma, dst_addr, 0); folio = alloc_hugetlb_folio(dst_vma, dst_addr, 0);
if (IS_ERR(folio)) { if (IS_ERR(folio)) {
put_page(*pagep); folio_put(*foliop);
ret = -ENOMEM; ret = -ENOMEM;
*pagep = NULL; *foliop = NULL;
goto out; goto out;
} }
copy_user_huge_page(&folio->page, *pagep, dst_addr, dst_vma, copy_user_huge_page(&folio->page, &(*foliop)->page, dst_addr, dst_vma,
pages_per_huge_page(h)); pages_per_huge_page(h));
put_page(*pagep); folio_put(*foliop);
*pagep = NULL; *foliop = NULL;
} }
/* /*
......
...@@ -321,7 +321,7 @@ static __always_inline ssize_t mfill_atomic_hugetlb( ...@@ -321,7 +321,7 @@ static __always_inline ssize_t mfill_atomic_hugetlb(
pte_t *dst_pte; pte_t *dst_pte;
unsigned long src_addr, dst_addr; unsigned long src_addr, dst_addr;
long copied; long copied;
struct page *page; struct folio *folio;
unsigned long vma_hpagesize; unsigned long vma_hpagesize;
pgoff_t idx; pgoff_t idx;
u32 hash; u32 hash;
...@@ -341,7 +341,7 @@ static __always_inline ssize_t mfill_atomic_hugetlb( ...@@ -341,7 +341,7 @@ static __always_inline ssize_t mfill_atomic_hugetlb(
src_addr = src_start; src_addr = src_start;
dst_addr = dst_start; dst_addr = dst_start;
copied = 0; copied = 0;
page = NULL; folio = NULL;
vma_hpagesize = vma_kernel_pagesize(dst_vma); vma_hpagesize = vma_kernel_pagesize(dst_vma);
/* /*
...@@ -410,7 +410,7 @@ static __always_inline ssize_t mfill_atomic_hugetlb( ...@@ -410,7 +410,7 @@ static __always_inline ssize_t mfill_atomic_hugetlb(
} }
err = hugetlb_mfill_atomic_pte(dst_pte, dst_vma, dst_addr, err = hugetlb_mfill_atomic_pte(dst_pte, dst_vma, dst_addr,
src_addr, flags, &page); src_addr, flags, &folio);
hugetlb_vma_unlock_read(dst_vma); hugetlb_vma_unlock_read(dst_vma);
mutex_unlock(&hugetlb_fault_mutex_table[hash]); mutex_unlock(&hugetlb_fault_mutex_table[hash]);
...@@ -419,9 +419,9 @@ static __always_inline ssize_t mfill_atomic_hugetlb( ...@@ -419,9 +419,9 @@ static __always_inline ssize_t mfill_atomic_hugetlb(
if (unlikely(err == -ENOENT)) { if (unlikely(err == -ENOENT)) {
mmap_read_unlock(dst_mm); mmap_read_unlock(dst_mm);
BUG_ON(!page); BUG_ON(!folio);
err = copy_folio_from_user(page_folio(page), err = copy_folio_from_user(folio,
(const void __user *)src_addr, true); (const void __user *)src_addr, true);
if (unlikely(err)) { if (unlikely(err)) {
err = -EFAULT; err = -EFAULT;
...@@ -432,7 +432,7 @@ static __always_inline ssize_t mfill_atomic_hugetlb( ...@@ -432,7 +432,7 @@ static __always_inline ssize_t mfill_atomic_hugetlb(
dst_vma = NULL; dst_vma = NULL;
goto retry; goto retry;
} else } else
BUG_ON(page); BUG_ON(folio);
if (!err) { if (!err) {
dst_addr += vma_hpagesize; dst_addr += vma_hpagesize;
...@@ -449,8 +449,8 @@ static __always_inline ssize_t mfill_atomic_hugetlb( ...@@ -449,8 +449,8 @@ static __always_inline ssize_t mfill_atomic_hugetlb(
out_unlock: out_unlock:
mmap_read_unlock(dst_mm); mmap_read_unlock(dst_mm);
out: out:
if (page) if (folio)
put_page(page); folio_put(folio);
BUG_ON(copied < 0); BUG_ON(copied < 0);
BUG_ON(err > 0); BUG_ON(err > 0);
BUG_ON(!copied && !err); BUG_ON(!copied && !err);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment