aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mm/memory_hotplug.c29
1 files changed, 22 insertions, 7 deletions
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index 26f1840879d6..c37319542b70 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -52,6 +52,9 @@ static int __add_section(struct zone *zone, unsigned long phys_start_pfn)
52 int nr_pages = PAGES_PER_SECTION; 52 int nr_pages = PAGES_PER_SECTION;
53 int ret; 53 int ret;
54 54
55 if (pfn_valid(phys_start_pfn))
56 return -EEXIST;
57
55 ret = sparse_add_one_section(zone, phys_start_pfn, nr_pages); 58 ret = sparse_add_one_section(zone, phys_start_pfn, nr_pages);
56 59
57 if (ret < 0) 60 if (ret < 0)
@@ -220,10 +223,9 @@ static void rollback_node_hotadd(int nid, pg_data_t *pgdat)
220} 223}
221 224
222/* add this memory to iomem resource */ 225/* add this memory to iomem resource */
223static int register_memory_resource(u64 start, u64 size) 226static struct resource *register_memory_resource(u64 start, u64 size)
224{ 227{
225 struct resource *res; 228 struct resource *res;
226 int ret = 0;
227 res = kzalloc(sizeof(struct resource), GFP_KERNEL); 229 res = kzalloc(sizeof(struct resource), GFP_KERNEL);
228 BUG_ON(!res); 230 BUG_ON(!res);
229 231
@@ -235,9 +237,18 @@ static int register_memory_resource(u64 start, u64 size)
235 printk("System RAM resource %llx - %llx cannot be added\n", 237 printk("System RAM resource %llx - %llx cannot be added\n",
236 (unsigned long long)res->start, (unsigned long long)res->end); 238 (unsigned long long)res->start, (unsigned long long)res->end);
237 kfree(res); 239 kfree(res);
238 ret = -EEXIST; 240 res = NULL;
239 } 241 }
240 return ret; 242 return res;
243}
244
245static void release_memory_resource(struct resource *res)
246{
247 if (!res)
248 return;
249 release_resource(res);
250 kfree(res);
251 return;
241} 252}
242 253
243 254
@@ -246,8 +257,13 @@ int add_memory(int nid, u64 start, u64 size)
246{ 257{
247 pg_data_t *pgdat = NULL; 258 pg_data_t *pgdat = NULL;
248 int new_pgdat = 0; 259 int new_pgdat = 0;
260 struct resource *res;
249 int ret; 261 int ret;
250 262
263 res = register_memory_resource(start, size);
264 if (!res)
265 return -EEXIST;
266
251 if (!node_online(nid)) { 267 if (!node_online(nid)) {
252 pgdat = hotadd_new_pgdat(nid, start); 268 pgdat = hotadd_new_pgdat(nid, start);
253 if (!pgdat) 269 if (!pgdat)
@@ -277,14 +293,13 @@ int add_memory(int nid, u64 start, u64 size)
277 BUG_ON(ret); 293 BUG_ON(ret);
278 } 294 }
279 295
280 /* register this memory as resource */
281 ret = register_memory_resource(start, size);
282
283 return ret; 296 return ret;
284error: 297error:
285 /* rollback pgdat allocation and others */ 298 /* rollback pgdat allocation and others */
286 if (new_pgdat) 299 if (new_pgdat)
287 rollback_node_hotadd(nid, pgdat); 300 rollback_node_hotadd(nid, pgdat);
301 if (res)
302 release_memory_resource(res);
288 303
289 return ret; 304 return ret;
290} 305}