aboutsummaryrefslogtreecommitdiffstats
path: root/mm/memory_hotplug.c
diff options
context:
space:
mode:
authorWen Congyang <wency@cn.fujitsu.com>2013-02-22 19:32:50 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-02-23 20:50:11 -0500
commit993c1aad8f316dbafae6a0ec660ec846676838d6 (patch)
tree3c08ed271bbccf6b822190e0c3ad4825ffe10f7a /mm/memory_hotplug.c
parenta864b9d06c71456470b3544fe4cc07bcdd29828d (diff)
memory-hotplug: try to offline the memory twice to avoid dependence
memory can't be offlined when CONFIG_MEMCG is selected. For example: there is a memory device on node 1. The address range is [1G, 1.5G). You will find 4 new directories memory8, memory9, memory10, and memory11 under the directory /sys/devices/system/memory/. If CONFIG_MEMCG is selected, we will allocate memory to store page cgroup when we online pages. When we online memory8, the memory stored page cgroup is not provided by this memory device. But when we online memory9, the memory stored page cgroup may be provided by memory8. So we can't offline memory8 now. We should offline the memory in the reversed order. When the memory device is hotremoved, we will auto offline memory provided by this memory device. But we don't know which memory is onlined first, so offlining memory may fail. In such case, iterate twice to offline the memory. 1st iterate: offline every non primary memory block. 2nd iterate: offline primary (i.e. first added) memory block. This idea is suggested by KOSAKI Motohiro. Signed-off-by: Wen Congyang <wency@cn.fujitsu.com> Signed-off-by: Tang Chen <tangchen@cn.fujitsu.com> Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> Cc: Jiang Liu <jiang.liu@huawei.com> Cc: Jianguo Wu <wujianguo@huawei.com> Cc: Kamezawa Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Cc: Lai Jiangshan <laijs@cn.fujitsu.com> Cc: Wu Jianguo <wujianguo@huawei.com> Cc: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: "H. Peter Anvin" <hpa@zytor.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/memory_hotplug.c')
-rw-r--r--mm/memory_hotplug.c16
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
1396repeat:
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