|
@@ -26,6 +26,7 @@
|
|
|
#include <linux/migrate.h>
|
|
|
#include <linux/page-isolation.h>
|
|
|
#include <linux/pfn.h>
|
|
|
+#include <linux/suspend.h>
|
|
|
|
|
|
#include <asm/tlbflush.h>
|
|
|
|
|
@@ -485,14 +486,18 @@ int __ref add_memory(int nid, u64 start, u64 size)
|
|
|
struct resource *res;
|
|
|
int ret;
|
|
|
|
|
|
+ lock_system_sleep();
|
|
|
+
|
|
|
res = register_memory_resource(start, size);
|
|
|
+ ret = -EEXIST;
|
|
|
if (!res)
|
|
|
- return -EEXIST;
|
|
|
+ goto out;
|
|
|
|
|
|
if (!node_online(nid)) {
|
|
|
pgdat = hotadd_new_pgdat(nid, start);
|
|
|
+ ret = -ENOMEM;
|
|
|
if (!pgdat)
|
|
|
- return -ENOMEM;
|
|
|
+ goto out;
|
|
|
new_pgdat = 1;
|
|
|
}
|
|
|
|
|
@@ -515,7 +520,8 @@ int __ref add_memory(int nid, u64 start, u64 size)
|
|
|
BUG_ON(ret);
|
|
|
}
|
|
|
|
|
|
- return ret;
|
|
|
+ goto out;
|
|
|
+
|
|
|
error:
|
|
|
/* rollback pgdat allocation and others */
|
|
|
if (new_pgdat)
|
|
@@ -523,6 +529,8 @@ error:
|
|
|
if (res)
|
|
|
release_memory_resource(res);
|
|
|
|
|
|
+out:
|
|
|
+ unlock_system_sleep();
|
|
|
return ret;
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(add_memory);
|
|
@@ -759,6 +767,8 @@ int offline_pages(unsigned long start_pfn,
|
|
|
if (!test_pages_in_a_zone(start_pfn, end_pfn))
|
|
|
return -EINVAL;
|
|
|
|
|
|
+ lock_system_sleep();
|
|
|
+
|
|
|
zone = page_zone(pfn_to_page(start_pfn));
|
|
|
node = zone_to_nid(zone);
|
|
|
nr_pages = end_pfn - start_pfn;
|
|
@@ -766,7 +776,7 @@ int offline_pages(unsigned long start_pfn,
|
|
|
/* set above range as isolated */
|
|
|
ret = start_isolate_page_range(start_pfn, end_pfn);
|
|
|
if (ret)
|
|
|
- return ret;
|
|
|
+ goto out;
|
|
|
|
|
|
arg.start_pfn = start_pfn;
|
|
|
arg.nr_pages = nr_pages;
|
|
@@ -844,6 +854,7 @@ repeat:
|
|
|
writeback_set_ratelimit();
|
|
|
|
|
|
memory_notify(MEM_OFFLINE, &arg);
|
|
|
+ unlock_system_sleep();
|
|
|
return 0;
|
|
|
|
|
|
failed_removal:
|
|
@@ -853,6 +864,8 @@ failed_removal:
|
|
|
/* pushback to free area */
|
|
|
undo_isolate_page_range(start_pfn, end_pfn);
|
|
|
|
|
|
+out:
|
|
|
+ unlock_system_sleep();
|
|
|
return ret;
|
|
|
}
|
|
|
|