diff options
Diffstat (limited to 'drivers/base/node.c')
-rw-r--r-- | drivers/base/node.c | 52 |
1 files changed, 18 insertions, 34 deletions
diff --git a/drivers/base/node.c b/drivers/base/node.c index ce27be2d001d..9fe33d3e2d3b 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c | |||
@@ -420,8 +420,6 @@ int register_mem_sect_under_node(struct memory_block *mem_blk, void *arg) | |||
420 | int ret, nid = *(int *)arg; | 420 | int ret, nid = *(int *)arg; |
421 | unsigned long pfn, sect_start_pfn, sect_end_pfn; | 421 | unsigned long pfn, sect_start_pfn, sect_end_pfn; |
422 | 422 | ||
423 | mem_blk->nid = nid; | ||
424 | |||
425 | sect_start_pfn = section_nr_to_pfn(mem_blk->start_section_nr); | 423 | sect_start_pfn = section_nr_to_pfn(mem_blk->start_section_nr); |
426 | sect_end_pfn = section_nr_to_pfn(mem_blk->end_section_nr); | 424 | sect_end_pfn = section_nr_to_pfn(mem_blk->end_section_nr); |
427 | sect_end_pfn += PAGES_PER_SECTION - 1; | 425 | sect_end_pfn += PAGES_PER_SECTION - 1; |
@@ -450,6 +448,13 @@ int register_mem_sect_under_node(struct memory_block *mem_blk, void *arg) | |||
450 | if (page_nid != nid) | 448 | if (page_nid != nid) |
451 | continue; | 449 | continue; |
452 | } | 450 | } |
451 | |||
452 | /* | ||
453 | * If this memory block spans multiple nodes, we only indicate | ||
454 | * the last processed node. | ||
455 | */ | ||
456 | mem_blk->nid = nid; | ||
457 | |||
453 | ret = sysfs_create_link_nowarn(&node_devices[nid]->dev.kobj, | 458 | ret = sysfs_create_link_nowarn(&node_devices[nid]->dev.kobj, |
454 | &mem_blk->dev.kobj, | 459 | &mem_blk->dev.kobj, |
455 | kobject_name(&mem_blk->dev.kobj)); | 460 | kobject_name(&mem_blk->dev.kobj)); |
@@ -464,40 +469,19 @@ int register_mem_sect_under_node(struct memory_block *mem_blk, void *arg) | |||
464 | return 0; | 469 | return 0; |
465 | } | 470 | } |
466 | 471 | ||
467 | /* unregister memory section under all nodes that it spans */ | 472 | /* |
468 | int unregister_mem_sect_under_nodes(struct memory_block *mem_blk, | 473 | * Unregister a memory block device under the node it spans. Memory blocks |
469 | unsigned long phys_index) | 474 | * with multiple nodes cannot be offlined and therefore also never be removed. |
475 | */ | ||
476 | void unregister_memory_block_under_nodes(struct memory_block *mem_blk) | ||
470 | { | 477 | { |
471 | NODEMASK_ALLOC(nodemask_t, unlinked_nodes, GFP_KERNEL); | 478 | if (mem_blk->nid == NUMA_NO_NODE) |
472 | unsigned long pfn, sect_start_pfn, sect_end_pfn; | 479 | return; |
473 | |||
474 | if (!mem_blk) { | ||
475 | NODEMASK_FREE(unlinked_nodes); | ||
476 | return -EFAULT; | ||
477 | } | ||
478 | if (!unlinked_nodes) | ||
479 | return -ENOMEM; | ||
480 | nodes_clear(*unlinked_nodes); | ||
481 | |||
482 | sect_start_pfn = section_nr_to_pfn(phys_index); | ||
483 | sect_end_pfn = sect_start_pfn + PAGES_PER_SECTION - 1; | ||
484 | for (pfn = sect_start_pfn; pfn <= sect_end_pfn; pfn++) { | ||
485 | int nid; | ||
486 | 480 | ||
487 | nid = get_nid_for_pfn(pfn); | 481 | sysfs_remove_link(&node_devices[mem_blk->nid]->dev.kobj, |
488 | if (nid < 0) | 482 | kobject_name(&mem_blk->dev.kobj)); |
489 | continue; | 483 | sysfs_remove_link(&mem_blk->dev.kobj, |
490 | if (!node_online(nid)) | 484 | kobject_name(&node_devices[mem_blk->nid]->dev.kobj)); |
491 | continue; | ||
492 | if (node_test_and_set(nid, *unlinked_nodes)) | ||
493 | continue; | ||
494 | sysfs_remove_link(&node_devices[nid]->dev.kobj, | ||
495 | kobject_name(&mem_blk->dev.kobj)); | ||
496 | sysfs_remove_link(&mem_blk->dev.kobj, | ||
497 | kobject_name(&node_devices[nid]->dev.kobj)); | ||
498 | } | ||
499 | NODEMASK_FREE(unlinked_nodes); | ||
500 | return 0; | ||
501 | } | 485 | } |
502 | 486 | ||
503 | int link_mem_sections(int nid, unsigned long start_pfn, unsigned long end_pfn) | 487 | int link_mem_sections(int nid, unsigned long start_pfn, unsigned long end_pfn) |