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