aboutsummaryrefslogtreecommitdiffstats
path: root/mm/memory_hotplug.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/memory_hotplug.c')
-rw-r--r--mm/memory_hotplug.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index 85eb4d342ac5..089cc97aed3c 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -389,6 +389,11 @@ int online_pages(unsigned long pfn, unsigned long nr_pages)
389 int nid; 389 int nid;
390 int ret; 390 int ret;
391 struct memory_notify arg; 391 struct memory_notify arg;
392 /*
393 * mutex to protect zone->pageset when it's still shared
394 * in onlined_pages()
395 */
396 static DEFINE_MUTEX(zone_pageset_mutex);
392 397
393 arg.start_pfn = pfn; 398 arg.start_pfn = pfn;
394 arg.nr_pages = nr_pages; 399 arg.nr_pages = nr_pages;
@@ -415,12 +420,14 @@ int online_pages(unsigned long pfn, unsigned long nr_pages)
415 * This means the page allocator ignores this zone. 420 * This means the page allocator ignores this zone.
416 * So, zonelist must be updated after online. 421 * So, zonelist must be updated after online.
417 */ 422 */
423 mutex_lock(&zone_pageset_mutex);
418 if (!populated_zone(zone)) 424 if (!populated_zone(zone))
419 need_zonelists_rebuild = 1; 425 need_zonelists_rebuild = 1;
420 426
421 ret = walk_system_ram_range(pfn, nr_pages, &onlined_pages, 427 ret = walk_system_ram_range(pfn, nr_pages, &onlined_pages,
422 online_pages_range); 428 online_pages_range);
423 if (ret) { 429 if (ret) {
430 mutex_unlock(&zone_pageset_mutex);
424 printk(KERN_DEBUG "online_pages %lx at %lx failed\n", 431 printk(KERN_DEBUG "online_pages %lx at %lx failed\n",
425 nr_pages, pfn); 432 nr_pages, pfn);
426 memory_notify(MEM_CANCEL_ONLINE, &arg); 433 memory_notify(MEM_CANCEL_ONLINE, &arg);
@@ -429,8 +436,12 @@ int online_pages(unsigned long pfn, unsigned long nr_pages)
429 436
430 zone->present_pages += onlined_pages; 437 zone->present_pages += onlined_pages;
431 zone->zone_pgdat->node_present_pages += onlined_pages; 438 zone->zone_pgdat->node_present_pages += onlined_pages;
439 if (need_zonelists_rebuild)
440 build_all_zonelists(zone);
441 else
442 zone_pcp_update(zone);
432 443
433 zone_pcp_update(zone); 444 mutex_unlock(&zone_pageset_mutex);
434 setup_per_zone_wmarks(); 445 setup_per_zone_wmarks();
435 calculate_zone_inactive_ratio(zone); 446 calculate_zone_inactive_ratio(zone);
436 if (onlined_pages) { 447 if (onlined_pages) {
@@ -438,10 +449,7 @@ int online_pages(unsigned long pfn, unsigned long nr_pages)
438 node_set_state(zone_to_nid(zone), N_HIGH_MEMORY); 449 node_set_state(zone_to_nid(zone), N_HIGH_MEMORY);
439 } 450 }
440 451
441 if (need_zonelists_rebuild) 452 vm_total_pages = nr_free_pagecache_pages();
442 build_all_zonelists();
443 else
444 vm_total_pages = nr_free_pagecache_pages();
445 453
446 writeback_set_ratelimit(); 454 writeback_set_ratelimit();
447 455