@@ -758,14 +758,36 @@ static int __ref get_nid_for_pfn(unsigned long pfn)
758758 return pfn_to_nid (pfn );
759759}
760760
761+ static int do_register_memory_block_under_node (int nid ,
762+ struct memory_block * mem_blk )
763+ {
764+ int ret ;
765+
766+ /*
767+ * If this memory block spans multiple nodes, we only indicate
768+ * the last processed node.
769+ */
770+ mem_blk -> nid = nid ;
771+
772+ ret = sysfs_create_link_nowarn (& node_devices [nid ]-> dev .kobj ,
773+ & mem_blk -> dev .kobj ,
774+ kobject_name (& mem_blk -> dev .kobj ));
775+ if (ret )
776+ return ret ;
777+
778+ return sysfs_create_link_nowarn (& mem_blk -> dev .kobj ,
779+ & node_devices [nid ]-> dev .kobj ,
780+ kobject_name (& node_devices [nid ]-> dev .kobj ));
781+ }
782+
761783/* register memory section under specified node if it spans that node */
762- static int register_mem_sect_under_node (struct memory_block * mem_blk ,
763- void * arg )
784+ static int register_mem_block_under_node_early (struct memory_block * mem_blk ,
785+ void * arg )
764786{
765787 unsigned long memory_block_pfns = memory_block_size_bytes () / PAGE_SIZE ;
766788 unsigned long start_pfn = section_nr_to_pfn (mem_blk -> start_section_nr );
767789 unsigned long end_pfn = start_pfn + memory_block_pfns - 1 ;
768- int ret , nid = * (int * )arg ;
790+ int nid = * (int * )arg ;
769791 unsigned long pfn ;
770792
771793 for (pfn = start_pfn ; pfn <= end_pfn ; pfn ++ ) {
@@ -782,38 +804,33 @@ static int register_mem_sect_under_node(struct memory_block *mem_blk,
782804 }
783805
784806 /*
785- * We need to check if page belongs to nid only for the boot
786- * case, during hotplug we know that all pages in the memory
787- * block belong to the same node.
788- */
789- if (system_state == SYSTEM_BOOTING ) {
790- page_nid = get_nid_for_pfn (pfn );
791- if (page_nid < 0 )
792- continue ;
793- if (page_nid != nid )
794- continue ;
795- }
796-
797- /*
798- * If this memory block spans multiple nodes, we only indicate
799- * the last processed node.
807+ * We need to check if page belongs to nid only at the boot
808+ * case because node's ranges can be interleaved.
800809 */
801- mem_blk -> nid = nid ;
802-
803- ret = sysfs_create_link_nowarn (& node_devices [nid ]-> dev .kobj ,
804- & mem_blk -> dev .kobj ,
805- kobject_name (& mem_blk -> dev .kobj ));
806- if (ret )
807- return ret ;
810+ page_nid = get_nid_for_pfn (pfn );
811+ if (page_nid < 0 )
812+ continue ;
813+ if (page_nid != nid )
814+ continue ;
808815
809- return sysfs_create_link_nowarn (& mem_blk -> dev .kobj ,
810- & node_devices [nid ]-> dev .kobj ,
811- kobject_name (& node_devices [nid ]-> dev .kobj ));
816+ return do_register_memory_block_under_node (nid , mem_blk );
812817 }
813818 /* mem section does not span the specified node */
814819 return 0 ;
815820}
816821
822+ /*
823+ * During hotplug we know that all pages in the memory block belong to the same
824+ * node.
825+ */
826+ static int register_mem_block_under_node_hotplug (struct memory_block * mem_blk ,
827+ void * arg )
828+ {
829+ int nid = * (int * )arg ;
830+
831+ return do_register_memory_block_under_node (nid , mem_blk );
832+ }
833+
817834/*
818835 * Unregister a memory block device under the node it spans. Memory blocks
819836 * with multiple nodes cannot be offlined and therefore also never be removed.
@@ -829,11 +846,19 @@ void unregister_memory_block_under_nodes(struct memory_block *mem_blk)
829846 kobject_name (& node_devices [mem_blk -> nid ]-> dev .kobj ));
830847}
831848
832- int link_mem_sections (int nid , unsigned long start_pfn , unsigned long end_pfn )
849+ int link_mem_sections (int nid , unsigned long start_pfn , unsigned long end_pfn ,
850+ enum meminit_context context )
833851{
852+ walk_memory_blocks_func_t func ;
853+
854+ if (context == MEMINIT_HOTPLUG )
855+ func = register_mem_block_under_node_hotplug ;
856+ else
857+ func = register_mem_block_under_node_early ;
858+
834859 return walk_memory_blocks (PFN_PHYS (start_pfn ),
835860 PFN_PHYS (end_pfn - start_pfn ), (void * )& nid ,
836- register_mem_sect_under_node );
861+ func );
837862}
838863
839864#ifdef CONFIG_HUGETLBFS
0 commit comments