All of lore.kernel.org
 help / color / mirror / Atom feed
diff for duplicates of <20160128154746.GI12228@redhat.com>

diff --git a/a/1.txt b/N1/1.txt
index 3210a31..d695421 100644
--- a/a/1.txt
+++ b/N1/1.txt
@@ -7,3 +7,62 @@ On Wed, Jan 27, 2016 at 10:11:44PM +0100, Dmitry Vyukov wrote:
 > for  at least an hour.
 
 Does this help for the mm bug?
+
+>From 0cc410ae59800444ca929e3dc48e4f1580a95be6 Mon Sep 17 00:00:00 2001
+From: Andrea Arcangeli <aarcange@redhat.com>
+Date: Thu, 28 Jan 2016 16:34:44 +0100
+Subject: [PATCH 1/1] mm: validate_mm browse_rb SMP race condition
+
+The mmap_sem for reading in validate_mm called from expand_stack is
+not enough to prevent the argumented rbtree rb_subtree_gap information
+to change from under us because expand_stack may be running from other
+threads concurrently which will hold the mmap_sem for reading too.
+
+The argumented rbtree is updated with vma_gap_update under the
+page_table_lock so use it in browse_rb() too to avoid false positives.
+
+Reported-by: Dmitry Vyukov <dvyukov@google.com>
+Signed-off-by: Andrea Arcangeli <aarcange@redhat.com>
+---
+ mm/mmap.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/mm/mmap.c b/mm/mmap.c
+index f384def..8389e03 100644
+--- a/mm/mmap.c
++++ b/mm/mmap.c
+@@ -389,8 +389,9 @@ static long vma_compute_subtree_gap(struct vm_area_struct *vma)
+ }
+ 
+ #ifdef CONFIG_DEBUG_VM_RB
+-static int browse_rb(struct rb_root *root)
++static int browse_rb(struct mm_struct *mm)
+ {
++	struct rb_root *root = &mm->mm_rb;
+ 	int i = 0, j, bug = 0;
+ 	struct rb_node *nd, *pn = NULL;
+ 	unsigned long prev = 0, pend = 0;
+@@ -413,12 +414,14 @@ static int browse_rb(struct rb_root *root)
+ 				  vma->vm_start, vma->vm_end);
+ 			bug = 1;
+ 		}
++		spin_lock(&mm->page_table_lock);
+ 		if (vma->rb_subtree_gap != vma_compute_subtree_gap(vma)) {
+ 			pr_emerg("free gap %lx, correct %lx\n",
+ 			       vma->rb_subtree_gap,
+ 			       vma_compute_subtree_gap(vma));
+ 			bug = 1;
+ 		}
++		spin_unlock(&mm->page_table_lock);
+ 		i++;
+ 		pn = nd;
+ 		prev = vma->vm_start;
+@@ -474,7 +477,7 @@ static void validate_mm(struct mm_struct *mm)
+ 			  mm->highest_vm_end, highest_address);
+ 		bug = 1;
+ 	}
+-	i = browse_rb(&mm->mm_rb);
++	i = browse_rb(mm);
+ 	if (i != mm->map_count) {
+ 		if (i != -1)
+ 			pr_emerg("map_count %d rb %d\n", mm->map_count, i);
diff --git a/a/content_digest b/N1/content_digest
index 4439fbe..e808081 100644
--- a/a/content_digest
+++ b/N1/content_digest
@@ -32,6 +32,65 @@
  "> loop with CPU oversubscription (e.g. 32 parallel processes on 2 cores)\n"
  "> for  at least an hour.\n"
  "\n"
- Does this help for the mm bug?
+ "Does this help for the mm bug?\n"
+ "\n"
+ ">From 0cc410ae59800444ca929e3dc48e4f1580a95be6 Mon Sep 17 00:00:00 2001\n"
+ "From: Andrea Arcangeli <aarcange@redhat.com>\n"
+ "Date: Thu, 28 Jan 2016 16:34:44 +0100\n"
+ "Subject: [PATCH 1/1] mm: validate_mm browse_rb SMP race condition\n"
+ "\n"
+ "The mmap_sem for reading in validate_mm called from expand_stack is\n"
+ "not enough to prevent the argumented rbtree rb_subtree_gap information\n"
+ "to change from under us because expand_stack may be running from other\n"
+ "threads concurrently which will hold the mmap_sem for reading too.\n"
+ "\n"
+ "The argumented rbtree is updated with vma_gap_update under the\n"
+ "page_table_lock so use it in browse_rb() too to avoid false positives.\n"
+ "\n"
+ "Reported-by: Dmitry Vyukov <dvyukov@google.com>\n"
+ "Signed-off-by: Andrea Arcangeli <aarcange@redhat.com>\n"
+ "---\n"
+ " mm/mmap.c | 7 +++++--\n"
+ " 1 file changed, 5 insertions(+), 2 deletions(-)\n"
+ "\n"
+ "diff --git a/mm/mmap.c b/mm/mmap.c\n"
+ "index f384def..8389e03 100644\n"
+ "--- a/mm/mmap.c\n"
+ "+++ b/mm/mmap.c\n"
+ "@@ -389,8 +389,9 @@ static long vma_compute_subtree_gap(struct vm_area_struct *vma)\n"
+ " }\n"
+ " \n"
+ " #ifdef CONFIG_DEBUG_VM_RB\n"
+ "-static int browse_rb(struct rb_root *root)\n"
+ "+static int browse_rb(struct mm_struct *mm)\n"
+ " {\n"
+ "+\tstruct rb_root *root = &mm->mm_rb;\n"
+ " \tint i = 0, j, bug = 0;\n"
+ " \tstruct rb_node *nd, *pn = NULL;\n"
+ " \tunsigned long prev = 0, pend = 0;\n"
+ "@@ -413,12 +414,14 @@ static int browse_rb(struct rb_root *root)\n"
+ " \t\t\t\t  vma->vm_start, vma->vm_end);\n"
+ " \t\t\tbug = 1;\n"
+ " \t\t}\n"
+ "+\t\tspin_lock(&mm->page_table_lock);\n"
+ " \t\tif (vma->rb_subtree_gap != vma_compute_subtree_gap(vma)) {\n"
+ " \t\t\tpr_emerg(\"free gap %lx, correct %lx\\n\",\n"
+ " \t\t\t       vma->rb_subtree_gap,\n"
+ " \t\t\t       vma_compute_subtree_gap(vma));\n"
+ " \t\t\tbug = 1;\n"
+ " \t\t}\n"
+ "+\t\tspin_unlock(&mm->page_table_lock);\n"
+ " \t\ti++;\n"
+ " \t\tpn = nd;\n"
+ " \t\tprev = vma->vm_start;\n"
+ "@@ -474,7 +477,7 @@ static void validate_mm(struct mm_struct *mm)\n"
+ " \t\t\t  mm->highest_vm_end, highest_address);\n"
+ " \t\tbug = 1;\n"
+ " \t}\n"
+ "-\ti = browse_rb(&mm->mm_rb);\n"
+ "+\ti = browse_rb(mm);\n"
+ " \tif (i != mm->map_count) {\n"
+ " \t\tif (i != -1)\n"
+ " \t\t\tpr_emerg(\"map_count %d rb %d\\n\", mm->map_count, i);"
 
-abfecc0d3e2502867e6612c73a537993c8e45553d5b15bb06196cd8069aceabe
+7dc422501a90eaa9db364812b07ee17b6f6fd9a512000a06546853f11f26d349

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.