All of lore.kernel.org
 help / color / mirror / Atom feed
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.