@@ -59,9 +59,8 @@ struct target_cache {
5959};
6060
6161enum {
62- NODE_ACCESS_CLASS_0 = 0 ,
63- NODE_ACCESS_CLASS_1 ,
64- NODE_ACCESS_CLASS_GENPORT_SINK ,
62+ NODE_ACCESS_CLASS_GENPORT_SINK_LOCAL = ACCESS_COORDINATE_MAX ,
63+ NODE_ACCESS_CLASS_GENPORT_SINK_CPU ,
6564 NODE_ACCESS_CLASS_MAX ,
6665};
6766
@@ -75,6 +74,7 @@ struct memory_target {
7574 struct node_cache_attrs cache_attrs ;
7675 u8 gen_port_device_handle [ACPI_SRAT_DEVICE_HANDLE_SIZE ];
7776 bool registered ;
77+ bool ext_updated ; /* externally updated */
7878};
7979
8080struct memory_initiator {
@@ -127,7 +127,8 @@ static struct memory_target *acpi_find_genport_target(u32 uid)
127127/**
128128 * acpi_get_genport_coordinates - Retrieve the access coordinates for a generic port
129129 * @uid: ACPI unique id
130- * @coord: The access coordinates written back out for the generic port
130+ * @coord: The access coordinates written back out for the generic port.
131+ * Expect 2 levels array.
131132 *
132133 * Return: 0 on success. Errno on failure.
133134 *
@@ -143,7 +144,10 @@ int acpi_get_genport_coordinates(u32 uid,
143144 if (!target )
144145 return - ENOENT ;
145146
146- * coord = target -> coord [NODE_ACCESS_CLASS_GENPORT_SINK ];
147+ coord [ACCESS_COORDINATE_LOCAL ] =
148+ target -> coord [NODE_ACCESS_CLASS_GENPORT_SINK_LOCAL ];
149+ coord [ACCESS_COORDINATE_CPU ] =
150+ target -> coord [NODE_ACCESS_CLASS_GENPORT_SINK_CPU ];
147151
148152 return 0 ;
149153}
@@ -325,6 +329,35 @@ static void hmat_update_target_access(struct memory_target *target,
325329 }
326330}
327331
332+ int hmat_update_target_coordinates (int nid , struct access_coordinate * coord ,
333+ enum access_coordinate_class access )
334+ {
335+ struct memory_target * target ;
336+ int pxm ;
337+
338+ if (nid == NUMA_NO_NODE )
339+ return - EINVAL ;
340+
341+ pxm = node_to_pxm (nid );
342+ guard (mutex )(& target_lock );
343+ target = find_mem_target (pxm );
344+ if (!target )
345+ return - ENODEV ;
346+
347+ hmat_update_target_access (target , ACPI_HMAT_READ_LATENCY ,
348+ coord -> read_latency , access );
349+ hmat_update_target_access (target , ACPI_HMAT_WRITE_LATENCY ,
350+ coord -> write_latency , access );
351+ hmat_update_target_access (target , ACPI_HMAT_READ_BANDWIDTH ,
352+ coord -> read_bandwidth , access );
353+ hmat_update_target_access (target , ACPI_HMAT_WRITE_BANDWIDTH ,
354+ coord -> write_bandwidth , access );
355+ target -> ext_updated = true;
356+
357+ return 0 ;
358+ }
359+ EXPORT_SYMBOL_GPL (hmat_update_target_coordinates );
360+
328361static __init void hmat_add_locality (struct acpi_hmat_locality * hmat_loc )
329362{
330363 struct memory_locality * loc ;
@@ -374,11 +407,11 @@ static __init void hmat_update_target(unsigned int tgt_pxm, unsigned int init_px
374407
375408 if (target && target -> processor_pxm == init_pxm ) {
376409 hmat_update_target_access (target , type , value ,
377- NODE_ACCESS_CLASS_0 );
410+ ACCESS_COORDINATE_LOCAL );
378411 /* If the node has a CPU, update access 1 */
379412 if (node_state (pxm_to_node (init_pxm ), N_CPU ))
380413 hmat_update_target_access (target , type , value ,
381- NODE_ACCESS_CLASS_1 );
414+ ACCESS_COORDINATE_CPU );
382415 }
383416}
384417
@@ -696,8 +729,13 @@ static void hmat_update_target_attrs(struct memory_target *target,
696729 u32 best = 0 ;
697730 int i ;
698731
732+ /* Don't update if an external agent has changed the data. */
733+ if (target -> ext_updated )
734+ return ;
735+
699736 /* Don't update for generic port if there's no device handle */
700- if (access == NODE_ACCESS_CLASS_GENPORT_SINK &&
737+ if ((access == NODE_ACCESS_CLASS_GENPORT_SINK_LOCAL ||
738+ access == NODE_ACCESS_CLASS_GENPORT_SINK_CPU ) &&
701739 !(* (u16 * )target -> gen_port_device_handle ))
702740 return ;
703741
@@ -709,7 +747,8 @@ static void hmat_update_target_attrs(struct memory_target *target,
709747 */
710748 if (target -> processor_pxm != PXM_INVAL ) {
711749 cpu_nid = pxm_to_node (target -> processor_pxm );
712- if (access == 0 || node_state (cpu_nid , N_CPU )) {
750+ if (access == ACCESS_COORDINATE_LOCAL ||
751+ node_state (cpu_nid , N_CPU )) {
713752 set_bit (target -> processor_pxm , p_nodes );
714753 return ;
715754 }
@@ -737,7 +776,9 @@ static void hmat_update_target_attrs(struct memory_target *target,
737776 list_for_each_entry (initiator , & initiators , node ) {
738777 u32 value ;
739778
740- if (access == 1 && !initiator -> has_cpu ) {
779+ if ((access == ACCESS_COORDINATE_CPU ||
780+ access == NODE_ACCESS_CLASS_GENPORT_SINK_CPU ) &&
781+ !initiator -> has_cpu ) {
741782 clear_bit (initiator -> processor_pxm , p_nodes );
742783 continue ;
743784 }
@@ -770,20 +811,24 @@ static void __hmat_register_target_initiators(struct memory_target *target,
770811 }
771812}
772813
773- static void hmat_register_generic_target_initiators (struct memory_target * target )
814+ static void hmat_update_generic_target (struct memory_target * target )
774815{
775816 static DECLARE_BITMAP (p_nodes , MAX_NUMNODES );
776817
777- __hmat_register_target_initiators (target , p_nodes ,
778- NODE_ACCESS_CLASS_GENPORT_SINK );
818+ hmat_update_target_attrs (target , p_nodes ,
819+ NODE_ACCESS_CLASS_GENPORT_SINK_LOCAL );
820+ hmat_update_target_attrs (target , p_nodes ,
821+ NODE_ACCESS_CLASS_GENPORT_SINK_CPU );
779822}
780823
781824static void hmat_register_target_initiators (struct memory_target * target )
782825{
783826 static DECLARE_BITMAP (p_nodes , MAX_NUMNODES );
784827
785- __hmat_register_target_initiators (target , p_nodes , 0 );
786- __hmat_register_target_initiators (target , p_nodes , 1 );
828+ __hmat_register_target_initiators (target , p_nodes ,
829+ ACCESS_COORDINATE_LOCAL );
830+ __hmat_register_target_initiators (target , p_nodes ,
831+ ACCESS_COORDINATE_CPU );
787832}
788833
789834static void hmat_register_target_cache (struct memory_target * target )
@@ -835,7 +880,7 @@ static void hmat_register_target(struct memory_target *target)
835880 */
836881 mutex_lock (& target_lock );
837882 if (* (u16 * )target -> gen_port_device_handle ) {
838- hmat_register_generic_target_initiators (target );
883+ hmat_update_generic_target (target );
839884 target -> registered = true;
840885 }
841886 mutex_unlock (& target_lock );
@@ -854,8 +899,8 @@ static void hmat_register_target(struct memory_target *target)
854899 if (!target -> registered ) {
855900 hmat_register_target_initiators (target );
856901 hmat_register_target_cache (target );
857- hmat_register_target_perf (target , NODE_ACCESS_CLASS_0 );
858- hmat_register_target_perf (target , NODE_ACCESS_CLASS_1 );
902+ hmat_register_target_perf (target , ACCESS_COORDINATE_LOCAL );
903+ hmat_register_target_perf (target , ACCESS_COORDINATE_CPU );
859904 target -> registered = true;
860905 }
861906 mutex_unlock (& target_lock );
@@ -927,7 +972,7 @@ static int hmat_calculate_adistance(struct notifier_block *self,
927972 return NOTIFY_OK ;
928973
929974 mutex_lock (& target_lock );
930- hmat_update_target_attrs (target , p_nodes , 1 );
975+ hmat_update_target_attrs (target , p_nodes , ACCESS_COORDINATE_CPU );
931976 mutex_unlock (& target_lock );
932977
933978 perf = & target -> coord [1 ];
0 commit comments