@@ -761,14 +761,36 @@ static int __ref get_nid_for_pfn(unsigned long pfn)
761761 return pfn_to_nid (pfn );
762762}
763763
764+ static int do_register_memory_block_under_node (int nid ,
765+ struct memory_block * mem_blk )
766+ {
767+ int ret ;
768+
769+ /*
770+ * If this memory block spans multiple nodes, we only indicate
771+ * the last processed node.
772+ */
773+ mem_blk -> nid = nid ;
774+
775+ ret = sysfs_create_link_nowarn (& node_devices [nid ]-> dev .kobj ,
776+ & mem_blk -> dev .kobj ,
777+ kobject_name (& mem_blk -> dev .kobj ));
778+ if (ret )
779+ return ret ;
780+
781+ return sysfs_create_link_nowarn (& mem_blk -> dev .kobj ,
782+ & node_devices [nid ]-> dev .kobj ,
783+ kobject_name (& node_devices [nid ]-> dev .kobj ));
784+ }
785+
764786/* register memory section under specified node if it spans that node */
765- static int register_mem_sect_under_node (struct memory_block * mem_blk ,
766- void * arg )
787+ static int register_mem_block_under_node_early (struct memory_block * mem_blk ,
788+ void * arg )
767789{
768790 unsigned long memory_block_pfns = memory_block_size_bytes () / PAGE_SIZE ;
769791 unsigned long start_pfn = section_nr_to_pfn (mem_blk -> start_section_nr );
770792 unsigned long end_pfn = start_pfn + memory_block_pfns - 1 ;
771- int ret , nid = * (int * )arg ;
793+ int nid = * (int * )arg ;
772794 unsigned long pfn ;
773795
774796 for (pfn = start_pfn ; pfn <= end_pfn ; pfn ++ ) {
@@ -785,38 +807,33 @@ static int register_mem_sect_under_node(struct memory_block *mem_blk,
785807 }
786808
787809 /*
788- * We need to check if page belongs to nid only for the boot
789- * case, during hotplug we know that all pages in the memory
790- * block belong to the same node.
791- */
792- if (system_state == SYSTEM_BOOTING ) {
793- page_nid = get_nid_for_pfn (pfn );
794- if (page_nid < 0 )
795- continue ;
796- if (page_nid != nid )
797- continue ;
798- }
799-
800- /*
801- * If this memory block spans multiple nodes, we only indicate
802- * the last processed node.
810+ * We need to check if page belongs to nid only at the boot
811+ * case because node's ranges can be interleaved.
803812 */
804- mem_blk -> nid = nid ;
805-
806- ret = sysfs_create_link_nowarn (& node_devices [nid ]-> dev .kobj ,
807- & mem_blk -> dev .kobj ,
808- kobject_name (& mem_blk -> dev .kobj ));
809- if (ret )
810- return ret ;
813+ page_nid = get_nid_for_pfn (pfn );
814+ if (page_nid < 0 )
815+ continue ;
816+ if (page_nid != nid )
817+ continue ;
811818
812- return sysfs_create_link_nowarn (& mem_blk -> dev .kobj ,
813- & node_devices [nid ]-> dev .kobj ,
814- kobject_name (& node_devices [nid ]-> dev .kobj ));
819+ return do_register_memory_block_under_node (nid , mem_blk );
815820 }
816821 /* mem section does not span the specified node */
817822 return 0 ;
818823}
819824
825+ /*
826+ * During hotplug we know that all pages in the memory block belong to the same
827+ * node.
828+ */
829+ static int register_mem_block_under_node_hotplug (struct memory_block * mem_blk ,
830+ void * arg )
831+ {
832+ int nid = * (int * )arg ;
833+
834+ return do_register_memory_block_under_node (nid , mem_blk );
835+ }
836+
820837/*
821838 * Unregister a memory block device under the node it spans. Memory blocks
822839 * with multiple nodes cannot be offlined and therefore also never be removed.
@@ -832,11 +849,19 @@ void unregister_memory_block_under_nodes(struct memory_block *mem_blk)
832849 kobject_name (& node_devices [mem_blk -> nid ]-> dev .kobj ));
833850}
834851
835- int link_mem_sections (int nid , unsigned long start_pfn , unsigned long end_pfn )
852+ int link_mem_sections (int nid , unsigned long start_pfn , unsigned long end_pfn ,
853+ enum meminit_context context )
836854{
855+ walk_memory_blocks_func_t func ;
856+
857+ if (context == MEMINIT_HOTPLUG )
858+ func = register_mem_block_under_node_hotplug ;
859+ else
860+ func = register_mem_block_under_node_early ;
861+
837862 return walk_memory_blocks (PFN_PHYS (start_pfn ),
838863 PFN_PHYS (end_pfn - start_pfn ), (void * )& nid ,
839- register_mem_sect_under_node );
864+ func );
840865}
841866
842867#ifdef CONFIG_HUGETLBFS
0 commit comments