On Mon, 12 Apr 2021, Axel Rasmussen wrote:

> Previously, we did a dance where we had one calling path in
> userfaultfd.c (mfill_atomic_pte), but then we split it into two in
> shmem_fs.h (shmem_{mcopy_atomic,mfill_zeropage}_pte), and then rejoined
> into a single shared function in shmem.c (shmem_mfill_atomic_pte).
> 
> This is all a bit overly complex. Just call the single combined shmem
> function directly, allowing us to clean up various branches,
> boilerplate, etc.
> 
> While we're touching this function, two other small cleanup changes:
> - offset is equivalent to pgoff, so we can get rid of offset entirely.
> - Split two VM_BUG_ON cases into two statements. This means the line
>   number reported when the BUG is hit specifies exactly which condition
>   was true.
> 
> Reviewed-by: Peter Xu <pet...@redhat.com>
> Signed-off-by: Axel Rasmussen <axelrasmus...@google.com>

Acked-by: Hugh Dickins <hu...@google.com>
though you've dropped one minor fix I did like, see below...

> ---
>  include/linux/shmem_fs.h | 15 +++++-------
>  mm/shmem.c               | 52 +++++++++++++---------------------------
>  mm/userfaultfd.c         | 10 +++-----
>  3 files changed, 25 insertions(+), 52 deletions(-)
> 
> diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h
> index d82b6f396588..919e36671fe6 100644
> --- a/include/linux/shmem_fs.h
> +++ b/include/linux/shmem_fs.h
> @@ -122,21 +122,18 @@ static inline bool shmem_file(struct file *file)
>  extern bool shmem_charge(struct inode *inode, long pages);
>  extern void shmem_uncharge(struct inode *inode, long pages);
>  
> +#ifdef CONFIG_USERFAULTFD
>  #ifdef CONFIG_SHMEM
>  extern int shmem_mcopy_atomic_pte(struct mm_struct *dst_mm, pmd_t *dst_pmd,
>                                 struct vm_area_struct *dst_vma,
>                                 unsigned long dst_addr,
>                                 unsigned long src_addr,
> +                               bool zeropage,
>                                 struct page **pagep);
> -extern int shmem_mfill_zeropage_pte(struct mm_struct *dst_mm,
> -                                 pmd_t *dst_pmd,
> -                                 struct vm_area_struct *dst_vma,
> -                                 unsigned long dst_addr);
> -#else
> +#else /* !CONFIG_SHMEM */
>  #define shmem_mcopy_atomic_pte(dst_mm, dst_pte, dst_vma, dst_addr, \

In a previous version, you quietly corrected that "dst_pte" to "dst_pmd":
of course it makes no difference to the code generated, but it was a good
correction, helping to prevent confusion.

> -                            src_addr, pagep)        ({ BUG(); 0; })
> -#define shmem_mfill_zeropage_pte(dst_mm, dst_pmd, dst_vma, \
> -                              dst_addr)      ({ BUG(); 0; })
> -#endif
> +                            src_addr, zeropage, pagep)       ({ BUG(); 0; })
> +#endif /* CONFIG_SHMEM */
> +#endif /* CONFIG_USERFAULTFD */
>  
>  #endif
> diff --git a/mm/shmem.c b/mm/shmem.c
> index 26c76b13ad23..b72c55aa07fc 100644
> --- a/mm/shmem.c
> +++ b/mm/shmem.c
> @@ -2354,13 +2354,14 @@ static struct inode *shmem_get_inode(struct 
> super_block *sb, const struct inode
>       return inode;
>  }
>  
> -static int shmem_mfill_atomic_pte(struct mm_struct *dst_mm,
> -                               pmd_t *dst_pmd,
> -                               struct vm_area_struct *dst_vma,
> -                               unsigned long dst_addr,
> -                               unsigned long src_addr,
> -                               bool zeropage,
> -                               struct page **pagep)
> +#ifdef CONFIG_USERFAULTFD
> +int shmem_mcopy_atomic_pte(struct mm_struct *dst_mm,
> +                        pmd_t *dst_pmd,
> +                        struct vm_area_struct *dst_vma,
> +                        unsigned long dst_addr,
> +                        unsigned long src_addr,
> +                        bool zeropage,
> +                        struct page **pagep)
>  {
>       struct inode *inode = file_inode(dst_vma->vm_file);
>       struct shmem_inode_info *info = SHMEM_I(inode);
> @@ -2372,7 +2373,7 @@ static int shmem_mfill_atomic_pte(struct mm_struct 
> *dst_mm,
>       struct page *page;
>       pte_t _dst_pte, *dst_pte;
>       int ret;
> -     pgoff_t offset, max_off;
> +     pgoff_t max_off;
>  
>       ret = -ENOMEM;
>       if (!shmem_inode_acct_block(inode, 1))
> @@ -2383,7 +2384,7 @@ static int shmem_mfill_atomic_pte(struct mm_struct 
> *dst_mm,
>               if (!page)
>                       goto out_unacct_blocks;
>  
> -             if (!zeropage) {        /* mcopy_atomic */
> +             if (!zeropage) {        /* COPY */
>                       page_kaddr = kmap_atomic(page);
>                       ret = copy_from_user(page_kaddr,
>                                            (const void __user *)src_addr,
> @@ -2397,7 +2398,7 @@ static int shmem_mfill_atomic_pte(struct mm_struct 
> *dst_mm,
>                               /* don't free the page */
>                               return -ENOENT;
>                       }
> -             } else {                /* mfill_zeropage_atomic */
> +             } else {                /* ZEROPAGE */
>                       clear_highpage(page);
>               }
>       } else {
> @@ -2405,15 +2406,15 @@ static int shmem_mfill_atomic_pte(struct mm_struct 
> *dst_mm,
>               *pagep = NULL;
>       }
>  
> -     VM_BUG_ON(PageLocked(page) || PageSwapBacked(page));
> +     VM_BUG_ON(PageLocked(page));
> +     VM_BUG_ON(PageSwapBacked(page));
>       __SetPageLocked(page);
>       __SetPageSwapBacked(page);
>       __SetPageUptodate(page);
>  
>       ret = -EFAULT;
> -     offset = linear_page_index(dst_vma, dst_addr);
>       max_off = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE);
> -     if (unlikely(offset >= max_off))
> +     if (unlikely(pgoff >= max_off))
>               goto out_release;
>  
>       ret = shmem_add_to_page_cache(page, mapping, pgoff, NULL,
> @@ -2439,7 +2440,7 @@ static int shmem_mfill_atomic_pte(struct mm_struct 
> *dst_mm,
>  
>       ret = -EFAULT;
>       max_off = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE);
> -     if (unlikely(offset >= max_off))
> +     if (unlikely(pgoff >= max_off))
>               goto out_release_unlock;
>  
>       ret = -EEXIST;
> @@ -2476,28 +2477,7 @@ static int shmem_mfill_atomic_pte(struct mm_struct 
> *dst_mm,
>       shmem_inode_unacct_blocks(inode, 1);
>       goto out;
>  }
> -
> -int shmem_mcopy_atomic_pte(struct mm_struct *dst_mm,
> -                        pmd_t *dst_pmd,
> -                        struct vm_area_struct *dst_vma,
> -                        unsigned long dst_addr,
> -                        unsigned long src_addr,
> -                        struct page **pagep)
> -{
> -     return shmem_mfill_atomic_pte(dst_mm, dst_pmd, dst_vma,
> -                                   dst_addr, src_addr, false, pagep);
> -}
> -
> -int shmem_mfill_zeropage_pte(struct mm_struct *dst_mm,
> -                          pmd_t *dst_pmd,
> -                          struct vm_area_struct *dst_vma,
> -                          unsigned long dst_addr)
> -{
> -     struct page *page = NULL;
> -
> -     return shmem_mfill_atomic_pte(dst_mm, dst_pmd, dst_vma,
> -                                   dst_addr, 0, true, &page);
> -}
> +#endif /* CONFIG_USERFAULTFD */
>  
>  #ifdef CONFIG_TMPFS
>  static const struct inode_operations shmem_symlink_inode_operations;
> diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c
> index e14b3820c6a8..23fa2583bbd1 100644
> --- a/mm/userfaultfd.c
> +++ b/mm/userfaultfd.c
> @@ -440,13 +440,9 @@ static __always_inline ssize_t mfill_atomic_pte(struct 
> mm_struct *dst_mm,
>                                                dst_vma, dst_addr);
>       } else {
>               VM_WARN_ON_ONCE(wp_copy);
> -             if (!zeropage)
> -                     err = shmem_mcopy_atomic_pte(dst_mm, dst_pmd,
> -                                                  dst_vma, dst_addr,
> -                                                  src_addr, page);
> -             else
> -                     err = shmem_mfill_zeropage_pte(dst_mm, dst_pmd,
> -                                                    dst_vma, dst_addr);
> +             err = shmem_mcopy_atomic_pte(dst_mm, dst_pmd, dst_vma,
> +                                          dst_addr, src_addr, zeropage,
> +                                          page);
>       }
>  
>       return err;
> -- 
> 2.31.1.295.g9ea45b61b8-goog
> 
> 

Reply via email to