diff for duplicates of <20160118133852.GC14531@node.shutemov.name> diff --git a/a/1.txt b/N1/1.txt index 901489e..d5bea84 100644 --- a/a/1.txt +++ b/N1/1.txt @@ -123,3 +123,67 @@ On Mon, Jan 18, 2016 at 02:08:15PM +0100, Dmitry Vyukov wrote: Thanks for report. I think this should fix the issue: + +>From 10859758dadfa249616870f63c1636ec9857c501 Mon Sep 17 00:00:00 2001 +From: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com> +Date: Mon, 18 Jan 2016 16:28:12 +0300 +Subject: [PATCH] thp: fix interrupt unsafe locking in split_huge_page() + +split_queue_lock can be taken from interrupt context in some cases, but +I forgot to convert locking in split_huge_page() to interrupt-safe +primitives. + +Let's fix this. + +Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> +Reported-by: Dmitry Vyukov <dvyukov@google.com> +--- + mm/huge_memory.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/mm/huge_memory.c b/mm/huge_memory.c +index 50342eff7960..21fda6a10e89 100644 +--- a/mm/huge_memory.c ++++ b/mm/huge_memory.c +@@ -3357,6 +3357,7 @@ int split_huge_page_to_list(struct page *page, struct list_head *list) + struct anon_vma *anon_vma; + int count, mapcount, ret; + bool mlocked; ++ unsigned long flags; + + VM_BUG_ON_PAGE(is_huge_zero_page(page), page); + VM_BUG_ON_PAGE(!PageAnon(page), page); +@@ -3396,7 +3397,7 @@ int split_huge_page_to_list(struct page *page, struct list_head *list) + lru_add_drain(); + + /* Prevent deferred_split_scan() touching ->_count */ +- spin_lock(&split_queue_lock); ++ spin_lock_irqsave(&split_queue_lock, flags); + count = page_count(head); + mapcount = total_mapcount(head); + if (!mapcount && count == 1) { +@@ -3404,11 +3405,11 @@ int split_huge_page_to_list(struct page *page, struct list_head *list) + split_queue_len--; + list_del(page_deferred_list(head)); + } +- spin_unlock(&split_queue_lock); ++ spin_unlock_irqrestore(&split_queue_lock, flags); + __split_huge_page(page, list); + ret = 0; + } else if (IS_ENABLED(CONFIG_DEBUG_VM) && mapcount) { +- spin_unlock(&split_queue_lock); ++ spin_unlock_irqrestore(&split_queue_lock, flags); + pr_alert("total_mapcount: %u, page_count(): %u\n", + mapcount, count); + if (PageTail(page)) +@@ -3416,7 +3417,7 @@ int split_huge_page_to_list(struct page *page, struct list_head *list) + dump_page(page, "total_mapcount(head) > 0"); + BUG(); + } else { +- spin_unlock(&split_queue_lock); ++ spin_unlock_irqrestore(&split_queue_lock, flags); + unfreeze_page(anon_vma, head); + ret = -EBUSY; + } +-- + Kirill A. Shutemov diff --git a/a/content_digest b/N1/content_digest index 6fd8c19..f997142 100644 --- a/a/content_digest +++ b/N1/content_digest @@ -148,6 +148,70 @@ "\n" "Thanks for report.\n" "\n" - I think this should fix the issue: + "I think this should fix the issue:\n" + "\n" + ">From 10859758dadfa249616870f63c1636ec9857c501 Mon Sep 17 00:00:00 2001\n" + "From: \"Kirill A. Shutemov\" <kirill.shutemov@linux.intel.com>\n" + "Date: Mon, 18 Jan 2016 16:28:12 +0300\n" + "Subject: [PATCH] thp: fix interrupt unsafe locking in split_huge_page()\n" + "\n" + "split_queue_lock can be taken from interrupt context in some cases, but\n" + "I forgot to convert locking in split_huge_page() to interrupt-safe\n" + "primitives.\n" + "\n" + "Let's fix this.\n" + "\n" + "Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>\n" + "Reported-by: Dmitry Vyukov <dvyukov@google.com>\n" + "---\n" + " mm/huge_memory.c | 9 +++++----\n" + " 1 file changed, 5 insertions(+), 4 deletions(-)\n" + "\n" + "diff --git a/mm/huge_memory.c b/mm/huge_memory.c\n" + "index 50342eff7960..21fda6a10e89 100644\n" + "--- a/mm/huge_memory.c\n" + "+++ b/mm/huge_memory.c\n" + "@@ -3357,6 +3357,7 @@ int split_huge_page_to_list(struct page *page, struct list_head *list)\n" + " \tstruct anon_vma *anon_vma;\n" + " \tint count, mapcount, ret;\n" + " \tbool mlocked;\n" + "+\tunsigned long flags;\n" + " \n" + " \tVM_BUG_ON_PAGE(is_huge_zero_page(page), page);\n" + " \tVM_BUG_ON_PAGE(!PageAnon(page), page);\n" + "@@ -3396,7 +3397,7 @@ int split_huge_page_to_list(struct page *page, struct list_head *list)\n" + " \t\tlru_add_drain();\n" + " \n" + " \t/* Prevent deferred_split_scan() touching ->_count */\n" + "-\tspin_lock(&split_queue_lock);\n" + "+\tspin_lock_irqsave(&split_queue_lock, flags);\n" + " \tcount = page_count(head);\n" + " \tmapcount = total_mapcount(head);\n" + " \tif (!mapcount && count == 1) {\n" + "@@ -3404,11 +3405,11 @@ int split_huge_page_to_list(struct page *page, struct list_head *list)\n" + " \t\t\tsplit_queue_len--;\n" + " \t\t\tlist_del(page_deferred_list(head));\n" + " \t\t}\n" + "-\t\tspin_unlock(&split_queue_lock);\n" + "+\t\tspin_unlock_irqrestore(&split_queue_lock, flags);\n" + " \t\t__split_huge_page(page, list);\n" + " \t\tret = 0;\n" + " \t} else if (IS_ENABLED(CONFIG_DEBUG_VM) && mapcount) {\n" + "-\t\tspin_unlock(&split_queue_lock);\n" + "+\t\tspin_unlock_irqrestore(&split_queue_lock, flags);\n" + " \t\tpr_alert(\"total_mapcount: %u, page_count(): %u\\n\",\n" + " \t\t\t\tmapcount, count);\n" + " \t\tif (PageTail(page))\n" + "@@ -3416,7 +3417,7 @@ int split_huge_page_to_list(struct page *page, struct list_head *list)\n" + " \t\tdump_page(page, \"total_mapcount(head) > 0\");\n" + " \t\tBUG();\n" + " \t} else {\n" + "-\t\tspin_unlock(&split_queue_lock);\n" + "+\t\tspin_unlock_irqrestore(&split_queue_lock, flags);\n" + " \t\tunfreeze_page(anon_vma, head);\n" + " \t\tret = -EBUSY;\n" + " \t}\n" + "-- \n" + Kirill A. Shutemov -b2e81cb3fa2db9e2a4db3b80fc61e27e1cd8428e570638199c3fd5f121021c1c +41b071aee67ad67e1ec2d0de0cd4517dd0a9f3c1f018c5ea6afc7b348c005667
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.