diff options
| -rw-r--r-- | mm/memory_hotplug.c | 29 |
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 */ |
| 223 | static int register_memory_resource(u64 start, u64 size) | 226 | static 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 | |||
| 245 | static 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; |
| 284 | error: | 297 | error: |
| 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 | } |
