diff options
-rw-r--r-- | mm/memory_hotplug.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index 302291429953..6a82972aeae5 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c | |||
@@ -1387,10 +1387,13 @@ int remove_memory(u64 start, u64 size) | |||
1387 | unsigned long start_pfn, end_pfn; | 1387 | unsigned long start_pfn, end_pfn; |
1388 | unsigned long pfn, section_nr; | 1388 | unsigned long pfn, section_nr; |
1389 | int ret; | 1389 | int ret; |
1390 | int return_on_error = 0; | ||
1391 | int retry = 0; | ||
1390 | 1392 | ||
1391 | start_pfn = PFN_DOWN(start); | 1393 | start_pfn = PFN_DOWN(start); |
1392 | end_pfn = start_pfn + PFN_DOWN(size); | 1394 | end_pfn = start_pfn + PFN_DOWN(size); |
1393 | 1395 | ||
1396 | repeat: | ||
1394 | for (pfn = start_pfn; pfn < end_pfn; pfn += PAGES_PER_SECTION) { | 1397 | for (pfn = start_pfn; pfn < end_pfn; pfn += PAGES_PER_SECTION) { |
1395 | section_nr = pfn_to_section_nr(pfn); | 1398 | section_nr = pfn_to_section_nr(pfn); |
1396 | if (!present_section_nr(section_nr)) | 1399 | if (!present_section_nr(section_nr)) |
@@ -1409,14 +1412,23 @@ int remove_memory(u64 start, u64 size) | |||
1409 | 1412 | ||
1410 | ret = offline_memory_block(mem); | 1413 | ret = offline_memory_block(mem); |
1411 | if (ret) { | 1414 | if (ret) { |
1412 | kobject_put(&mem->dev.kobj); | 1415 | if (return_on_error) { |
1413 | return ret; | 1416 | kobject_put(&mem->dev.kobj); |
1417 | return ret; | ||
1418 | } else { | ||
1419 | retry = 1; | ||
1420 | } | ||
1414 | } | 1421 | } |
1415 | } | 1422 | } |
1416 | 1423 | ||
1417 | if (mem) | 1424 | if (mem) |
1418 | kobject_put(&mem->dev.kobj); | 1425 | kobject_put(&mem->dev.kobj); |
1419 | 1426 | ||
1427 | if (retry) { | ||
1428 | return_on_error = 1; | ||
1429 | goto repeat; | ||
1430 | } | ||
1431 | |||
1420 | return 0; | 1432 | return 0; |
1421 | } | 1433 | } |
1422 | #else | 1434 | #else |