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.