diff options
Diffstat (limited to 'drivers/base')
| -rw-r--r-- | drivers/base/cpu.c | 21 | ||||
| -rw-r--r-- | drivers/base/memory.c | 31 | ||||
| -rw-r--r-- | drivers/base/node.c | 8 |
3 files changed, 55 insertions, 5 deletions
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index db87e78d7459..4dabf5077c48 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c | |||
| @@ -208,6 +208,25 @@ static ssize_t print_cpus_offline(struct device *dev, | |||
| 208 | } | 208 | } |
| 209 | static DEVICE_ATTR(offline, 0444, print_cpus_offline, NULL); | 209 | static DEVICE_ATTR(offline, 0444, print_cpus_offline, NULL); |
| 210 | 210 | ||
| 211 | static void cpu_device_release(struct device *dev) | ||
| 212 | { | ||
| 213 | /* | ||
| 214 | * This is an empty function to prevent the driver core from spitting a | ||
| 215 | * warning at us. Yes, I know this is directly opposite of what the | ||
| 216 | * documentation for the driver core and kobjects say, and the author | ||
| 217 | * of this code has already been publically ridiculed for doing | ||
| 218 | * something as foolish as this. However, at this point in time, it is | ||
| 219 | * the only way to handle the issue of statically allocated cpu | ||
| 220 | * devices. The different architectures will have their cpu device | ||
| 221 | * code reworked to properly handle this in the near future, so this | ||
| 222 | * function will then be changed to correctly free up the memory held | ||
| 223 | * by the cpu device. | ||
| 224 | * | ||
| 225 | * Never copy this way of doing things, or you too will be made fun of | ||
| 226 | * on the linux-kerenl list, you have been warned. | ||
| 227 | */ | ||
| 228 | } | ||
| 229 | |||
| 211 | /* | 230 | /* |
| 212 | * register_cpu - Setup a sysfs device for a CPU. | 231 | * register_cpu - Setup a sysfs device for a CPU. |
| 213 | * @cpu - cpu->hotpluggable field set to 1 will generate a control file in | 232 | * @cpu - cpu->hotpluggable field set to 1 will generate a control file in |
| @@ -221,8 +240,10 @@ int __cpuinit register_cpu(struct cpu *cpu, int num) | |||
| 221 | int error; | 240 | int error; |
| 222 | 241 | ||
| 223 | cpu->node_id = cpu_to_node(num); | 242 | cpu->node_id = cpu_to_node(num); |
| 243 | memset(&cpu->dev, 0x00, sizeof(struct device)); | ||
| 224 | cpu->dev.id = num; | 244 | cpu->dev.id = num; |
| 225 | cpu->dev.bus = &cpu_subsys; | 245 | cpu->dev.bus = &cpu_subsys; |
| 246 | cpu->dev.release = cpu_device_release; | ||
| 226 | error = device_register(&cpu->dev); | 247 | error = device_register(&cpu->dev); |
| 227 | if (!error && cpu->hotpluggable) | 248 | if (!error && cpu->hotpluggable) |
| 228 | register_cpu_control(cpu); | 249 | register_cpu_control(cpu); |
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; |
diff --git a/drivers/base/node.c b/drivers/base/node.c index 44f427a66117..90aa2a11a933 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c | |||
| @@ -456,7 +456,15 @@ static int link_mem_sections(int nid) | |||
| 456 | if (!present_section_nr(section_nr)) | 456 | if (!present_section_nr(section_nr)) |
| 457 | continue; | 457 | continue; |
| 458 | mem_sect = __nr_to_section(section_nr); | 458 | mem_sect = __nr_to_section(section_nr); |
| 459 | |||
| 460 | /* same memblock ? */ | ||
| 461 | if (mem_blk) | ||
| 462 | if ((section_nr >= mem_blk->start_section_nr) && | ||
| 463 | (section_nr <= mem_blk->end_section_nr)) | ||
| 464 | continue; | ||
| 465 | |||
| 459 | mem_blk = find_memory_block_hinted(mem_sect, mem_blk); | 466 | mem_blk = find_memory_block_hinted(mem_sect, mem_blk); |
| 467 | |||
| 460 | ret = register_mem_sect_under_node(mem_blk, nid); | 468 | ret = register_mem_sect_under_node(mem_blk, nid); |
| 461 | if (!err) | 469 | if (!err) |
| 462 | err = ret; | 470 | err = ret; |
