We're going to use migration entries instead of compound_lock() to
stabilize page refcounts. Setup and remove migration entries require
page to be locked.

Some of split_huge_page() callers already have the page locked. Let's
require everybody to lock the page before calling split_huge_page().

Signed-off-by: Kirill A. Shutemov <kirill.shute...@linux.intel.com>
---
 mm/huge_memory.c    |  1 +
 mm/ksm.c            |  6 ++++--
 mm/memory-failure.c | 12 +++++++++---
 mm/migrate.c        |  8 ++++++--
 4 files changed, 20 insertions(+), 7 deletions(-)

diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 3741f81e423e..f1d88b9059e2 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -1846,6 +1846,7 @@ int split_huge_page_to_list(struct page *page, struct 
list_head *list)
 
        BUG_ON(is_huge_zero_page(page));
        BUG_ON(!PageAnon(page));
+       BUG_ON(!PageLocked(page));
 
        /*
         * The caller does not necessarily hold an mmap_sem that would prevent
diff --git a/mm/ksm.c b/mm/ksm.c
index 92182eeba87d..a8a88b0f6f62 100644
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -987,9 +987,11 @@ static int page_trans_compound_anon_split(struct page 
*page)
                         * Recheck we got the reference while the head
                         * was still anonymous.
                         */
-                       if (PageAnon(transhuge_head))
+                       if (PageAnon(transhuge_head)) {
+                               lock_page(transhuge_head);
                                ret = split_huge_page(transhuge_head);
-                       else
+                               unlock_page(transhuge_head);
+                       } else
                                /*
                                 * Retry later if split_huge_page run
                                 * from under us.
diff --git a/mm/memory-failure.c b/mm/memory-failure.c
index d487f8dc6d39..74c5aaddae85 100644
--- a/mm/memory-failure.c
+++ b/mm/memory-failure.c
@@ -950,7 +950,10 @@ static int hwpoison_user_mappings(struct page *p, unsigned 
long pfn,
                 * enough * to be safe.
                 */
                if (!PageHuge(hpage) && PageAnon(hpage)) {
-                       if (unlikely(split_huge_page(hpage))) {
+                       lock_page(hpage);
+                       ret = split_huge_page(hpage);
+                       unlock_page(hpage);
+                       if (unlikely(ret)) {
                                /*
                                 * FIXME: if splitting THP is failed, it is
                                 * better to stop the following operation rather
@@ -1694,10 +1697,13 @@ int soft_offline_page(struct page *page, int flags)
                return -EBUSY;
        }
        if (!PageHuge(page) && PageTransHuge(hpage)) {
-               if (PageAnon(hpage) && unlikely(split_huge_page(hpage))) {
+               lock_page(page);
+               ret = split_huge_page(hpage);
+               unlock_page(page);
+               if (unlikely(ret)) {
                        pr_info("soft offline: %#lx: failed to split THP\n",
                                pfn);
-                       return -EBUSY;
+                       return ret;
                }
        }
 
diff --git a/mm/migrate.c b/mm/migrate.c
index 01449826b914..91a67029bb18 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -920,9 +920,13 @@ static int unmap_and_move(new_page_t get_new_page, 
free_page_t put_new_page,
                goto out;
        }
 
-       if (unlikely(PageTransHuge(page)))
-               if (unlikely(split_huge_page(page)))
+       if (unlikely(PageTransHuge(page))) {
+               lock_page(page);
+               rc = split_huge_page(page);
+               unlock_page(page);
+               if (rc)
                        goto out;
+       }
 
        rc = __unmap_and_move(page, newpage, force, mode);
 
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to