linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/3] mm/hugetlb: replace parameters of follow_huge_pmd/pud()
@ 2014-07-28 18:08 Naoya Horiguchi
  2014-07-28 18:08 ` [PATCH 2/3] mm/hugetlb: take refcount under page table lock in follow_huge_pmd() Naoya Horiguchi
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Naoya Horiguchi @ 2014-07-28 18:08 UTC (permalink / raw)
  To: Andrew Morton, Hugh Dickins; +Cc: linux-mm, linux-kernel, Naoya Horiguchi

Currently follow_huge_pmd() and follow_huge_pud() don't use the parameter
mm or write. So let's change these to vma and flags as a preparation for
the next patch. No behavioral change.

Signed-off-by: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
---
 arch/ia64/mm/hugetlbpage.c    |  3 ++-
 arch/metag/mm/hugetlbpage.c   |  4 ++--
 arch/mips/mm/hugetlbpage.c    |  4 ++--
 arch/powerpc/mm/hugetlbpage.c |  4 ++--
 arch/s390/mm/hugetlbpage.c    |  4 ++--
 arch/sh/mm/hugetlbpage.c      |  4 ++--
 arch/sparc/mm/hugetlbpage.c   |  4 ++--
 arch/tile/mm/hugetlbpage.c    |  8 ++++----
 arch/x86/mm/hugetlbpage.c     |  4 ++--
 include/linux/hugetlb.h       | 12 ++++++------
 mm/gup.c                      |  4 ++--
 mm/hugetlb.c                  | 12 ++++++------
 12 files changed, 34 insertions(+), 33 deletions(-)

diff --git mmotm-2014-07-22-15-58.orig/arch/ia64/mm/hugetlbpage.c mmotm-2014-07-22-15-58/arch/ia64/mm/hugetlbpage.c
index 76069c18ee42..ce67cf227c37 100644
--- mmotm-2014-07-22-15-58.orig/arch/ia64/mm/hugetlbpage.c
+++ mmotm-2014-07-22-15-58/arch/ia64/mm/hugetlbpage.c
@@ -115,7 +115,8 @@ int pud_huge(pud_t pud)
 }
 
 struct page *
-follow_huge_pmd(struct mm_struct *mm, unsigned long address, pmd_t *pmd, int write)
+follow_huge_pmd(struct vm_area_struct *vma, unsigned long address,
+		pmd_t *pmd, int flags)
 {
 	return NULL;
 }
diff --git mmotm-2014-07-22-15-58.orig/arch/metag/mm/hugetlbpage.c mmotm-2014-07-22-15-58/arch/metag/mm/hugetlbpage.c
index 3c52fa6d0f8e..55d1be14cecf 100644
--- mmotm-2014-07-22-15-58.orig/arch/metag/mm/hugetlbpage.c
+++ mmotm-2014-07-22-15-58/arch/metag/mm/hugetlbpage.c
@@ -110,8 +110,8 @@ int pud_huge(pud_t pud)
 	return 0;
 }
 
-struct page *follow_huge_pmd(struct mm_struct *mm, unsigned long address,
-			     pmd_t *pmd, int write)
+struct page *follow_huge_pmd(struct vm_area_struct *vma, unsigned long address,
+			     pmd_t *pmd, int flags)
 {
 	return NULL;
 }
diff --git mmotm-2014-07-22-15-58.orig/arch/mips/mm/hugetlbpage.c mmotm-2014-07-22-15-58/arch/mips/mm/hugetlbpage.c
index 4ec8ee10d371..3b1fb97f2fa9 100644
--- mmotm-2014-07-22-15-58.orig/arch/mips/mm/hugetlbpage.c
+++ mmotm-2014-07-22-15-58/arch/mips/mm/hugetlbpage.c
@@ -85,8 +85,8 @@ int pud_huge(pud_t pud)
 }
 
 struct page *
-follow_huge_pmd(struct mm_struct *mm, unsigned long address,
-		pmd_t *pmd, int write)
+follow_huge_pmd(struct vm_area_struct *vma, unsigned long address,
+		pmd_t *pmd, int flags)
 {
 	struct page *page;
 
diff --git mmotm-2014-07-22-15-58.orig/arch/powerpc/mm/hugetlbpage.c mmotm-2014-07-22-15-58/arch/powerpc/mm/hugetlbpage.c
index 7e70ae968e5f..3d366b06e0c7 100644
--- mmotm-2014-07-22-15-58.orig/arch/powerpc/mm/hugetlbpage.c
+++ mmotm-2014-07-22-15-58/arch/powerpc/mm/hugetlbpage.c
@@ -699,8 +699,8 @@ follow_huge_addr(struct mm_struct *mm, unsigned long address, int write)
 }
 
 struct page *
-follow_huge_pmd(struct mm_struct *mm, unsigned long address,
-		pmd_t *pmd, int write)
+follow_huge_pmd(struct vm_area_struct *vma, unsigned long address,
+		pmd_t *pmd, int flags)
 {
 	BUG();
 	return NULL;
diff --git mmotm-2014-07-22-15-58.orig/arch/s390/mm/hugetlbpage.c mmotm-2014-07-22-15-58/arch/s390/mm/hugetlbpage.c
index 0ff66a7e29bb..c41f51585309 100644
--- mmotm-2014-07-22-15-58.orig/arch/s390/mm/hugetlbpage.c
+++ mmotm-2014-07-22-15-58/arch/s390/mm/hugetlbpage.c
@@ -220,8 +220,8 @@ int pud_huge(pud_t pud)
 	return 0;
 }
 
-struct page *follow_huge_pmd(struct mm_struct *mm, unsigned long address,
-			     pmd_t *pmdp, int write)
+struct page *follow_huge_pmd(struct vm_area_struct *vma, unsigned long address,
+			     pmd_t *pmdp, int flags)
 {
 	struct page *page;
 
diff --git mmotm-2014-07-22-15-58.orig/arch/sh/mm/hugetlbpage.c mmotm-2014-07-22-15-58/arch/sh/mm/hugetlbpage.c
index d7762349ea48..21e8362d535b 100644
--- mmotm-2014-07-22-15-58.orig/arch/sh/mm/hugetlbpage.c
+++ mmotm-2014-07-22-15-58/arch/sh/mm/hugetlbpage.c
@@ -83,8 +83,8 @@ int pud_huge(pud_t pud)
 	return 0;
 }
 
-struct page *follow_huge_pmd(struct mm_struct *mm, unsigned long address,
-			     pmd_t *pmd, int write)
+struct page *follow_huge_pmd(struct vm_area_struct *vma, unsigned long address,
+			     pmd_t *pmd, int flags)
 {
 	return NULL;
 }
diff --git mmotm-2014-07-22-15-58.orig/arch/sparc/mm/hugetlbpage.c mmotm-2014-07-22-15-58/arch/sparc/mm/hugetlbpage.c
index d329537739c6..f99dc9097261 100644
--- mmotm-2014-07-22-15-58.orig/arch/sparc/mm/hugetlbpage.c
+++ mmotm-2014-07-22-15-58/arch/sparc/mm/hugetlbpage.c
@@ -231,8 +231,8 @@ int pud_huge(pud_t pud)
 	return 0;
 }
 
-struct page *follow_huge_pmd(struct mm_struct *mm, unsigned long address,
-			     pmd_t *pmd, int write)
+struct page *follow_huge_pmd(struct vm_area_struct *vma, unsigned long address,
+			     pmd_t *pmd, int flags)
 {
 	return NULL;
 }
diff --git mmotm-2014-07-22-15-58.orig/arch/tile/mm/hugetlbpage.c mmotm-2014-07-22-15-58/arch/tile/mm/hugetlbpage.c
index e514899e1100..2eb1df67cb7d 100644
--- mmotm-2014-07-22-15-58.orig/arch/tile/mm/hugetlbpage.c
+++ mmotm-2014-07-22-15-58/arch/tile/mm/hugetlbpage.c
@@ -166,8 +166,8 @@ int pud_huge(pud_t pud)
 	return !!(pud_val(pud) & _PAGE_HUGE_PAGE);
 }
 
-struct page *follow_huge_pmd(struct mm_struct *mm, unsigned long address,
-			     pmd_t *pmd, int write)
+struct page *follow_huge_pmd(struct vm_area_struct *vma, unsigned long address,
+			     pmd_t *pmd, int flags)
 {
 	struct page *page;
 
@@ -177,8 +177,8 @@ struct page *follow_huge_pmd(struct mm_struct *mm, unsigned long address,
 	return page;
 }
 
-struct page *follow_huge_pud(struct mm_struct *mm, unsigned long address,
-			     pud_t *pud, int write)
+struct page *follow_huge_pud(struct vm_area_struct *vma, unsigned long address,
+			     pud_t *pud, int flags)
 {
 	struct page *page;
 
diff --git mmotm-2014-07-22-15-58.orig/arch/x86/mm/hugetlbpage.c mmotm-2014-07-22-15-58/arch/x86/mm/hugetlbpage.c
index 8b977ebf9388..416c416357df 100644
--- mmotm-2014-07-22-15-58.orig/arch/x86/mm/hugetlbpage.c
+++ mmotm-2014-07-22-15-58/arch/x86/mm/hugetlbpage.c
@@ -53,8 +53,8 @@ int pud_huge(pud_t pud)
 }
 
 struct page *
-follow_huge_pmd(struct mm_struct *mm, unsigned long address,
-		pmd_t *pmd, int write)
+follow_huge_pmd(struct vm_area_struct *vma, unsigned long address,
+		pmd_t *pmd, int flags)
 {
 	return NULL;
 }
diff --git mmotm-2014-07-22-15-58.orig/include/linux/hugetlb.h mmotm-2014-07-22-15-58/include/linux/hugetlb.h
index 41272bcf73f8..647cc4821ac2 100644
--- mmotm-2014-07-22-15-58.orig/include/linux/hugetlb.h
+++ mmotm-2014-07-22-15-58/include/linux/hugetlb.h
@@ -97,10 +97,10 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr);
 int huge_pmd_unshare(struct mm_struct *mm, unsigned long *addr, pte_t *ptep);
 struct page *follow_huge_addr(struct mm_struct *mm, unsigned long address,
 			      int write);
-struct page *follow_huge_pmd(struct mm_struct *mm, unsigned long address,
-				pmd_t *pmd, int write);
-struct page *follow_huge_pud(struct mm_struct *mm, unsigned long address,
-				pud_t *pud, int write);
+struct page *follow_huge_pmd(struct vm_area_struct *vma, unsigned long address,
+				pmd_t *pmd, int flags);
+struct page *follow_huge_pud(struct vm_area_struct *vma, unsigned long address,
+				pud_t *pud, int flags);
 int pmd_huge(pmd_t pmd);
 int pud_huge(pud_t pmd);
 unsigned long hugetlb_change_protection(struct vm_area_struct *vma,
@@ -132,8 +132,8 @@ static inline void hugetlb_report_meminfo(struct seq_file *m)
 static inline void hugetlb_show_meminfo(void)
 {
 }
-#define follow_huge_pmd(mm, addr, pmd, write)	NULL
-#define follow_huge_pud(mm, addr, pud, write)	NULL
+#define follow_huge_pmd(vma, addr, pmd, flags)	NULL
+#define follow_huge_pud(vma, addr, pud, flags)	NULL
 #define prepare_hugepage_range(file, addr, len)	(-EINVAL)
 #define pmd_huge(x)	0
 #define pud_huge(x)	0
diff --git mmotm-2014-07-22-15-58.orig/mm/gup.c mmotm-2014-07-22-15-58/mm/gup.c
index 91d044b1600d..ba2c933625b2 100644
--- mmotm-2014-07-22-15-58.orig/mm/gup.c
+++ mmotm-2014-07-22-15-58/mm/gup.c
@@ -165,7 +165,7 @@ struct page *follow_page_mask(struct vm_area_struct *vma,
 	if (pud_huge(*pud) && vma->vm_flags & VM_HUGETLB) {
 		if (flags & FOLL_GET)
 			return NULL;
-		page = follow_huge_pud(mm, address, pud, flags & FOLL_WRITE);
+		page = follow_huge_pud(vma, address, pud, flags);
 		return page;
 	}
 	if (unlikely(pud_bad(*pud)))
@@ -175,7 +175,7 @@ struct page *follow_page_mask(struct vm_area_struct *vma,
 	if (pmd_none(*pmd))
 		return no_page_table(vma, flags);
 	if (pmd_huge(*pmd) && vma->vm_flags & VM_HUGETLB) {
-		page = follow_huge_pmd(mm, address, pmd, flags & FOLL_WRITE);
+		page = follow_huge_pmd(vma, address, pmd, flags);
 		if (flags & FOLL_GET) {
 			/*
 			 * Refcount on tail pages are not well-defined and
diff --git mmotm-2014-07-22-15-58.orig/mm/hugetlb.c mmotm-2014-07-22-15-58/mm/hugetlb.c
index 7263c770e9b3..ade297a9c519 100644
--- mmotm-2014-07-22-15-58.orig/mm/hugetlb.c
+++ mmotm-2014-07-22-15-58/mm/hugetlb.c
@@ -3651,8 +3651,8 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
 }
 
 struct page *
-follow_huge_pmd(struct mm_struct *mm, unsigned long address,
-		pmd_t *pmd, int write)
+follow_huge_pmd(struct vm_area_struct *vma, unsigned long address,
+		pmd_t *pmd, int flags)
 {
 	struct page *page;
 
@@ -3663,8 +3663,8 @@ follow_huge_pmd(struct mm_struct *mm, unsigned long address,
 }
 
 struct page *
-follow_huge_pud(struct mm_struct *mm, unsigned long address,
-		pud_t *pud, int write)
+follow_huge_pud(struct vm_area_struct *vma, unsigned long address,
+		pud_t *pud, int flags)
 {
 	struct page *page;
 
@@ -3678,8 +3678,8 @@ follow_huge_pud(struct mm_struct *mm, unsigned long address,
 
 /* Can be overriden by architectures */
 struct page * __weak
-follow_huge_pud(struct mm_struct *mm, unsigned long address,
-	       pud_t *pud, int write)
+follow_huge_pud(struct vm_area_struct *vma, unsigned long address,
+	       pud_t *pud, int flags)
 {
 	BUG();
 	return NULL;
-- 
1.9.3

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

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

* [PATCH 2/3] mm/hugetlb: take refcount under page table lock in follow_huge_pmd()
  2014-07-28 18:08 [PATCH 1/3] mm/hugetlb: replace parameters of follow_huge_pmd/pud() Naoya Horiguchi
@ 2014-07-28 18:08 ` Naoya Horiguchi
  2014-07-28 23:02   ` David Rientjes
  2014-07-28 18:08 ` [PATCH 3/3] mm/hugetlb: use get_page_unless_zero() in hugetlb_fault() Naoya Horiguchi
  2014-07-28 22:55 ` [PATCH 1/3] mm/hugetlb: replace parameters of follow_huge_pmd/pud() David Rientjes
  2 siblings, 1 reply; 6+ messages in thread
From: Naoya Horiguchi @ 2014-07-28 18:08 UTC (permalink / raw)
  To: Andrew Morton, Hugh Dickins; +Cc: linux-mm, linux-kernel, Naoya Horiguchi

We have a race condition between move_pages() and freeing hugepages,
where move_pages() calls follow_page(FOLL_GET) for hugepages internally
and tries to get its refcount without preventing concurrent freeing.
This race crashes the kernel, so this patch fixes it by moving FOLL_GET
code for hugepages into follow_huge_pmd() with taking the page table lock.

This patch passes the following test. And libhugetlbfs test shows no
regression.

  $ cat move_pages.c
  #include <stdio.h>
  #include <stdlib.h>
  #include <numaif.h>

  #define ADDR_INPUT      0x700000000000
  #define HPS             0x200000
  #define PS              0x1000

  int main(int argc, char *argv[]) {
          int i;
          int nr_hp = 1;
          int nr_p  = nr_hp * HPS / PS;
          int ret;
          void **addrs;
          int *status;
          int *nodes;
          pid_t pid;

          if (argc < 2) {
                  fprintf(stderr, "no args for pid\n");
                  exit(EXIT_FAILURE);
          }

          pid = strtol(argv[1], NULL, 0);
          addrs  = malloc(sizeof(char *) * nr_p + 1);
          status = malloc(sizeof(char *) * nr_p + 1);
          nodes  = malloc(sizeof(char *) * nr_p + 1);

          while (1) {
                  for (i = 0; i < nr_p; i++) {
                          addrs[i] = (void *)ADDR_INPUT + i * PS;
                          nodes[i] = 1;
                          status[i] = 0;
                  }
                  ret = numa_move_pages(pid, nr_p, addrs, nodes, status,
                                        MPOL_MF_MOVE_ALL);
                  if (ret == -1)
                          err("move_pages");

                  for (i = 0; i < nr_p; i++) {
                          addrs[i] = (void *)ADDR_INPUT + i * PS;
                          nodes[i] = 0;
                          status[i] = 0;
                  }
                  ret = numa_move_pages(pid, nr_p, addrs, nodes, status,
                                        MPOL_MF_MOVE_ALL);
                  if (ret == -1)
                          err("move_pages");
          }
          return 0;
  }

  $ cat hugepage.c
  #include <stdio.h>
  #include <sys/mman.h>
  #include <string.h>

  #define ADDR_INPUT      0x700000000000UL
  #define HPS             0x200000

  int main(int argc, char *argv[]) {
          char *p;

          while (1) {
                  p = mmap((void *)ADDR_INPUT, HPS, PROT_READ | PROT_WRITE,
                           MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB, -1, 0);
                  if (p != (void *)ADDR_INPUT) {
                          perror("mmap");
                          break;
                  }
                  memset(p, 0, HPS);
                  munmap(p, HPS);
          }
  }

  $ sysctl vm.nr_hugepages=10
  $ ./hugepage &
  $ ./move_pages $(pgrep -f hugepage)

Note for stable inclusion:
  This patch fixes e632a938d914 ("mm: migrate: add hugepage migration code
  to move_pages()"), so is applicable to -stable kernels which includes it.
  And this patch depends on the patch "mm/hugetlb: replace parameters of
  follow_huge_pmd/pud()".

Signed-off-by: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
Cc: <stable@vger.kernel.org>  # [3.12+]
---
 mm/gup.c     | 17 ++---------------
 mm/hugetlb.c | 18 ++++++++++++++++++
 2 files changed, 20 insertions(+), 15 deletions(-)

diff --git mmotm-2014-07-22-15-58.orig/mm/gup.c mmotm-2014-07-22-15-58/mm/gup.c
index ba2c933625b2..ecd5dc0e2952 100644
--- mmotm-2014-07-22-15-58.orig/mm/gup.c
+++ mmotm-2014-07-22-15-58/mm/gup.c
@@ -174,21 +174,8 @@ struct page *follow_page_mask(struct vm_area_struct *vma,
 	pmd = pmd_offset(pud, address);
 	if (pmd_none(*pmd))
 		return no_page_table(vma, flags);
-	if (pmd_huge(*pmd) && vma->vm_flags & VM_HUGETLB) {
-		page = follow_huge_pmd(vma, address, pmd, flags);
-		if (flags & FOLL_GET) {
-			/*
-			 * Refcount on tail pages are not well-defined and
-			 * shouldn't be taken. The caller should handle a NULL
-			 * return when trying to follow tail pages.
-			 */
-			if (PageHead(page))
-				get_page(page);
-			else
-				page = NULL;
-		}
-		return page;
-	}
+	if (pmd_huge(*pmd) && vma->vm_flags & VM_HUGETLB)
+		return follow_huge_pmd(vma, address, pmd, flags);
 	if ((flags & FOLL_NUMA) && pmd_numa(*pmd))
 		return no_page_table(vma, flags);
 	if (pmd_trans_huge(*pmd)) {
diff --git mmotm-2014-07-22-15-58.orig/mm/hugetlb.c mmotm-2014-07-22-15-58/mm/hugetlb.c
index ade297a9c519..6793914b6aac 100644
--- mmotm-2014-07-22-15-58.orig/mm/hugetlb.c
+++ mmotm-2014-07-22-15-58/mm/hugetlb.c
@@ -3655,10 +3655,28 @@ follow_huge_pmd(struct vm_area_struct *vma, unsigned long address,
 		pmd_t *pmd, int flags)
 {
 	struct page *page;
+	spinlock_t *ptl;
+
+	if (flags & FOLL_GET)
+		ptl = huge_pte_lock(hstate_vma(vma), vma->vm_mm, (pte_t *)pmd);
 
 	page = pte_page(*(pte_t *)pmd);
 	if (page)
 		page += ((address & ~PMD_MASK) >> PAGE_SHIFT);
+
+	if (flags & FOLL_GET) {
+		/*
+		 * Refcount on tail pages are not well-defined and
+		 * shouldn't be taken. The caller should handle a NULL
+		 * return when trying to follow tail pages.
+		 */
+		if (PageHead(page))
+			get_page(page);
+		else
+			page = NULL;
+		spin_unlock(ptl);
+	}
+
 	return page;
 }
 
-- 
1.9.3

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

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

* [PATCH 3/3] mm/hugetlb: use get_page_unless_zero() in hugetlb_fault()
  2014-07-28 18:08 [PATCH 1/3] mm/hugetlb: replace parameters of follow_huge_pmd/pud() Naoya Horiguchi
  2014-07-28 18:08 ` [PATCH 2/3] mm/hugetlb: take refcount under page table lock in follow_huge_pmd() Naoya Horiguchi
@ 2014-07-28 18:08 ` Naoya Horiguchi
  2014-07-28 22:55 ` [PATCH 1/3] mm/hugetlb: replace parameters of follow_huge_pmd/pud() David Rientjes
  2 siblings, 0 replies; 6+ messages in thread
From: Naoya Horiguchi @ 2014-07-28 18:08 UTC (permalink / raw)
  To: Andrew Morton, Hugh Dickins; +Cc: linux-mm, linux-kernel, Naoya Horiguchi

After fixing the race in follow_page(FOLL_GET) for hugepages, I start to
observe the BUG of "get_page() on refcount 0 page" in hugetlb_fault() in
the same test.

I'm not exactly sure about how this race is triggered, but hugetlb_fault()
calls pte_page() and get_page() outside page table lock, so it's not safe.
This patch checks the refcount of the gotten page, and aborts the page fault
if the refcount is 0, expecting to retry.

Signed-off-by: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
Cc: <stable@vger.kernel.org>  # [3.12+]
---
 mm/hugetlb.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git mmotm-2014-07-22-15-58.orig/mm/hugetlb.c mmotm-2014-07-22-15-58/mm/hugetlb.c
index 6793914b6aac..86e7341aad77 100644
--- mmotm-2014-07-22-15-58.orig/mm/hugetlb.c
+++ mmotm-2014-07-22-15-58/mm/hugetlb.c
@@ -3189,7 +3189,8 @@ int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma,
 	 * so no worry about deadlock.
 	 */
 	page = pte_page(entry);
-	get_page(page);
+	if (!get_page_unless_zero(page))
+		goto out_put_pagecache;
 	if (page != pagecache_page)
 		lock_page(page);
 
@@ -3215,15 +3216,14 @@ int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma,
 
 out_ptl:
 	spin_unlock(ptl);
-
+	if (page != pagecache_page)
+		unlock_page(page);
+	put_page(page);
+out_put_pagecache:
 	if (pagecache_page) {
 		unlock_page(pagecache_page);
 		put_page(pagecache_page);
 	}
-	if (page != pagecache_page)
-		unlock_page(page);
-	put_page(page);
-
 out_mutex:
 	mutex_unlock(&htlb_fault_mutex_table[hash]);
 	return ret;
-- 
1.9.3

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

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

* Re: [PATCH 1/3] mm/hugetlb: replace parameters of follow_huge_pmd/pud()
  2014-07-28 18:08 [PATCH 1/3] mm/hugetlb: replace parameters of follow_huge_pmd/pud() Naoya Horiguchi
  2014-07-28 18:08 ` [PATCH 2/3] mm/hugetlb: take refcount under page table lock in follow_huge_pmd() Naoya Horiguchi
  2014-07-28 18:08 ` [PATCH 3/3] mm/hugetlb: use get_page_unless_zero() in hugetlb_fault() Naoya Horiguchi
@ 2014-07-28 22:55 ` David Rientjes
  2 siblings, 0 replies; 6+ messages in thread
From: David Rientjes @ 2014-07-28 22:55 UTC (permalink / raw)
  To: Naoya Horiguchi
  Cc: Andrew Morton, Hugh Dickins, linux-mm, linux-kernel, Naoya Horiguchi

On Mon, 28 Jul 2014, Naoya Horiguchi wrote:

> Currently follow_huge_pmd() and follow_huge_pud() don't use the parameter
> mm or write. So let's change these to vma and flags as a preparation for
> the next patch. No behavioral change.
> 
> Signed-off-by: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>

Acked-by: David Rientjes <rientjes@google.com>

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

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

* Re: [PATCH 2/3] mm/hugetlb: take refcount under page table lock in follow_huge_pmd()
  2014-07-28 18:08 ` [PATCH 2/3] mm/hugetlb: take refcount under page table lock in follow_huge_pmd() Naoya Horiguchi
@ 2014-07-28 23:02   ` David Rientjes
  2014-07-29  1:10     ` Naoya Horiguchi
  0 siblings, 1 reply; 6+ messages in thread
From: David Rientjes @ 2014-07-28 23:02 UTC (permalink / raw)
  To: Naoya Horiguchi
  Cc: Andrew Morton, Hugh Dickins, linux-mm, linux-kernel, Naoya Horiguchi

On Mon, 28 Jul 2014, Naoya Horiguchi wrote:

> We have a race condition between move_pages() and freeing hugepages,
> where move_pages() calls follow_page(FOLL_GET) for hugepages internally
> and tries to get its refcount without preventing concurrent freeing.
> This race crashes the kernel, so this patch fixes it by moving FOLL_GET
> code for hugepages into follow_huge_pmd() with taking the page table lock.
> 

What about CONFIG_ARCH_WANT_GENERAL_HUGETLB=n configs?

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

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

* Re: [PATCH 2/3] mm/hugetlb: take refcount under page table lock in follow_huge_pmd()
  2014-07-28 23:02   ` David Rientjes
@ 2014-07-29  1:10     ` Naoya Horiguchi
  0 siblings, 0 replies; 6+ messages in thread
From: Naoya Horiguchi @ 2014-07-29  1:10 UTC (permalink / raw)
  To: David Rientjes
  Cc: Andrew Morton, Hugh Dickins, linux-mm, linux-kernel, Naoya Horiguchi

On Mon, Jul 28, 2014 at 04:02:31PM -0700, David Rientjes wrote:
> On Mon, 28 Jul 2014, Naoya Horiguchi wrote:
> 
> > We have a race condition between move_pages() and freeing hugepages,
> > where move_pages() calls follow_page(FOLL_GET) for hugepages internally
> > and tries to get its refcount without preventing concurrent freeing.
> > This race crashes the kernel, so this patch fixes it by moving FOLL_GET
> > code for hugepages into follow_huge_pmd() with taking the page table lock.
> > 
> 
> What about CONFIG_ARCH_WANT_GENERAL_HUGETLB=n configs?

Ah yes, I need cover them.
So I'll add some wrapper to do this locking in common hugetlb code.

Thanks,
Naoya Horiguchi

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

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

end of thread, other threads:[~2014-07-29  2:02 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-07-28 18:08 [PATCH 1/3] mm/hugetlb: replace parameters of follow_huge_pmd/pud() Naoya Horiguchi
2014-07-28 18:08 ` [PATCH 2/3] mm/hugetlb: take refcount under page table lock in follow_huge_pmd() Naoya Horiguchi
2014-07-28 23:02   ` David Rientjes
2014-07-29  1:10     ` Naoya Horiguchi
2014-07-28 18:08 ` [PATCH 3/3] mm/hugetlb: use get_page_unless_zero() in hugetlb_fault() Naoya Horiguchi
2014-07-28 22:55 ` [PATCH 1/3] mm/hugetlb: replace parameters of follow_huge_pmd/pud() David Rientjes

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox