@@ -167,13 +167,26 @@ static umf_result_t numa_get_capacity(void *memTarget, size_t *capacity) {
167167 return UMF_RESULT_SUCCESS ;
168168}
169169
170- static umf_result_t numa_get_bandwidth (void * srcMemoryTarget ,
171- void * dstMemoryTarget ,
172- size_t * bandwidth ) {
173- if (!srcMemoryTarget || !dstMemoryTarget || !bandwidth ) {
174- return UMF_RESULT_ERROR_INVALID_ARGUMENT ;
170+ typedef enum memattr_type {
171+ MEMATTR_TYPE_BANDWIDTH ,
172+ MEMATTR_TYPE_LATENCY
173+ } memattr_type ;
174+
175+ static size_t memattr_get_worst_value (memattr_type type ) {
176+ switch (type ) {
177+ case MEMATTR_TYPE_BANDWIDTH :
178+ return 0 ;
179+ case MEMATTR_TYPE_LATENCY :
180+ return SIZE_MAX ;
181+ default :
182+ assert (0 ); // Should not be reachable
183+ return 0 ;
175184 }
185+ }
176186
187+ static umf_result_t query_attribute_value (void * srcMemoryTarget ,
188+ void * dstMemoryTarget , size_t * value ,
189+ memattr_type type ) {
177190 hwloc_topology_t topology = umfGetTopology ();
178191 if (!topology ) {
179192 return UMF_RESULT_ERROR_NOT_SUPPORTED ;
@@ -195,23 +208,75 @@ static umf_result_t numa_get_bandwidth(void *srcMemoryTarget,
195208
196209 // Given NUMA nodes aren't local, HWLOC returns an error in such case.
197210 if (!hwloc_bitmap_intersects (srcNumaNode -> cpuset , dstNumaNode -> cpuset )) {
198- * bandwidth = 0 ;
211+ // Since we want to skip such query, we return the worst possible
212+ // value for given memory attribute.
213+ * value = memattr_get_worst_value (type );
199214 return UMF_RESULT_SUCCESS ;
200215 }
201216
217+ enum hwloc_memattr_id_e hwlocMemAttrType = INT_MAX ;
218+ switch (type ) {
219+ case MEMATTR_TYPE_BANDWIDTH :
220+ hwlocMemAttrType = HWLOC_MEMATTR_ID_BANDWIDTH ;
221+ break ;
222+ case MEMATTR_TYPE_LATENCY :
223+ hwlocMemAttrType = HWLOC_MEMATTR_ID_LATENCY ;
224+ break ;
225+ default :
226+ assert (0 ); // Shouldn't be reachable.
227+ return UMF_RESULT_ERROR_INVALID_ARGUMENT ;
228+ }
229+
202230 struct hwloc_location initiator = {.location .cpuset = srcNumaNode -> cpuset ,
203231 .type = HWLOC_LOCATION_TYPE_CPUSET };
204- hwloc_uint64_t value = 0 ;
205- int ret = hwloc_memattr_get_value (topology , HWLOC_MEMATTR_ID_BANDWIDTH ,
206- dstNumaNode , & initiator , 0 , & value );
232+
233+ hwloc_uint64_t memAttrValue = 0 ;
234+ int ret = hwloc_memattr_get_value (topology , hwlocMemAttrType , dstNumaNode ,
235+ & initiator , 0 , & memAttrValue );
207236 if (ret ) {
208- LOG_ERR ("Retrieving bandwidth for initiator node %u to node %u failed." ,
209- srcNumaNode -> os_index , dstNumaNode -> os_index );
210237 return (errno == EINVAL ) ? UMF_RESULT_ERROR_NOT_SUPPORTED
211238 : UMF_RESULT_ERROR_UNKNOWN ;
212239 }
213240
214- * bandwidth = value ;
241+ * value = memAttrValue ;
242+
243+ return UMF_RESULT_SUCCESS ;
244+ }
245+
246+ static umf_result_t numa_get_bandwidth (void * srcMemoryTarget ,
247+ void * dstMemoryTarget ,
248+ size_t * bandwidth ) {
249+ if (!srcMemoryTarget || !dstMemoryTarget || !bandwidth ) {
250+ return UMF_RESULT_ERROR_INVALID_ARGUMENT ;
251+ }
252+
253+ umf_result_t ret = query_attribute_value (srcMemoryTarget , dstMemoryTarget ,
254+ bandwidth , MEMATTR_TYPE_BANDWIDTH );
255+ if (ret ) {
256+ LOG_ERR ("Retrieving bandwidth for initiator node %u to node %u failed." ,
257+ ((struct numa_memory_target_t * )srcMemoryTarget )-> physical_id ,
258+ ((struct numa_memory_target_t * )dstMemoryTarget )-> physical_id );
259+ return ret ;
260+ }
261+
262+ return UMF_RESULT_SUCCESS ;
263+ }
264+
265+ static umf_result_t numa_get_latency (void * srcMemoryTarget ,
266+ void * dstMemoryTarget , size_t * latency ) {
267+ if (!srcMemoryTarget || !dstMemoryTarget || !latency ) {
268+ return UMF_RESULT_ERROR_INVALID_ARGUMENT ;
269+ }
270+
271+ umf_result_t ret = query_attribute_value (srcMemoryTarget , dstMemoryTarget ,
272+ latency , MEMATTR_TYPE_LATENCY );
273+ if (ret ) {
274+ LOG_ERR ("Retrieving latency for initiator node %u to node %u failed." ,
275+ ((struct numa_memory_target_t * )srcMemoryTarget )-> physical_id ,
276+ ((struct numa_memory_target_t * )dstMemoryTarget )-> physical_id );
277+ return ret ;
278+ }
279+
215280 return UMF_RESULT_SUCCESS ;
216281}
217282
@@ -223,5 +288,6 @@ struct umf_memory_target_ops_t UMF_MEMORY_TARGET_NUMA_OPS = {
223288 .clone = numa_clone ,
224289 .get_capacity = numa_get_capacity ,
225290 .get_bandwidth = numa_get_bandwidth ,
291+ .get_latency = numa_get_latency ,
226292 .memory_provider_create_from_memspace =
227293 numa_memory_provider_create_from_memspace };
0 commit comments