linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/7] userfaultfd: enable zeropage support for shmem
@ 2017-06-20  6:20 Mike Rapoport
  2017-06-20  6:20 ` [PATCH 1/7] shmem: shmem_charge: verify max_block is not exceeded before inode update Mike Rapoport
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: Mike Rapoport @ 2017-06-20  6:20 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Andrea Arcangeli, Hugh Dickins, Kirill A. Shutemov, Hillf Danton,
	Pavel Emelyanov, linux mm, lkml, Mike Rapoport

Hi,

These patches enable support for UFFDIO_ZEROPAGE for shared memory.

The first two patches are not strictly related to userfaultfd, they are
just minor refactoring to reduce amount of code duplication.

Mike Rapoport (7):
  shmem: shmem_charge: verify max_block is not exceeded before inode update
  shmem: introduce shmem_inode_acct_block
  userfaultfd: shmem: add shmem_mfill_zeropage_pte for userfaultfd support
  userfaultfd: mcopy_atomic: introduce mfill_atomic_pte helper
  userfaultfd: shmem: wire up shmem_mfill_zeropage_pte
  userfaultfd: report UFFDIO_ZEROPAGE as available for shmem VMAs
  userfaultfd: selftest: enable testing of UFFDIO_ZEROPAGE for shmem

 fs/userfaultfd.c                         |  10 +-
 include/linux/shmem_fs.h                 |   6 ++
 mm/shmem.c                               | 167 +++++++++++++++++--------------
 mm/userfaultfd.c                         |  48 ++++++---
 tools/testing/selftests/vm/userfaultfd.c |   2 +-
 5 files changed, 136 insertions(+), 97 deletions(-)

-- 
2.7.4

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 1/7] shmem: shmem_charge: verify max_block is not exceeded before inode update
  2017-06-20  6:20 [PATCH 0/7] userfaultfd: enable zeropage support for shmem Mike Rapoport
@ 2017-06-20  6:20 ` Mike Rapoport
  2017-06-20  6:20 ` [PATCH 2/7] shmem: introduce shmem_inode_acct_block Mike Rapoport
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Mike Rapoport @ 2017-06-20  6:20 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Andrea Arcangeli, Hugh Dickins, Kirill A. Shutemov, Hillf Danton,
	Pavel Emelyanov, linux mm, lkml, Mike Rapoport

Currently we update inode and shmem_inode_info before verifying that
used_blocks will not exceed max_blocks. In case it will, we undo the
update. Let's switch the order and move the verification of the blocks
count before the inode and shmem_inode_info update.

Signed-off-by: Mike Rapoport <rppt@linux.vnet.ibm.com>
---
 mm/shmem.c | 25 ++++++++++++-------------
 1 file changed, 12 insertions(+), 13 deletions(-)

diff --git a/mm/shmem.c b/mm/shmem.c
index e67d6ba..40a43ae 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -265,6 +265,14 @@ bool shmem_charge(struct inode *inode, long pages)
 
 	if (shmem_acct_block(info->flags, pages))
 		return false;
+
+	if (sbinfo->max_blocks) {
+		if (percpu_counter_compare(&sbinfo->used_blocks,
+					   sbinfo->max_blocks - pages) > 0)
+			goto unacct;
+		percpu_counter_add(&sbinfo->used_blocks, pages);
+	}
+
 	spin_lock_irqsave(&info->lock, flags);
 	info->alloced += pages;
 	inode->i_blocks += pages * BLOCKS_PER_PAGE;
@@ -272,20 +280,11 @@ bool shmem_charge(struct inode *inode, long pages)
 	spin_unlock_irqrestore(&info->lock, flags);
 	inode->i_mapping->nrpages += pages;
 
-	if (!sbinfo->max_blocks)
-		return true;
-	if (percpu_counter_compare(&sbinfo->used_blocks,
-				sbinfo->max_blocks - pages) > 0) {
-		inode->i_mapping->nrpages -= pages;
-		spin_lock_irqsave(&info->lock, flags);
-		info->alloced -= pages;
-		shmem_recalc_inode(inode);
-		spin_unlock_irqrestore(&info->lock, flags);
-		shmem_unacct_blocks(info->flags, pages);
-		return false;
-	}
-	percpu_counter_add(&sbinfo->used_blocks, pages);
 	return true;
+
+unacct:
+	shmem_unacct_blocks(info->flags, pages);
+	return false;
 }
 
 void shmem_uncharge(struct inode *inode, long pages)
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 2/7] shmem: introduce shmem_inode_acct_block
  2017-06-20  6:20 [PATCH 0/7] userfaultfd: enable zeropage support for shmem Mike Rapoport
  2017-06-20  6:20 ` [PATCH 1/7] shmem: shmem_charge: verify max_block is not exceeded before inode update Mike Rapoport
@ 2017-06-20  6:20 ` Mike Rapoport
  2017-06-20  6:20 ` [PATCH 3/7] userfaultfd: shmem: add shmem_mfill_zeropage_pte for userfaultfd support Mike Rapoport
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Mike Rapoport @ 2017-06-20  6:20 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Andrea Arcangeli, Hugh Dickins, Kirill A. Shutemov, Hillf Danton,
	Pavel Emelyanov, linux mm, lkml, Mike Rapoport

The shmem_acct_block and the update of used_blocks are following one
another in all the places they are used. Combine these two into a helper
function.

Signed-off-by: Mike Rapoport <rppt@linux.vnet.ibm.com>
---
 mm/shmem.c | 102 ++++++++++++++++++++++++++++---------------------------------
 1 file changed, 46 insertions(+), 56 deletions(-)

diff --git a/mm/shmem.c b/mm/shmem.c
index 40a43ae..a92e3d7 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -187,6 +187,38 @@ static inline void shmem_unacct_blocks(unsigned long flags, long pages)
 		vm_unacct_memory(pages * VM_ACCT(PAGE_SIZE));
 }
 
+static inline bool shmem_inode_acct_block(struct inode *inode, long pages)
+{
+	struct shmem_inode_info *info = SHMEM_I(inode);
+	struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb);
+
+	if (shmem_acct_block(info->flags, pages))
+		return false;
+
+	if (sbinfo->max_blocks) {
+		if (percpu_counter_compare(&sbinfo->used_blocks,
+					   sbinfo->max_blocks - pages) > 0)
+			goto unacct;
+		percpu_counter_add(&sbinfo->used_blocks, pages);
+	}
+
+	return true;
+
+unacct:
+	shmem_unacct_blocks(info->flags, pages);
+	return false;
+}
+
+static inline void shmem_inode_unacct_blocks(struct inode *inode, long pages)
+{
+	struct shmem_inode_info *info = SHMEM_I(inode);
+	struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb);
+
+	if (sbinfo->max_blocks)
+		percpu_counter_sub(&sbinfo->used_blocks, pages);
+	shmem_unacct_blocks(info->flags, pages);
+}
+
 static const struct super_operations shmem_ops;
 static const struct address_space_operations shmem_aops;
 static const struct file_operations shmem_file_operations;
@@ -248,31 +280,20 @@ static void shmem_recalc_inode(struct inode *inode)
 
 	freed = info->alloced - info->swapped - inode->i_mapping->nrpages;
 	if (freed > 0) {
-		struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb);
-		if (sbinfo->max_blocks)
-			percpu_counter_add(&sbinfo->used_blocks, -freed);
 		info->alloced -= freed;
 		inode->i_blocks -= freed * BLOCKS_PER_PAGE;
-		shmem_unacct_blocks(info->flags, freed);
+		shmem_inode_unacct_blocks(inode, freed);
 	}
 }
 
 bool shmem_charge(struct inode *inode, long pages)
 {
 	struct shmem_inode_info *info = SHMEM_I(inode);
-	struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb);
 	unsigned long flags;
 
-	if (shmem_acct_block(info->flags, pages))
+	if (!shmem_inode_acct_block(inode, pages))
 		return false;
 
-	if (sbinfo->max_blocks) {
-		if (percpu_counter_compare(&sbinfo->used_blocks,
-					   sbinfo->max_blocks - pages) > 0)
-			goto unacct;
-		percpu_counter_add(&sbinfo->used_blocks, pages);
-	}
-
 	spin_lock_irqsave(&info->lock, flags);
 	info->alloced += pages;
 	inode->i_blocks += pages * BLOCKS_PER_PAGE;
@@ -281,16 +302,11 @@ bool shmem_charge(struct inode *inode, long pages)
 	inode->i_mapping->nrpages += pages;
 
 	return true;
-
-unacct:
-	shmem_unacct_blocks(info->flags, pages);
-	return false;
 }
 
 void shmem_uncharge(struct inode *inode, long pages)
 {
 	struct shmem_inode_info *info = SHMEM_I(inode);
-	struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb);
 	unsigned long flags;
 
 	spin_lock_irqsave(&info->lock, flags);
@@ -299,9 +315,7 @@ void shmem_uncharge(struct inode *inode, long pages)
 	shmem_recalc_inode(inode);
 	spin_unlock_irqrestore(&info->lock, flags);
 
-	if (sbinfo->max_blocks)
-		percpu_counter_sub(&sbinfo->used_blocks, pages);
-	shmem_unacct_blocks(info->flags, pages);
+	shmem_inode_unacct_blocks(inode, pages);
 }
 
 /*
@@ -1446,9 +1460,10 @@ static struct page *shmem_alloc_page(gfp_t gfp,
 }
 
 static struct page *shmem_alloc_and_acct_page(gfp_t gfp,
-		struct shmem_inode_info *info, struct shmem_sb_info *sbinfo,
+		struct inode *inode,
 		pgoff_t index, bool huge)
 {
+	struct shmem_inode_info *info = SHMEM_I(inode);
 	struct page *page;
 	int nr;
 	int err = -ENOSPC;
@@ -1457,14 +1472,8 @@ static struct page *shmem_alloc_and_acct_page(gfp_t gfp,
 		huge = false;
 	nr = huge ? HPAGE_PMD_NR : 1;
 
-	if (shmem_acct_block(info->flags, nr))
+	if (!shmem_inode_acct_block(inode, nr))
 		goto failed;
-	if (sbinfo->max_blocks) {
-		if (percpu_counter_compare(&sbinfo->used_blocks,
-					sbinfo->max_blocks - nr) > 0)
-			goto unacct;
-		percpu_counter_add(&sbinfo->used_blocks, nr);
-	}
 
 	if (huge)
 		page = shmem_alloc_hugepage(gfp, info, index);
@@ -1477,10 +1486,7 @@ static struct page *shmem_alloc_and_acct_page(gfp_t gfp,
 	}
 
 	err = -ENOMEM;
-	if (sbinfo->max_blocks)
-		percpu_counter_add(&sbinfo->used_blocks, -nr);
-unacct:
-	shmem_unacct_blocks(info->flags, nr);
+	shmem_inode_unacct_blocks(inode, nr);
 failed:
 	return ERR_PTR(err);
 }
@@ -1746,10 +1752,9 @@ static int shmem_getpage_gfp(struct inode *inode, pgoff_t index,
 		}
 
 alloc_huge:
-		page = shmem_alloc_and_acct_page(gfp, info, sbinfo,
-				index, true);
+		page = shmem_alloc_and_acct_page(gfp, inode, index, true);
 		if (IS_ERR(page)) {
-alloc_nohuge:		page = shmem_alloc_and_acct_page(gfp, info, sbinfo,
+alloc_nohuge:		page = shmem_alloc_and_acct_page(gfp, inode,
 					index, false);
 		}
 		if (IS_ERR(page)) {
@@ -1867,10 +1872,7 @@ alloc_nohuge:		page = shmem_alloc_and_acct_page(gfp, info, sbinfo,
 	 * Error recovery.
 	 */
 unacct:
-	if (sbinfo->max_blocks)
-		percpu_counter_sub(&sbinfo->used_blocks,
-				1 << compound_order(page));
-	shmem_unacct_blocks(info->flags, 1 << compound_order(page));
+	shmem_inode_unacct_blocks(inode, 1 << compound_order(page));
 
 	if (PageTransHuge(page)) {
 		unlock_page(page);
@@ -2204,7 +2206,6 @@ int shmem_mcopy_atomic_pte(struct mm_struct *dst_mm,
 {
 	struct inode *inode = file_inode(dst_vma->vm_file);
 	struct shmem_inode_info *info = SHMEM_I(inode);
-	struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb);
 	struct address_space *mapping = inode->i_mapping;
 	gfp_t gfp = mapping_gfp_mask(mapping);
 	pgoff_t pgoff = linear_page_index(dst_vma, dst_addr);
@@ -2216,19 +2217,13 @@ int shmem_mcopy_atomic_pte(struct mm_struct *dst_mm,
 	int ret;
 
 	ret = -ENOMEM;
-	if (shmem_acct_block(info->flags, 1))
+	if (!shmem_inode_acct_block(inode, 1))
 		goto out;
-	if (sbinfo->max_blocks) {
-		if (percpu_counter_compare(&sbinfo->used_blocks,
-					   sbinfo->max_blocks) >= 0)
-			goto out_unacct_blocks;
-		percpu_counter_inc(&sbinfo->used_blocks);
-	}
 
 	if (!*pagep) {
 		page = shmem_alloc_page(gfp, info, pgoff);
 		if (!page)
-			goto out_dec_used_blocks;
+			goto out_unacct_blocks;
 
 		page_kaddr = kmap_atomic(page);
 		ret = copy_from_user(page_kaddr, (const void __user *)src_addr,
@@ -2238,9 +2233,7 @@ int shmem_mcopy_atomic_pte(struct mm_struct *dst_mm,
 		/* fallback to copy_from_user outside mmap_sem */
 		if (unlikely(ret)) {
 			*pagep = page;
-			if (sbinfo->max_blocks)
-				percpu_counter_add(&sbinfo->used_blocks, -1);
-			shmem_unacct_blocks(info->flags, 1);
+			shmem_inode_unacct_blocks(inode, 1);
 			/* don't free the page */
 			return -EFAULT;
 		}
@@ -2303,11 +2296,8 @@ int shmem_mcopy_atomic_pte(struct mm_struct *dst_mm,
 out_release:
 	unlock_page(page);
 	put_page(page);
-out_dec_used_blocks:
-	if (sbinfo->max_blocks)
-		percpu_counter_add(&sbinfo->used_blocks, -1);
 out_unacct_blocks:
-	shmem_unacct_blocks(info->flags, 1);
+	shmem_inode_unacct_blocks(inode, 1);
 	goto out;
 }
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 3/7] userfaultfd: shmem: add shmem_mfill_zeropage_pte for userfaultfd support
  2017-06-20  6:20 [PATCH 0/7] userfaultfd: enable zeropage support for shmem Mike Rapoport
  2017-06-20  6:20 ` [PATCH 1/7] shmem: shmem_charge: verify max_block is not exceeded before inode update Mike Rapoport
  2017-06-20  6:20 ` [PATCH 2/7] shmem: introduce shmem_inode_acct_block Mike Rapoport
@ 2017-06-20  6:20 ` Mike Rapoport
  2017-06-20  6:20 ` [PATCH 4/7] userfaultfd: mcopy_atomic: introduce mfill_atomic_pte helper Mike Rapoport
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Mike Rapoport @ 2017-06-20  6:20 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Andrea Arcangeli, Hugh Dickins, Kirill A. Shutemov, Hillf Danton,
	Pavel Emelyanov, linux mm, lkml, Mike Rapoport

shmem_mfill_zeropage_pte is the low level routine that implements the
userfaultfd UFFDIO_ZEROPAGE command. Since for shmem mappings zero pages are
always allocated and accounted, the new method is a slight extension of the
existing shmem_mcopy_atomic_pte.

Signed-off-by: Mike Rapoport <rppt@linux.vnet.ibm.com>
---
 include/linux/shmem_fs.h |  6 +++++
 mm/shmem.c               | 62 +++++++++++++++++++++++++++++++++++-------------
 2 files changed, 51 insertions(+), 17 deletions(-)

diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h
index a7d6bd2..b6c3540 100644
--- a/include/linux/shmem_fs.h
+++ b/include/linux/shmem_fs.h
@@ -137,9 +137,15 @@ extern int shmem_mcopy_atomic_pte(struct mm_struct *dst_mm, pmd_t *dst_pmd,
 				  unsigned long dst_addr,
 				  unsigned long src_addr,
 				  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
 #define shmem_mcopy_atomic_pte(dst_mm, dst_pte, dst_vma, dst_addr, \
 			       src_addr, pagep)        ({ BUG(); 0; })
+#define shmem_mfill_zeropage_pte(dst_mm, dst_pmd, dst_vma, \
+				 dst_addr)      ({ BUG(); 0; })
 #endif
 
 #endif
diff --git a/mm/shmem.c b/mm/shmem.c
index a92e3d7..e775a49 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -2197,12 +2197,13 @@ bool shmem_mapping(struct address_space *mapping)
 	return mapping->a_ops == &shmem_aops;
 }
 
-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)
+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)
 {
 	struct inode *inode = file_inode(dst_vma->vm_file);
 	struct shmem_inode_info *info = SHMEM_I(inode);
@@ -2225,17 +2226,22 @@ int shmem_mcopy_atomic_pte(struct mm_struct *dst_mm,
 		if (!page)
 			goto out_unacct_blocks;
 
-		page_kaddr = kmap_atomic(page);
-		ret = copy_from_user(page_kaddr, (const void __user *)src_addr,
-				     PAGE_SIZE);
-		kunmap_atomic(page_kaddr);
-
-		/* fallback to copy_from_user outside mmap_sem */
-		if (unlikely(ret)) {
-			*pagep = page;
-			shmem_inode_unacct_blocks(inode, 1);
-			/* don't free the page */
-			return -EFAULT;
+		if (!zeropage) {	/* mcopy_atomic */
+			page_kaddr = kmap_atomic(page);
+			ret = copy_from_user(page_kaddr,
+					     (const void __user *)src_addr,
+					     PAGE_SIZE);
+			kunmap_atomic(page_kaddr);
+
+			/* fallback to copy_from_user outside mmap_sem */
+			if (unlikely(ret)) {
+				*pagep = page;
+				shmem_inode_unacct_blocks(inode, 1);
+				/* don't free the page */
+				return -EFAULT;
+			}
+		} else {		/* mfill_zeropage_atomic */
+			clear_highpage(page);
 		}
 	} else {
 		page = *pagep;
@@ -2301,6 +2307,28 @@ int shmem_mcopy_atomic_pte(struct mm_struct *dst_mm,
 	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);
+}
+
 #ifdef CONFIG_TMPFS
 static const struct inode_operations shmem_symlink_inode_operations;
 static const struct inode_operations shmem_short_symlink_operations;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 4/7] userfaultfd: mcopy_atomic: introduce mfill_atomic_pte helper
  2017-06-20  6:20 [PATCH 0/7] userfaultfd: enable zeropage support for shmem Mike Rapoport
                   ` (2 preceding siblings ...)
  2017-06-20  6:20 ` [PATCH 3/7] userfaultfd: shmem: add shmem_mfill_zeropage_pte for userfaultfd support Mike Rapoport
@ 2017-06-20  6:20 ` Mike Rapoport
  2017-06-20  6:20 ` [PATCH 5/7] userfaultfd: shmem: wire up shmem_mfill_zeropage_pte Mike Rapoport
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Mike Rapoport @ 2017-06-20  6:20 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Andrea Arcangeli, Hugh Dickins, Kirill A. Shutemov, Hillf Danton,
	Pavel Emelyanov, linux mm, lkml, Mike Rapoport

Shuffle the code a bit to improve readability.

Signed-off-by: Mike Rapoport <rppt@linux.vnet.ibm.com>
---
 mm/userfaultfd.c | 46 ++++++++++++++++++++++++++++++----------------
 1 file changed, 30 insertions(+), 16 deletions(-)

diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c
index 8bcb501..48c015c 100644
--- a/mm/userfaultfd.c
+++ b/mm/userfaultfd.c
@@ -371,6 +371,34 @@ extern ssize_t __mcopy_atomic_hugetlb(struct mm_struct *dst_mm,
 				      bool zeropage);
 #endif /* CONFIG_HUGETLB_PAGE */
 
+static __always_inline ssize_t 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,
+						struct page **page,
+						bool zeropage)
+{
+	ssize_t err;
+
+	if (vma_is_anonymous(dst_vma)) {
+		if (!zeropage)
+			err = mcopy_atomic_pte(dst_mm, dst_pmd, dst_vma,
+					       dst_addr, src_addr, page);
+		else
+			err = mfill_zeropage_pte(dst_mm, dst_pmd,
+						 dst_vma, dst_addr);
+	} else {
+		err = -EINVAL; /* if zeropage is true return -EINVAL */
+		if (likely(!zeropage))
+			err = shmem_mcopy_atomic_pte(dst_mm, dst_pmd,
+						     dst_vma, dst_addr,
+						     src_addr, page);
+	}
+
+	return err;
+}
+
 static __always_inline ssize_t __mcopy_atomic(struct mm_struct *dst_mm,
 					      unsigned long dst_start,
 					      unsigned long src_start,
@@ -487,22 +515,8 @@ static __always_inline ssize_t __mcopy_atomic(struct mm_struct *dst_mm,
 		BUG_ON(pmd_none(*dst_pmd));
 		BUG_ON(pmd_trans_huge(*dst_pmd));
 
-		if (vma_is_anonymous(dst_vma)) {
-			if (!zeropage)
-				err = mcopy_atomic_pte(dst_mm, dst_pmd, dst_vma,
-						       dst_addr, src_addr,
-						       &page);
-			else
-				err = mfill_zeropage_pte(dst_mm, dst_pmd,
-							 dst_vma, dst_addr);
-		} else {
-			err = -EINVAL; /* if zeropage is true return -EINVAL */
-			if (likely(!zeropage))
-				err = shmem_mcopy_atomic_pte(dst_mm, dst_pmd,
-							     dst_vma, dst_addr,
-							     src_addr, &page);
-		}
-
+		err = mfill_atomic_pte(dst_mm, dst_pmd, dst_vma, dst_addr,
+				       src_addr, &page, zeropage);
 		cond_resched();
 
 		if (unlikely(err == -EFAULT)) {
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 5/7] userfaultfd: shmem: wire up shmem_mfill_zeropage_pte
  2017-06-20  6:20 [PATCH 0/7] userfaultfd: enable zeropage support for shmem Mike Rapoport
                   ` (3 preceding siblings ...)
  2017-06-20  6:20 ` [PATCH 4/7] userfaultfd: mcopy_atomic: introduce mfill_atomic_pte helper Mike Rapoport
@ 2017-06-20  6:20 ` Mike Rapoport
  2017-06-20  6:20 ` [PATCH 6/7] userfaultfd: report UFFDIO_ZEROPAGE as available for shmem VMAs Mike Rapoport
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Mike Rapoport @ 2017-06-20  6:20 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Andrea Arcangeli, Hugh Dickins, Kirill A. Shutemov, Hillf Danton,
	Pavel Emelyanov, linux mm, lkml, Mike Rapoport

For shmem VMAs we can use shmem_mfill_zeropage_pte for UFFDIO_ZEROPAGE

Signed-off-by: Mike Rapoport <rppt@linux.vnet.ibm.com>
---
 mm/userfaultfd.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c
index 48c015c..8119270 100644
--- a/mm/userfaultfd.c
+++ b/mm/userfaultfd.c
@@ -389,11 +389,13 @@ static __always_inline ssize_t mfill_atomic_pte(struct mm_struct *dst_mm,
 			err = mfill_zeropage_pte(dst_mm, dst_pmd,
 						 dst_vma, dst_addr);
 	} else {
-		err = -EINVAL; /* if zeropage is true return -EINVAL */
-		if (likely(!zeropage))
+		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);
 	}
 
 	return err;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 6/7] userfaultfd: report UFFDIO_ZEROPAGE as available for shmem VMAs
  2017-06-20  6:20 [PATCH 0/7] userfaultfd: enable zeropage support for shmem Mike Rapoport
                   ` (4 preceding siblings ...)
  2017-06-20  6:20 ` [PATCH 5/7] userfaultfd: shmem: wire up shmem_mfill_zeropage_pte Mike Rapoport
@ 2017-06-20  6:20 ` Mike Rapoport
  2017-06-20  6:20 ` [PATCH 7/7] userfaultfd: selftest: enable testing of UFFDIO_ZEROPAGE for shmem Mike Rapoport
  2017-06-30  9:20 ` [PATCH 0/7] userfaultfd: enable zeropage support " Mike Rapoprt
  7 siblings, 0 replies; 9+ messages in thread
From: Mike Rapoport @ 2017-06-20  6:20 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Andrea Arcangeli, Hugh Dickins, Kirill A. Shutemov, Hillf Danton,
	Pavel Emelyanov, linux mm, lkml, Mike Rapoport

Now when shmem VMAs can be filled with zero page via userfaultfd we can
report that UFFDIO_ZEROPAGE is available for those VMAs

Signed-off-by: Mike Rapoport <rppt@linux.vnet.ibm.com>
---
 fs/userfaultfd.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c
index f7555fc..57794c2 100644
--- a/fs/userfaultfd.c
+++ b/fs/userfaultfd.c
@@ -1183,7 +1183,7 @@ static int userfaultfd_register(struct userfaultfd_ctx *ctx,
 	struct uffdio_register __user *user_uffdio_register;
 	unsigned long vm_flags, new_flags;
 	bool found;
-	bool non_anon_pages;
+	bool basic_ioctls;
 	unsigned long start, end, vma_end;
 
 	user_uffdio_register = (struct uffdio_register __user *) arg;
@@ -1249,7 +1249,7 @@ static int userfaultfd_register(struct userfaultfd_ctx *ctx,
 	 * Search for not compatible vmas.
 	 */
 	found = false;
-	non_anon_pages = false;
+	basic_ioctls = false;
 	for (cur = vma; cur && cur->vm_start < end; cur = cur->vm_next) {
 		cond_resched();
 
@@ -1288,8 +1288,8 @@ static int userfaultfd_register(struct userfaultfd_ctx *ctx,
 		/*
 		 * Note vmas containing huge pages
 		 */
-		if (is_vm_hugetlb_page(cur) || vma_is_shmem(cur))
-			non_anon_pages = true;
+		if (is_vm_hugetlb_page(cur))
+			basic_ioctls = true;
 
 		found = true;
 	}
@@ -1360,7 +1360,7 @@ static int userfaultfd_register(struct userfaultfd_ctx *ctx,
 		 * userland which ioctls methods are guaranteed to
 		 * succeed on this range.
 		 */
-		if (put_user(non_anon_pages ? UFFD_API_RANGE_IOCTLS_BASIC :
+		if (put_user(basic_ioctls ? UFFD_API_RANGE_IOCTLS_BASIC :
 			     UFFD_API_RANGE_IOCTLS,
 			     &user_uffdio_register->ioctls))
 			ret = -EFAULT;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 7/7] userfaultfd: selftest: enable testing of UFFDIO_ZEROPAGE for shmem
  2017-06-20  6:20 [PATCH 0/7] userfaultfd: enable zeropage support for shmem Mike Rapoport
                   ` (5 preceding siblings ...)
  2017-06-20  6:20 ` [PATCH 6/7] userfaultfd: report UFFDIO_ZEROPAGE as available for shmem VMAs Mike Rapoport
@ 2017-06-20  6:20 ` Mike Rapoport
  2017-06-30  9:20 ` [PATCH 0/7] userfaultfd: enable zeropage support " Mike Rapoprt
  7 siblings, 0 replies; 9+ messages in thread
From: Mike Rapoport @ 2017-06-20  6:20 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Andrea Arcangeli, Hugh Dickins, Kirill A. Shutemov, Hillf Danton,
	Pavel Emelyanov, linux mm, lkml, Mike Rapoport

Signed-off-by: Mike Rapoport <rppt@linux.vnet.ibm.com>
---
 tools/testing/selftests/vm/userfaultfd.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/testing/selftests/vm/userfaultfd.c b/tools/testing/selftests/vm/userfaultfd.c
index 1eae79a..b0c9263 100644
--- a/tools/testing/selftests/vm/userfaultfd.c
+++ b/tools/testing/selftests/vm/userfaultfd.c
@@ -198,7 +198,7 @@ static struct uffd_test_ops anon_uffd_test_ops = {
 };
 
 static struct uffd_test_ops shmem_uffd_test_ops = {
-	.expected_ioctls = UFFD_API_RANGE_IOCTLS_BASIC,
+	.expected_ioctls = ANON_EXPECTED_IOCTLS,
 	.allocate_area	= shmem_allocate_area,
 	.release_pages	= shmem_release_pages,
 };
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH 0/7] userfaultfd: enable zeropage support for shmem
  2017-06-20  6:20 [PATCH 0/7] userfaultfd: enable zeropage support for shmem Mike Rapoport
                   ` (6 preceding siblings ...)
  2017-06-20  6:20 ` [PATCH 7/7] userfaultfd: selftest: enable testing of UFFDIO_ZEROPAGE for shmem Mike Rapoport
@ 2017-06-30  9:20 ` Mike Rapoprt
  7 siblings, 0 replies; 9+ messages in thread
From: Mike Rapoprt @ 2017-06-30  9:20 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Andrea Arcangeli, Hugh Dickins, Kirill A. Shutemov, Hillf Danton,
	Pavel Emelyanov, linux mm, lkml

Hi,

Any updates/comments?


On June 20, 2017 9:20:45 AM GMT+03:00, Mike Rapoport <rppt@linux.vnet.ibm.com> wrote:
>Hi,
>
>These patches enable support for UFFDIO_ZEROPAGE for shared memory.
>
>The first two patches are not strictly related to userfaultfd, they are
>just minor refactoring to reduce amount of code duplication.
>
>Mike Rapoport (7):
>shmem: shmem_charge: verify max_block is not exceeded before inode
>update
>  shmem: introduce shmem_inode_acct_block
>userfaultfd: shmem: add shmem_mfill_zeropage_pte for userfaultfd
>support
>  userfaultfd: mcopy_atomic: introduce mfill_atomic_pte helper
>  userfaultfd: shmem: wire up shmem_mfill_zeropage_pte
>  userfaultfd: report UFFDIO_ZEROPAGE as available for shmem VMAs
>  userfaultfd: selftest: enable testing of UFFDIO_ZEROPAGE for shmem
>
> fs/userfaultfd.c                         |  10 +-
> include/linux/shmem_fs.h                 |   6 ++
>mm/shmem.c                               | 167
>+++++++++++++++++--------------
> mm/userfaultfd.c                         |  48 ++++++---
> tools/testing/selftests/vm/userfaultfd.c |   2 +-
> 5 files changed, 136 insertions(+), 97 deletions(-)

-- 
Sent from my Android device with K-9 Mail. Please excuse my brevity.

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2017-06-30  9:20 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-06-20  6:20 [PATCH 0/7] userfaultfd: enable zeropage support for shmem Mike Rapoport
2017-06-20  6:20 ` [PATCH 1/7] shmem: shmem_charge: verify max_block is not exceeded before inode update Mike Rapoport
2017-06-20  6:20 ` [PATCH 2/7] shmem: introduce shmem_inode_acct_block Mike Rapoport
2017-06-20  6:20 ` [PATCH 3/7] userfaultfd: shmem: add shmem_mfill_zeropage_pte for userfaultfd support Mike Rapoport
2017-06-20  6:20 ` [PATCH 4/7] userfaultfd: mcopy_atomic: introduce mfill_atomic_pte helper Mike Rapoport
2017-06-20  6:20 ` [PATCH 5/7] userfaultfd: shmem: wire up shmem_mfill_zeropage_pte Mike Rapoport
2017-06-20  6:20 ` [PATCH 6/7] userfaultfd: report UFFDIO_ZEROPAGE as available for shmem VMAs Mike Rapoport
2017-06-20  6:20 ` [PATCH 7/7] userfaultfd: selftest: enable testing of UFFDIO_ZEROPAGE for shmem Mike Rapoport
2017-06-30  9:20 ` [PATCH 0/7] userfaultfd: enable zeropage support " Mike Rapoprt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).