diff options
Diffstat (limited to 'drivers/base/memory.c')
-rw-r--r-- | drivers/base/memory.c | 31 |
1 files changed, 26 insertions, 5 deletions
diff --git a/drivers/base/memory.c b/drivers/base/memory.c index ed5de58c340f..9e60dbe9fd94 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c | |||
@@ -572,19 +572,36 @@ static int init_memory_block(struct memory_block **memory, | |||
572 | } | 572 | } |
573 | 573 | ||
574 | static int add_memory_section(int nid, struct mem_section *section, | 574 | static int add_memory_section(int nid, struct mem_section *section, |
575 | struct memory_block **mem_p, | ||
575 | unsigned long state, enum mem_add_context context) | 576 | unsigned long state, enum mem_add_context context) |
576 | { | 577 | { |
577 | struct memory_block *mem; | 578 | struct memory_block *mem = NULL; |
579 | int scn_nr = __section_nr(section); | ||
578 | int ret = 0; | 580 | int ret = 0; |
579 | 581 | ||
580 | mutex_lock(&mem_sysfs_mutex); | 582 | mutex_lock(&mem_sysfs_mutex); |
581 | 583 | ||
582 | mem = find_memory_block(section); | 584 | if (context == BOOT) { |
585 | /* same memory block ? */ | ||
586 | if (mem_p && *mem_p) | ||
587 | if (scn_nr >= (*mem_p)->start_section_nr && | ||
588 | scn_nr <= (*mem_p)->end_section_nr) { | ||
589 | mem = *mem_p; | ||
590 | kobject_get(&mem->dev.kobj); | ||
591 | } | ||
592 | } else | ||
593 | mem = find_memory_block(section); | ||
594 | |||
583 | if (mem) { | 595 | if (mem) { |
584 | mem->section_count++; | 596 | mem->section_count++; |
585 | kobject_put(&mem->dev.kobj); | 597 | kobject_put(&mem->dev.kobj); |
586 | } else | 598 | } else { |
587 | ret = init_memory_block(&mem, section, state); | 599 | ret = init_memory_block(&mem, section, state); |
600 | /* store memory_block pointer for next loop */ | ||
601 | if (!ret && context == BOOT) | ||
602 | if (mem_p) | ||
603 | *mem_p = mem; | ||
604 | } | ||
588 | 605 | ||
589 | if (!ret) { | 606 | if (!ret) { |
590 | if (context == HOTPLUG && | 607 | if (context == HOTPLUG && |
@@ -627,7 +644,7 @@ int remove_memory_block(unsigned long node_id, struct mem_section *section, | |||
627 | */ | 644 | */ |
628 | int register_new_memory(int nid, struct mem_section *section) | 645 | int register_new_memory(int nid, struct mem_section *section) |
629 | { | 646 | { |
630 | return add_memory_section(nid, section, MEM_OFFLINE, HOTPLUG); | 647 | return add_memory_section(nid, section, NULL, MEM_OFFLINE, HOTPLUG); |
631 | } | 648 | } |
632 | 649 | ||
633 | int unregister_memory_section(struct mem_section *section) | 650 | int unregister_memory_section(struct mem_section *section) |
@@ -647,6 +664,7 @@ int __init memory_dev_init(void) | |||
647 | int ret; | 664 | int ret; |
648 | int err; | 665 | int err; |
649 | unsigned long block_sz; | 666 | unsigned long block_sz; |
667 | struct memory_block *mem = NULL; | ||
650 | 668 | ||
651 | ret = subsys_system_register(&memory_subsys, NULL); | 669 | ret = subsys_system_register(&memory_subsys, NULL); |
652 | if (ret) | 670 | if (ret) |
@@ -662,7 +680,10 @@ int __init memory_dev_init(void) | |||
662 | for (i = 0; i < NR_MEM_SECTIONS; i++) { | 680 | for (i = 0; i < NR_MEM_SECTIONS; i++) { |
663 | if (!present_section_nr(i)) | 681 | if (!present_section_nr(i)) |
664 | continue; | 682 | continue; |
665 | err = add_memory_section(0, __nr_to_section(i), MEM_ONLINE, | 683 | /* don't need to reuse memory_block if only one per block */ |
684 | err = add_memory_section(0, __nr_to_section(i), | ||
685 | (sections_per_block == 1) ? NULL : &mem, | ||
686 | MEM_ONLINE, | ||
666 | BOOT); | 687 | BOOT); |
667 | if (!ret) | 688 | if (!ret) |
668 | ret = err; | 689 | ret = err; |