aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base/node.c')
-rw-r--r--drivers/base/node.c52
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/*
468int 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 */
476void 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
503int link_mem_sections(int nid, unsigned long start_pfn, unsigned long end_pfn) 487int link_mem_sections(int nid, unsigned long start_pfn, unsigned long end_pfn)