diff options
author | David Vrabel <david.vrabel@citrix.com> | 2015-06-25 16:35:49 +0100 |
---|---|---|
committer | David Vrabel <david.vrabel@citrix.com> | 2015-10-23 14:19:58 +0100 |
commit | 62cedb9f135794ec26a93ae29e5f0231ab263c84 (patch) | |
tree | 391e9f85e552feee52c6527daf7c95548572b6d0 /mm/memory_hotplug.c | |
parent | 7379047d5585187d1288486d4627873170d0005a (diff) | |
download | linux-62cedb9f135794ec26a93ae29e5f0231ab263c84.tar.gz linux-62cedb9f135794ec26a93ae29e5f0231ab263c84.tar.bz2 linux-62cedb9f135794ec26a93ae29e5f0231ab263c84.zip |
mm: memory hotplug with an existing resource
Add add_memory_resource() to add memory using an existing "System RAM"
resource. This is useful if the memory region is being located by
finding a free resource slot with allocate_resource().
Xen guests will make use of this in their balloon driver to hotplug
arbitrary amounts of memory in response to toolstack requests.
Signed-off-by: David Vrabel <david.vrabel@citrix.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Tang Chen <tangchen@cn.fujitsu.com>
Diffstat (limited to 'mm/memory_hotplug.c')
-rw-r--r-- | mm/memory_hotplug.c | 29 |
1 files changed, 21 insertions, 8 deletions
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index aa992e2df58a..0780d118d26e 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c @@ -1232,23 +1232,21 @@ int zone_for_memory(int nid, u64 start, u64 size, int zone_default, } /* we are OK calling __meminit stuff here - we have CONFIG_MEMORY_HOTPLUG */ -int __ref add_memory(int nid, u64 start, u64 size) +int __ref add_memory_resource(int nid, struct resource *res) { + u64 start, size; pg_data_t *pgdat = NULL; bool new_pgdat; bool new_node; - struct resource *res; int ret; + start = res->start; + size = resource_size(res); + ret = check_hotplug_memory_range(start, size); if (ret) return ret; - res = register_memory_resource(start, size); - ret = -EEXIST; - if (!res) - return ret; - { /* Stupid hack to suppress address-never-null warning */ void *p = NODE_DATA(nid); new_pgdat = !p; @@ -1300,13 +1298,28 @@ error: /* rollback pgdat allocation and others */ if (new_pgdat) rollback_node_hotadd(nid, pgdat); - release_memory_resource(res); memblock_remove(start, size); out: mem_hotplug_done(); return ret; } +EXPORT_SYMBOL_GPL(add_memory_resource); + +int __ref add_memory(int nid, u64 start, u64 size) +{ + struct resource *res; + int ret; + + res = register_memory_resource(start, size); + if (!res) + return -EEXIST; + + ret = add_memory_resource(nid, res); + if (ret < 0) + release_memory_resource(res); + return ret; +} EXPORT_SYMBOL_GPL(add_memory); #ifdef CONFIG_MEMORY_HOTREMOVE |