aboutsummaryrefslogtreecommitdiffstats
path: root/mm/memory_hotplug.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/memory_hotplug.c')
-rw-r--r--mm/memory_hotplug.c42
1 files changed, 35 insertions, 7 deletions
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index d595606728f9..0eb1a1df649d 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -30,6 +30,7 @@
30#include <linux/mm_inline.h> 30#include <linux/mm_inline.h>
31#include <linux/firmware-map.h> 31#include <linux/firmware-map.h>
32#include <linux/stop_machine.h> 32#include <linux/stop_machine.h>
33#include <linux/hugetlb.h>
33 34
34#include <asm/tlbflush.h> 35#include <asm/tlbflush.h>
35 36
@@ -1230,10 +1231,12 @@ static int test_pages_in_a_zone(unsigned long start_pfn, unsigned long end_pfn)
1230} 1231}
1231 1232
1232/* 1233/*
1233 * Scanning pfn is much easier than scanning lru list. 1234 * Scan pfn range [start,end) to find movable/migratable pages (LRU pages
1234 * Scan pfn from start to end and Find LRU page. 1235 * and hugepages). We scan pfn because it's much easier than scanning over
1236 * linked list. This function returns the pfn of the first found movable
1237 * page if it's found, otherwise 0.
1235 */ 1238 */
1236static unsigned long scan_lru_pages(unsigned long start, unsigned long end) 1239static unsigned long scan_movable_pages(unsigned long start, unsigned long end)
1237{ 1240{
1238 unsigned long pfn; 1241 unsigned long pfn;
1239 struct page *page; 1242 struct page *page;
@@ -1242,6 +1245,13 @@ static unsigned long scan_lru_pages(unsigned long start, unsigned long end)
1242 page = pfn_to_page(pfn); 1245 page = pfn_to_page(pfn);
1243 if (PageLRU(page)) 1246 if (PageLRU(page))
1244 return pfn; 1247 return pfn;
1248 if (PageHuge(page)) {
1249 if (is_hugepage_active(page))
1250 return pfn;
1251 else
1252 pfn = round_up(pfn + 1,
1253 1 << compound_order(page)) - 1;
1254 }
1245 } 1255 }
1246 } 1256 }
1247 return 0; 1257 return 0;
@@ -1262,6 +1272,19 @@ do_migrate_range(unsigned long start_pfn, unsigned long end_pfn)
1262 if (!pfn_valid(pfn)) 1272 if (!pfn_valid(pfn))
1263 continue; 1273 continue;
1264 page = pfn_to_page(pfn); 1274 page = pfn_to_page(pfn);
1275
1276 if (PageHuge(page)) {
1277 struct page *head = compound_head(page);
1278 pfn = page_to_pfn(head) + (1<<compound_order(head)) - 1;
1279 if (compound_order(head) > PFN_SECTION_SHIFT) {
1280 ret = -EBUSY;
1281 break;
1282 }
1283 if (isolate_huge_page(page, &source))
1284 move_pages -= 1 << compound_order(head);
1285 continue;
1286 }
1287
1265 if (!get_page_unless_zero(page)) 1288 if (!get_page_unless_zero(page))
1266 continue; 1289 continue;
1267 /* 1290 /*
@@ -1294,7 +1317,7 @@ do_migrate_range(unsigned long start_pfn, unsigned long end_pfn)
1294 } 1317 }
1295 if (!list_empty(&source)) { 1318 if (!list_empty(&source)) {
1296 if (not_managed) { 1319 if (not_managed) {
1297 putback_lru_pages(&source); 1320 putback_movable_pages(&source);
1298 goto out; 1321 goto out;
1299 } 1322 }
1300 1323
@@ -1305,7 +1328,7 @@ do_migrate_range(unsigned long start_pfn, unsigned long end_pfn)
1305 ret = migrate_pages(&source, alloc_migrate_target, 0, 1328 ret = migrate_pages(&source, alloc_migrate_target, 0,
1306 MIGRATE_SYNC, MR_MEMORY_HOTPLUG); 1329 MIGRATE_SYNC, MR_MEMORY_HOTPLUG);
1307 if (ret) 1330 if (ret)
1308 putback_lru_pages(&source); 1331 putback_movable_pages(&source);
1309 } 1332 }
1310out: 1333out:
1311 return ret; 1334 return ret;
@@ -1548,8 +1571,8 @@ repeat:
1548 drain_all_pages(); 1571 drain_all_pages();
1549 } 1572 }
1550 1573
1551 pfn = scan_lru_pages(start_pfn, end_pfn); 1574 pfn = scan_movable_pages(start_pfn, end_pfn);
1552 if (pfn) { /* We have page on LRU */ 1575 if (pfn) { /* We have movable pages */
1553 ret = do_migrate_range(pfn, end_pfn); 1576 ret = do_migrate_range(pfn, end_pfn);
1554 if (!ret) { 1577 if (!ret) {
1555 drain = 1; 1578 drain = 1;
@@ -1568,6 +1591,11 @@ repeat:
1568 yield(); 1591 yield();
1569 /* drain pcp pages, this is synchronous. */ 1592 /* drain pcp pages, this is synchronous. */
1570 drain_all_pages(); 1593 drain_all_pages();
1594 /*
1595 * dissolve free hugepages in the memory block before doing offlining
1596 * actually in order to make hugetlbfs's object counting consistent.
1597 */
1598 dissolve_free_huge_pages(start_pfn, end_pfn);
1571 /* check again */ 1599 /* check again */
1572 offlined_pages = check_pages_isolated(start_pfn, end_pfn); 1600 offlined_pages = check_pages_isolated(start_pfn, end_pfn);
1573 if (offlined_pages < 0) { 1601 if (offlined_pages < 0) {