|
@@ -1422,19 +1422,6 @@ static int __get_any_page(struct page *p, unsigned long pfn, int flags)
|
|
|
if (flags & MF_COUNT_INCREASED)
|
|
|
return 1;
|
|
|
|
|
|
- /*
|
|
|
- * The lock_memory_hotplug prevents a race with memory hotplug.
|
|
|
- * This is a big hammer, a better would be nicer.
|
|
|
- */
|
|
|
- lock_memory_hotplug();
|
|
|
-
|
|
|
- /*
|
|
|
- * Isolate the page, so that it doesn't get reallocated if it
|
|
|
- * was free. This flag should be kept set until the source page
|
|
|
- * is freed and PG_hwpoison on it is set.
|
|
|
- */
|
|
|
- if (get_pageblock_migratetype(p) != MIGRATE_ISOLATE)
|
|
|
- set_migratetype_isolate(p, true);
|
|
|
/*
|
|
|
* When the target page is a free hugepage, just remove it
|
|
|
* from free hugepage list.
|
|
@@ -1455,7 +1442,6 @@ static int __get_any_page(struct page *p, unsigned long pfn, int flags)
|
|
|
/* Not a free page */
|
|
|
ret = 1;
|
|
|
}
|
|
|
- unlock_memory_hotplug();
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
@@ -1654,15 +1640,28 @@ int soft_offline_page(struct page *page, int flags)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /*
|
|
|
+ * The lock_memory_hotplug prevents a race with memory hotplug.
|
|
|
+ * This is a big hammer, a better would be nicer.
|
|
|
+ */
|
|
|
+ lock_memory_hotplug();
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Isolate the page, so that it doesn't get reallocated if it
|
|
|
+ * was free. This flag should be kept set until the source page
|
|
|
+ * is freed and PG_hwpoison on it is set.
|
|
|
+ */
|
|
|
+ if (get_pageblock_migratetype(page) != MIGRATE_ISOLATE)
|
|
|
+ set_migratetype_isolate(page, true);
|
|
|
+
|
|
|
ret = get_any_page(page, pfn, flags);
|
|
|
- if (ret < 0)
|
|
|
- goto unset;
|
|
|
- if (ret) { /* for in-use pages */
|
|
|
+ unlock_memory_hotplug();
|
|
|
+ if (ret > 0) { /* for in-use pages */
|
|
|
if (PageHuge(page))
|
|
|
ret = soft_offline_huge_page(page, flags);
|
|
|
else
|
|
|
ret = __soft_offline_page(page, flags);
|
|
|
- } else { /* for free pages */
|
|
|
+ } else if (ret == 0) { /* for free pages */
|
|
|
if (PageHuge(page)) {
|
|
|
set_page_hwpoison_huge_page(hpage);
|
|
|
dequeue_hwpoisoned_huge_page(hpage);
|
|
@@ -1673,7 +1672,6 @@ int soft_offline_page(struct page *page, int flags)
|
|
|
atomic_long_inc(&num_poisoned_pages);
|
|
|
}
|
|
|
}
|
|
|
-unset:
|
|
|
unset_migratetype_isolate(page, MIGRATE_MOVABLE);
|
|
|
return ret;
|
|
|
}
|