[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>

authored by KAMEZAWA Hiroyuki and committed by Linus Torvalds ebd15302 5d2870fa

+22 -7
+22 -7
mm/memory_hotplug.c
··· 52 52 int nr_pages = PAGES_PER_SECTION; 53 53 int ret; 54 54 55 + if (pfn_valid(phys_start_pfn)) 56 + return -EEXIST; 57 + 55 58 ret = sparse_add_one_section(zone, phys_start_pfn, nr_pages); 56 59 57 60 if (ret < 0) ··· 223 220 } 224 221 225 222 /* add this memory to iomem resource */ 226 - static int register_memory_resource(u64 start, u64 size) 223 + static struct resource *register_memory_resource(u64 start, u64 size) 227 224 { 228 225 struct resource *res; 229 - int ret = 0; 230 226 res = kzalloc(sizeof(struct resource), GFP_KERNEL); 231 227 BUG_ON(!res); 232 228 ··· 237 235 printk("System RAM resource %llx - %llx cannot be added\n", 238 236 (unsigned long long)res->start, (unsigned long long)res->end); 239 237 kfree(res); 240 - ret = -EEXIST; 238 + res = NULL; 241 239 } 242 - return ret; 240 + return res; 241 + } 242 + 243 + static void release_memory_resource(struct resource *res) 244 + { 245 + if (!res) 246 + return; 247 + release_resource(res); 248 + kfree(res); 249 + return; 243 250 } 244 251 245 252 ··· 257 246 { 258 247 pg_data_t *pgdat = NULL; 259 248 int new_pgdat = 0; 249 + struct resource *res; 260 250 int ret; 251 + 252 + res = register_memory_resource(start, size); 253 + if (!res) 254 + return -EEXIST; 261 255 262 256 if (!node_online(nid)) { 263 257 pgdat = hotadd_new_pgdat(nid, start); ··· 293 277 BUG_ON(ret); 294 278 } 295 279 296 - /* register this memory as resource */ 297 - ret = register_memory_resource(start, size); 298 - 299 280 return ret; 300 281 error: 301 282 /* rollback pgdat allocation and others */ 302 283 if (new_pgdat) 303 284 rollback_node_hotadd(nid, pgdat); 285 + if (res) 286 + release_memory_resource(res); 304 287 305 288 return ret; 306 289 }