8
8
#include <assert.h>
9
9
#include <errno.h>
10
10
#include <limits.h>
11
-
11
+ #include <numaif.h>
12
12
#include <stddef.h>
13
13
#include <stdio.h>
14
14
#include <stdlib.h>
15
15
#include <string.h>
16
+ #include <sys/syscall.h>
17
+
16
18
#include <umf.h>
17
19
#include <umf/base.h>
18
20
#include <umf/memory_provider.h>
32
34
#define CTL_PROVIDER_TYPE os_memory_provider_t
33
35
#include "provider_ctl_stats_impl.h"
34
36
37
+ #define MAX_NUMNODES 1024
35
38
#define NODESET_STR_BUF_LEN 1024
36
-
37
39
#define TLS_MSG_BUF_LEN 1024
38
40
39
41
typedef struct umf_os_memory_provider_params_t {
@@ -149,11 +151,47 @@ static umf_result_t initialize_nodeset(os_memory_provider_t *os_provider,
149
151
// Hwloc_set_area_membind fails if empty nodeset is passed so
150
152
// if no node is specified, just pass all available nodes.
151
153
// For modes where no node is needed, they will be ignored anyway.
152
- out_nodeset [0 ] = hwloc_bitmap_dup (
153
- hwloc_topology_get_complete_nodeset (os_provider -> topo ));
154
+
155
+ size_t * nodes = umf_ba_global_alloc (sizeof (size_t ) * MAX_NUMNODES );
156
+ if (!nodes ) {
157
+ umf_ba_global_free (out_nodeset );
158
+ os_provider -> nodeset_len = 0 ;
159
+ return UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY ;
160
+ }
161
+
162
+ size_t num = 0 ;
163
+ int ret = utils_get_complete_nodeset (nodes , MAX_NUMNODES , & num );
164
+ if (ret < 0 ) {
165
+ umf_ba_global_free (out_nodeset );
166
+ os_provider -> nodeset_len = 0 ;
167
+ umf_ba_global_free (nodes );
168
+ return UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY ;
169
+ }
170
+
171
+ hwloc_bitmap_t complete_nodeset = hwloc_bitmap_alloc ();
172
+ if (!complete_nodeset ) {
173
+ umf_ba_global_free (out_nodeset );
174
+ os_provider -> nodeset_len = 0 ;
175
+ umf_ba_global_free (nodes );
176
+ return UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY ;
177
+ }
178
+
179
+ for (size_t i = 0 ; i < num ; i ++ ) {
180
+ if (hwloc_bitmap_set (complete_nodeset , (int )nodes [i ])) {
181
+ umf_ba_global_free (out_nodeset );
182
+ os_provider -> nodeset_len = 0 ;
183
+ hwloc_bitmap_free (complete_nodeset );
184
+ umf_ba_global_free (nodes );
185
+ return UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY ;
186
+ }
187
+ }
188
+ umf_ba_global_free (nodes );
189
+
190
+ out_nodeset [0 ] = hwloc_bitmap_dup (complete_nodeset );
154
191
if (!out_nodeset [0 ]) {
155
192
goto err_free_list ;
156
193
}
194
+ hwloc_bitmap_free (complete_nodeset );
157
195
return UMF_RESULT_SUCCESS ;
158
196
}
159
197
@@ -515,6 +553,11 @@ translate_params(const umf_os_memory_provider_params_t *in_params,
515
553
516
554
provider -> numa_flags =
517
555
getHwlocMembindFlags (in_params -> numa_mode , is_dedicated_node_bind );
556
+
557
+ //
558
+ provider -> mbind_mode = in_params -> numa_mode ;
559
+ provider -> dedicated = is_dedicated_node_bind ;
560
+
518
561
provider -> mode = in_params -> numa_mode ;
519
562
provider -> part_size = in_params -> part_size ;
520
563
@@ -556,21 +599,34 @@ static umf_result_t os_initialize(const void *params, void **provider) {
556
599
557
600
memset (os_provider , 0 , sizeof (* os_provider ));
558
601
559
- int r = hwloc_topology_init (& os_provider -> topo );
560
- if (r ) {
561
- LOG_ERR ("HWLOC topology init failed" );
562
- ret = UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY ;
563
- goto err_free_os_provider ;
564
- }
565
-
566
- r = hwloc_topology_load (os_provider -> topo );
567
- if (r ) {
568
- os_store_last_native_error (UMF_OS_RESULT_ERROR_TOPO_DISCOVERY_FAILED ,
569
- 0 );
570
- LOG_ERR ("HWLOC topology discovery failed" );
571
- ret = UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC ;
572
- goto err_destroy_hwloc_topology ;
573
- }
602
+ //struct timespec ts_init_start, ts_init_end;
603
+ //clock_gettime(CLOCK_MONOTONIC, &ts_init_start);
604
+
605
+ //int r = hwloc_topology_init(&os_provider->topo);
606
+ //if (r) {
607
+ // LOG_ERR("HWLOC topology init failed");
608
+ // ret = UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY;
609
+ // goto err_free_os_provider;
610
+ //}
611
+
612
+ //hwloc_topology_set_all_types_filter(os_provider->topo,
613
+ // HWLOC_TYPE_FILTER_KEEP_NONE);
614
+ //hwloc_topology_set_type_filter(os_provider->topo, HWLOC_OBJ_CORE,
615
+ // HWLOC_TYPE_FILTER_KEEP_ALL);
616
+
617
+ //r = hwloc_topology_load(os_provider->topo);
618
+ //if (r) {
619
+ // os_store_last_native_error(UMF_OS_RESULT_ERROR_TOPO_DISCOVERY_FAILED,
620
+ // 0);
621
+ // LOG_ERR("HWLOC topology discovery failed");
622
+ // ret = UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC;
623
+ // goto err_destroy_hwloc_topology;
624
+ //}
625
+
626
+ //clock_gettime(CLOCK_MONOTONIC, &ts_init_end);
627
+ //LOG_FATAL("HWLOC topology initialized in %ld.%09ld seconds",
628
+ // ts_init_end.tv_sec - ts_init_start.tv_sec,
629
+ // ts_init_end.tv_nsec - ts_init_start.tv_nsec);
574
630
575
631
os_provider -> fd_offset_map = critnib_new (NULL , NULL );
576
632
if (!os_provider -> fd_offset_map ) {
@@ -620,8 +676,8 @@ static umf_result_t os_initialize(const void *params, void **provider) {
620
676
err_destroy_critnib :
621
677
critnib_delete (os_provider -> fd_offset_map );
622
678
err_destroy_hwloc_topology :
623
- hwloc_topology_destroy (os_provider -> topo );
624
- err_free_os_provider :
679
+ // hwloc_topology_destroy(os_provider->topo);
680
+ // err_free_os_provider:
625
681
umf_ba_global_free (os_provider );
626
682
return ret ;
627
683
}
@@ -644,7 +700,7 @@ static umf_result_t os_finalize(void *provider) {
644
700
if (os_provider -> nodeset_str_buf ) {
645
701
umf_ba_global_free (os_provider -> nodeset_str_buf );
646
702
}
647
- hwloc_topology_destroy (os_provider -> topo );
703
+ // hwloc_topology_destroy(os_provider->topo);
648
704
umf_ba_global_free (os_provider );
649
705
return UMF_RESULT_SUCCESS ;
650
706
}
@@ -1007,10 +1063,47 @@ static umf_result_t os_alloc(void *provider, size_t size, size_t alignment,
1007
1063
1008
1064
do {
1009
1065
errno = 0 ;
1010
- ret = hwloc_set_area_membind (os_provider -> topo , membind .addr ,
1011
- membind .bind_size , membind .bitmap ,
1012
- os_provider -> numa_policy ,
1013
- os_provider -> numa_flags );
1066
+ ret = 0 ;
1067
+
1068
+ /* Use mbind syscall directly instead of hwloc */
1069
+ /* Requires: #include <numaif.h> */
1070
+ unsigned long nodemask = 0 ;
1071
+ int maxnode = 8 * sizeof (nodemask ); /* up to 64 nodes */
1072
+ /* Convert hwloc_bitmap_t to nodemask (assume bitmap fits in ulong) */
1073
+ if (membind .bitmap ) {
1074
+ for (int i = 0 ; i < maxnode ; ++ i ) {
1075
+ if (hwloc_bitmap_isset (membind .bitmap , i )) {
1076
+ nodemask |= (1UL << i );
1077
+ }
1078
+ }
1079
+ }
1080
+
1081
+ int mode = MPOL_DEFAULT ;
1082
+ if (os_provider -> mbind_mode == UMF_NUMA_MODE_INTERLEAVE &&
1083
+ os_provider -> dedicated == 0 ) {
1084
+ mode = MPOL_INTERLEAVE ;
1085
+ } else if (os_provider -> mbind_mode == UMF_NUMA_MODE_SPLIT ) {
1086
+ mode = MPOL_BIND ;
1087
+ } else if (os_provider -> mbind_mode == UMF_NUMA_MODE_LOCAL ) {
1088
+ mode = MPOL_LOCAL ;
1089
+ nodemask = 0 ; // MPOL_LOCAL does not use nodemask
1090
+ } else if (os_provider -> mbind_mode == UMF_NUMA_MODE_PREFERRED ) {
1091
+ mode = MPOL_BIND ;
1092
+ } else if (os_provider -> mbind_mode == UMF_NUMA_MODE_BIND ||
1093
+ os_provider -> dedicated ) {
1094
+ mode = MPOL_BIND ;
1095
+ }
1096
+
1097
+ unsigned long mbind_flags = 0 ;
1098
+ if (os_provider -> dedicated ) {
1099
+ mbind_flags |= MPOL_MF_STRICT ;
1100
+ }
1101
+
1102
+ ret = syscall (__NR_mbind , membind .addr , membind .bind_size , mode ,
1103
+ & nodemask , maxnode , mbind_flags );
1104
+
1105
+ // ret = mbind(addr, membind.bind_size, mode, &nodemask, maxnode,
1106
+ // mbind_flags);
1014
1107
1015
1108
if (ret ) {
1016
1109
os_store_last_native_error (UMF_OS_RESULT_ERROR_BIND_FAILED ,
0 commit comments