Skip to content

Commit a7383a8

Browse files
committed
x
1 parent 67e6263 commit a7383a8

File tree

6 files changed

+150
-17
lines changed

6 files changed

+150
-17
lines changed

include/umf/providers/provider_os_memory.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ typedef enum umf_numa_mode_t {
4646
/// umf_numa_split_partition_t can be passed in umf_os_memory_provider_params_t structure
4747
/// to specify other distribution.
4848
UMF_NUMA_MODE_SPLIT,
49+
4950
/// The memory is allocated on the node of the CPU that triggered the
5051
/// allocation. If this mode is specified, nodemask must be NULL and
5152
/// maxnode must be 0.
@@ -58,6 +59,7 @@ typedef struct umf_numa_split_partition_t {
5859
/// The weight of the partition, representing the proportion of
5960
/// the allocation that should be assigned to this NUMA node.
6061
unsigned weight;
62+
6163
/// The NUMA node where the pages assigned to this partition will be bound.
6264
unsigned target;
6365
} umf_numa_split_partition_t;

src/libumf.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ umf_result_t umfInit(void) {
4545
utils_mutex_lock(&initMutex);
4646

4747
if (umfRefCount == 0) {
48+
LOG_FATAL("umfInit");
49+
4850
utils_log_init();
4951
umf_result_t umf_result = umfMemoryTrackerCreate(&TRACKER);
5052
if (umf_result != UMF_RESULT_SUCCESS) {

src/provider/provider_os_memory.c

Lines changed: 110 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,16 @@
88
#include <assert.h>
99
#include <errno.h>
1010
#include <limits.h>
11-
1211
#include <stddef.h>
1312
#include <stdio.h>
1413
#include <stdlib.h>
1514
#include <string.h>
15+
16+
#ifndef _WIN32
17+
#include <numaif.h>
18+
#include <sys/syscall.h>
19+
#endif
20+
1621
#include <umf.h>
1722
#include <umf/base.h>
1823
#include <umf/memory_provider.h>
@@ -32,8 +37,8 @@
3237
#define CTL_PROVIDER_TYPE os_memory_provider_t
3338
#include "provider_ctl_stats_impl.h"
3439

40+
#define MAX_NUMNODES 1024
3541
#define NODESET_STR_BUF_LEN 1024
36-
3742
#define TLS_MSG_BUF_LEN 1024
3843

3944
static const char *DEFAULT_NAME = "OS";
@@ -152,8 +157,33 @@ static umf_result_t initialize_nodeset(os_memory_provider_t *os_provider,
152157
// Hwloc_set_area_membind fails if empty nodeset is passed so
153158
// if no node is specified, just pass all available nodes.
154159
// For modes where no node is needed, they will be ignored anyway.
160+
161+
#ifdef _WIN32
155162
out_nodeset[0] = hwloc_bitmap_dup(
156163
hwloc_topology_get_complete_nodeset(os_provider->topo));
164+
#else
165+
size_t *nodes = umf_ba_global_alloc(sizeof(size_t) * MAX_NUMNODES);
166+
if (!nodes) {
167+
umf_ba_global_free(out_nodeset);
168+
os_provider->nodeset_len = 0;
169+
return UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY;
170+
}
171+
172+
size_t num = 0;
173+
int ret = utils_get_complete_nodeset(nodes, MAX_NUMNODES, &num);
174+
if (ret < 0) {
175+
umf_ba_global_free(out_nodeset);
176+
os_provider->nodeset_len = 0;
177+
umf_ba_global_free(nodes);
178+
return UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY;
179+
}
180+
181+
for (size_t i = 0; i < num; i++) {
182+
hwloc_bitmap_set(out_nodeset[0], (int)nodes[i]);
183+
}
184+
umf_ba_global_free(nodes);
185+
#endif
186+
157187
if (!out_nodeset[0]) {
158188
goto err_free_list;
159189
}
@@ -518,6 +548,12 @@ translate_params(const umf_os_memory_provider_params_t *in_params,
518548

519549
provider->numa_flags =
520550
getHwlocMembindFlags(in_params->numa_mode, is_dedicated_node_bind);
551+
552+
#ifndef _WIN32
553+
provider->umf_numa_mode = in_params->numa_mode;
554+
provider->dedicated = is_dedicated_node_bind;
555+
#endif
556+
521557
provider->mode = in_params->numa_mode;
522558
provider->part_size = in_params->part_size;
523559

@@ -561,21 +597,34 @@ static umf_result_t os_initialize(const void *params, void **provider) {
561597
snprintf(os_provider->name, sizeof(os_provider->name), "%s",
562598
in_params->name);
563599

564-
int r = hwloc_topology_init(&os_provider->topo);
565-
if (r) {
566-
LOG_ERR("HWLOC topology init failed");
567-
ret = UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY;
568-
goto err_free_os_provider;
569-
}
570-
571-
r = hwloc_topology_load(os_provider->topo);
572-
if (r) {
573-
os_store_last_native_error(UMF_OS_RESULT_ERROR_TOPO_DISCOVERY_FAILED,
574-
0);
575-
LOG_ERR("HWLOC topology discovery failed");
576-
ret = UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC;
577-
goto err_destroy_hwloc_topology;
578-
}
600+
//struct timespec ts_init_start, ts_init_end;
601+
//clock_gettime(CLOCK_MONOTONIC, &ts_init_start);
602+
603+
//int r = hwloc_topology_init(&os_provider->topo);
604+
//if (r) {
605+
// LOG_ERR("HWLOC topology init failed");
606+
// ret = UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY;
607+
// goto err_free_os_provider;
608+
//}
609+
610+
//hwloc_topology_set_all_types_filter(os_provider->topo,
611+
// HWLOC_TYPE_FILTER_KEEP_NONE);
612+
//hwloc_topology_set_type_filter(os_provider->topo, HWLOC_OBJ_CORE,
613+
// HWLOC_TYPE_FILTER_KEEP_ALL);
614+
615+
//r = hwloc_topology_load(os_provider->topo);
616+
//if (r) {
617+
// os_store_last_native_error(UMF_OS_RESULT_ERROR_TOPO_DISCOVERY_FAILED,
618+
// 0);
619+
// LOG_ERR("HWLOC topology discovery failed");
620+
// ret = UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC;
621+
// goto err_destroy_hwloc_topology;
622+
//}
623+
624+
//clock_gettime(CLOCK_MONOTONIC, &ts_init_end);
625+
//LOG_FATAL("HWLOC topology initialized in %ld.%09ld seconds",
626+
// ts_init_end.tv_sec - ts_init_start.tv_sec,
627+
// ts_init_end.tv_nsec - ts_init_start.tv_nsec);
579628

580629
os_provider->fd_offset_map = critnib_new(NULL, NULL);
581630
if (!os_provider->fd_offset_map) {
@@ -625,8 +674,10 @@ static umf_result_t os_initialize(const void *params, void **provider) {
625674
err_destroy_critnib:
626675
critnib_delete(os_provider->fd_offset_map);
627676
err_destroy_hwloc_topology:
677+
#ifdef _WIN32
628678
hwloc_topology_destroy(os_provider->topo);
629679
err_free_os_provider:
680+
#endif
630681
umf_ba_global_free(os_provider);
631682
return ret;
632683
}
@@ -649,7 +700,9 @@ static umf_result_t os_finalize(void *provider) {
649700
if (os_provider->nodeset_str_buf) {
650701
umf_ba_global_free(os_provider->nodeset_str_buf);
651702
}
703+
#ifdef _WIN32
652704
hwloc_topology_destroy(os_provider->topo);
705+
#endif
653706
umf_ba_global_free(os_provider);
654707
return UMF_RESULT_SUCCESS;
655708
}
@@ -1012,10 +1065,50 @@ static umf_result_t os_alloc(void *provider, size_t size, size_t alignment,
10121065

10131066
do {
10141067
errno = 0;
1068+
ret = 0;
1069+
1070+
#ifdef _WIN32
10151071
ret = hwloc_set_area_membind(os_provider->topo, membind.addr,
10161072
membind.bind_size, membind.bitmap,
10171073
os_provider->numa_policy,
10181074
os_provider->numa_flags);
1075+
#else // !_WIN32
1076+
1077+
// on Linux, use mbind syscall directly instead of hwloc
1078+
unsigned long nodemask = 0;
1079+
int maxnode = 8 * sizeof(nodemask); // up to 64 nodes
1080+
if (membind.bitmap) {
1081+
for (int i = 0; i < maxnode; ++i) {
1082+
if (hwloc_bitmap_isset(membind.bitmap, i)) {
1083+
nodemask |= (1UL << i);
1084+
}
1085+
}
1086+
}
1087+
1088+
int mbind_mode = MPOL_DEFAULT;
1089+
if (os_provider->umf_numa_mode == UMF_NUMA_MODE_INTERLEAVE &&
1090+
os_provider->dedicated == 0) {
1091+
mbind_mode = MPOL_INTERLEAVE;
1092+
} else if (os_provider->umf_numa_mode == UMF_NUMA_MODE_SPLIT) {
1093+
mbind_mode = MPOL_BIND;
1094+
} else if (os_provider->umf_numa_mode == UMF_NUMA_MODE_LOCAL) {
1095+
mbind_mode = MPOL_LOCAL;
1096+
nodemask = 0;
1097+
} else if (os_provider->umf_numa_mode == UMF_NUMA_MODE_PREFERRED) {
1098+
mbind_mode = MPOL_BIND;
1099+
} else if (os_provider->umf_numa_mode == UMF_NUMA_MODE_BIND ||
1100+
os_provider->dedicated) {
1101+
mbind_mode = MPOL_BIND;
1102+
}
1103+
1104+
unsigned long mbind_flags = 0;
1105+
if (os_provider->dedicated) {
1106+
mbind_flags |= MPOL_MF_STRICT;
1107+
}
1108+
1109+
ret = syscall(__NR_mbind, membind.addr, membind.bind_size,
1110+
mbind_mode, &nodemask, maxnode, mbind_flags);
1111+
#endif // !_WIN32
10191112

10201113
if (ret) {
10211114
os_store_last_native_error(UMF_OS_RESULT_ERROR_BIND_FAILED,

src/provider/provider_os_memory_internal.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,15 @@ typedef struct os_memory_provider_t {
6868
unsigned partitions_len;
6969
size_t partitions_weight_sum;
7070

71+
#ifndef _WIN32
72+
// NOTE: on linux we don't want to use hwloc_topology_t directly because
73+
// of its long initialization time
74+
umf_numa_mode_t umf_numa_mode;
75+
int dedicated;
76+
77+
#else
7178
hwloc_topology_t topo;
79+
#endif
7280

7381
char name[64];
7482

src/utils/utils_common.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,8 @@ size_t utils_max(size_t a, size_t b);
188188

189189
size_t utils_min(size_t a, size_t b);
190190

191+
int utils_get_complete_nodeset(size_t *ids, size_t size, size_t *);
192+
191193
#ifdef __cplusplus
192194
}
193195
#endif

src/utils/utils_linux_common.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,12 @@
77
*
88
*/
99

10+
#include <dirent.h>
1011
#include <errno.h>
1112
#include <fcntl.h>
1213
#include <stdbool.h>
14+
#include <stdlib.h>
15+
#include <string.h>
1316
#include <sys/mman.h>
1417
#include <sys/stat.h>
1518
#include <sys/syscall.h>
@@ -240,3 +243,26 @@ int utils_create_anonymous_fd(void) {
240243

241244
return fd;
242245
}
246+
247+
int utils_get_complete_nodeset(size_t *nodes, size_t nodes_size, size_t *num) {
248+
DIR *dir = opendir("/sys/devices/system/node/");
249+
if (!dir) {
250+
return -1;
251+
}
252+
253+
struct dirent *entry;
254+
while ((entry = readdir(dir)) != NULL) {
255+
if (strncmp(entry->d_name, "node", 4) == 0) {
256+
char *endptr;
257+
long node_id = strtol(entry->d_name + 4, &endptr, 10);
258+
if (*endptr == '\0' && node_id >= 0 &&
259+
(size_t)node_id < nodes_size) {
260+
nodes[*num] = (size_t)node_id;
261+
(*num)++;
262+
}
263+
}
264+
}
265+
266+
closedir(dir);
267+
return 0;
268+
}

0 commit comments

Comments
 (0)