@@ -56,7 +56,7 @@ struct memory_target {
5656 unsigned int memory_pxm ;
5757 unsigned int processor_pxm ;
5858 struct resource memregions ;
59- struct node_hmem_attrs hmem_attrs ;
59+ struct node_hmem_attrs hmem_attrs [ 2 ] ;
6060 struct list_head caches ;
6161 struct node_cache_attrs cache_attrs ;
6262 bool registered ;
@@ -65,6 +65,7 @@ struct memory_target {
6565struct memory_initiator {
6666 struct list_head node ;
6767 unsigned int processor_pxm ;
68+ bool has_cpu ;
6869};
6970
7071struct memory_locality {
@@ -108,6 +109,7 @@ static __init void alloc_memory_initiator(unsigned int cpu_pxm)
108109 return ;
109110
110111 initiator -> processor_pxm = cpu_pxm ;
112+ initiator -> has_cpu = node_state (pxm_to_node (cpu_pxm ), N_CPU );
111113 list_add_tail (& initiator -> node , & initiators );
112114}
113115
@@ -215,28 +217,28 @@ static u32 hmat_normalize(u16 entry, u64 base, u8 type)
215217}
216218
217219static void hmat_update_target_access (struct memory_target * target ,
218- u8 type , u32 value )
220+ u8 type , u32 value , int access )
219221{
220222 switch (type ) {
221223 case ACPI_HMAT_ACCESS_LATENCY :
222- target -> hmem_attrs .read_latency = value ;
223- target -> hmem_attrs .write_latency = value ;
224+ target -> hmem_attrs [ access ] .read_latency = value ;
225+ target -> hmem_attrs [ access ] .write_latency = value ;
224226 break ;
225227 case ACPI_HMAT_READ_LATENCY :
226- target -> hmem_attrs .read_latency = value ;
228+ target -> hmem_attrs [ access ] .read_latency = value ;
227229 break ;
228230 case ACPI_HMAT_WRITE_LATENCY :
229- target -> hmem_attrs .write_latency = value ;
231+ target -> hmem_attrs [ access ] .write_latency = value ;
230232 break ;
231233 case ACPI_HMAT_ACCESS_BANDWIDTH :
232- target -> hmem_attrs .read_bandwidth = value ;
233- target -> hmem_attrs .write_bandwidth = value ;
234+ target -> hmem_attrs [ access ] .read_bandwidth = value ;
235+ target -> hmem_attrs [ access ] .write_bandwidth = value ;
234236 break ;
235237 case ACPI_HMAT_READ_BANDWIDTH :
236- target -> hmem_attrs .read_bandwidth = value ;
238+ target -> hmem_attrs [ access ] .read_bandwidth = value ;
237239 break ;
238240 case ACPI_HMAT_WRITE_BANDWIDTH :
239- target -> hmem_attrs .write_bandwidth = value ;
241+ target -> hmem_attrs [ access ] .write_bandwidth = value ;
240242 break ;
241243 default :
242244 break ;
@@ -329,8 +331,12 @@ static __init int hmat_parse_locality(union acpi_subtable_headers *header,
329331
330332 if (mem_hier == ACPI_HMAT_MEMORY ) {
331333 target = find_mem_target (targs [targ ]);
332- if (target && target -> processor_pxm == inits [init ])
333- hmat_update_target_access (target , type , value );
334+ if (target && target -> processor_pxm == inits [init ]) {
335+ hmat_update_target_access (target , type , value , 0 );
336+ /* If the node has a CPU, update access 1 */
337+ if (node_state (pxm_to_node (inits [init ]), N_CPU ))
338+ hmat_update_target_access (target , type , value , 1 );
339+ }
334340 }
335341 }
336342 }
@@ -424,7 +430,8 @@ static int __init hmat_parse_proximity_domain(union acpi_subtable_headers *heade
424430 pr_info ("HMAT: Memory Flags:%04x Processor Domain:%u Memory Domain:%u\n" ,
425431 p -> flags , p -> processor_PD , p -> memory_PD );
426432
427- if (p -> flags & ACPI_HMAT_MEMORY_PD_VALID && hmat_revision == 1 ) {
433+ if ((hmat_revision == 1 && p -> flags & ACPI_HMAT_MEMORY_PD_VALID ) ||
434+ hmat_revision > 1 ) {
428435 target = find_mem_target (p -> memory_PD );
429436 if (!target ) {
430437 pr_debug ("HMAT: Memory Domain missing from SRAT\n" );
@@ -566,6 +573,7 @@ static void hmat_register_target_initiators(struct memory_target *target)
566573 unsigned int mem_nid , cpu_nid ;
567574 struct memory_locality * loc = NULL ;
568575 u32 best = 0 ;
576+ bool access0done = false;
569577 int i ;
570578
571579 mem_nid = pxm_to_node (target -> memory_pxm );
@@ -577,7 +585,11 @@ static void hmat_register_target_initiators(struct memory_target *target)
577585 if (target -> processor_pxm != PXM_INVAL ) {
578586 cpu_nid = pxm_to_node (target -> processor_pxm );
579587 register_memory_node_under_compute_node (mem_nid , cpu_nid , 0 );
580- return ;
588+ access0done = true;
589+ if (node_state (cpu_nid , N_CPU )) {
590+ register_memory_node_under_compute_node (mem_nid , cpu_nid , 1 );
591+ return ;
592+ }
581593 }
582594
583595 if (list_empty (& localities ))
@@ -591,6 +603,41 @@ static void hmat_register_target_initiators(struct memory_target *target)
591603 */
592604 bitmap_zero (p_nodes , MAX_NUMNODES );
593605 list_sort (p_nodes , & initiators , initiator_cmp );
606+ if (!access0done ) {
607+ for (i = WRITE_LATENCY ; i <= READ_BANDWIDTH ; i ++ ) {
608+ loc = localities_types [i ];
609+ if (!loc )
610+ continue ;
611+
612+ best = 0 ;
613+ list_for_each_entry (initiator , & initiators , node ) {
614+ u32 value ;
615+
616+ if (!test_bit (initiator -> processor_pxm , p_nodes ))
617+ continue ;
618+
619+ value = hmat_initiator_perf (target , initiator ,
620+ loc -> hmat_loc );
621+ if (hmat_update_best (loc -> hmat_loc -> data_type , value , & best ))
622+ bitmap_clear (p_nodes , 0 , initiator -> processor_pxm );
623+ if (value != best )
624+ clear_bit (initiator -> processor_pxm , p_nodes );
625+ }
626+ if (best )
627+ hmat_update_target_access (target , loc -> hmat_loc -> data_type ,
628+ best , 0 );
629+ }
630+
631+ for_each_set_bit (i , p_nodes , MAX_NUMNODES ) {
632+ cpu_nid = pxm_to_node (i );
633+ register_memory_node_under_compute_node (mem_nid , cpu_nid , 0 );
634+ }
635+ }
636+
637+ /* Access 1 ignores Generic Initiators */
638+ bitmap_zero (p_nodes , MAX_NUMNODES );
639+ list_sort (p_nodes , & initiators , initiator_cmp );
640+ best = 0 ;
594641 for (i = WRITE_LATENCY ; i <= READ_BANDWIDTH ; i ++ ) {
595642 loc = localities_types [i ];
596643 if (!loc )
@@ -600,6 +647,10 @@ static void hmat_register_target_initiators(struct memory_target *target)
600647 list_for_each_entry (initiator , & initiators , node ) {
601648 u32 value ;
602649
650+ if (!initiator -> has_cpu ) {
651+ clear_bit (initiator -> processor_pxm , p_nodes );
652+ continue ;
653+ }
603654 if (!test_bit (initiator -> processor_pxm , p_nodes ))
604655 continue ;
605656
@@ -610,12 +661,11 @@ static void hmat_register_target_initiators(struct memory_target *target)
610661 clear_bit (initiator -> processor_pxm , p_nodes );
611662 }
612663 if (best )
613- hmat_update_target_access (target , loc -> hmat_loc -> data_type , best );
664+ hmat_update_target_access (target , loc -> hmat_loc -> data_type , best , 1 );
614665 }
615-
616666 for_each_set_bit (i , p_nodes , MAX_NUMNODES ) {
617667 cpu_nid = pxm_to_node (i );
618- register_memory_node_under_compute_node (mem_nid , cpu_nid , 0 );
668+ register_memory_node_under_compute_node (mem_nid , cpu_nid , 1 );
619669 }
620670}
621671
@@ -628,10 +678,10 @@ static void hmat_register_target_cache(struct memory_target *target)
628678 node_add_cache (mem_nid , & tcache -> cache_attrs );
629679}
630680
631- static void hmat_register_target_perf (struct memory_target * target )
681+ static void hmat_register_target_perf (struct memory_target * target , int access )
632682{
633683 unsigned mem_nid = pxm_to_node (target -> memory_pxm );
634- node_set_perf_attrs (mem_nid , & target -> hmem_attrs , 0 );
684+ node_set_perf_attrs (mem_nid , & target -> hmem_attrs [ access ], access );
635685}
636686
637687static void hmat_register_target_device (struct memory_target * target ,
@@ -664,9 +714,9 @@ static void hmat_register_target_device(struct memory_target *target,
664714 goto out_pdev ;
665715 }
666716
667- pdev -> dev .numa_node = acpi_map_pxm_to_online_node (target -> memory_pxm );
717+ pdev -> dev .numa_node = pxm_to_online_node (target -> memory_pxm );
668718 info = (struct memregion_info ) {
669- .target_node = acpi_map_pxm_to_node (target -> memory_pxm ),
719+ .target_node = pxm_to_node (target -> memory_pxm ),
670720 };
671721 rc = platform_device_add_data (pdev , & info , sizeof (info ));
672722 if (rc < 0 ) {
@@ -733,7 +783,8 @@ static void hmat_register_target(struct memory_target *target)
733783 if (!target -> registered ) {
734784 hmat_register_target_initiators (target );
735785 hmat_register_target_cache (target );
736- hmat_register_target_perf (target );
786+ hmat_register_target_perf (target , 0 );
787+ hmat_register_target_perf (target , 1 );
737788 target -> registered = true;
738789 }
739790 mutex_unlock (& target_lock );
0 commit comments