aboutsummaryrefslogtreecommitdiffstats
path: root/mm/memory_hotplug.c
diff options
context:
space:
mode:
authorKAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>2006-08-05 15:15:06 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-08-06 11:57:49 -0400
commitebd15302dc0ba1b8761600c20854f5371e7bae1e (patch)
treeaf9dc4b9c1c840fcdcd7d1a4053ba0e05eb1f028 /mm/memory_hotplug.c
parent5d2870faaa1fdcec795a6bf4dbbfc3e5d57fd7ab (diff)
[PATCH] memory hotadd fixes: enhance collision check
This patch is for collision check enhancement for memory hot add. It's better to do resouce collision check before doing memory hot add, which will touch memory management structures. And add_section() should check section exists or not before calling sparse_add_one_section(). (sparse_add_one_section() will do another check anyway. but checking in memory_hotplug.c will be easy to understand.) Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Cc: keith mannthey <kmannth@us.ibm.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'mm/memory_hotplug.c')
-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}