|
Packit |
345191 |
/*
|
|
Packit |
345191 |
* Copyright (C) 2019 Intel Corporation.
|
|
Packit |
345191 |
* All rights reserved.
|
|
Packit |
345191 |
*
|
|
Packit |
345191 |
* Redistribution and use in source and binary forms, with or without
|
|
Packit |
345191 |
* modification, are permitted provided that the following conditions are met:
|
|
Packit |
345191 |
* 1. Redistributions of source code must retain the above copyright notice(s),
|
|
Packit |
345191 |
* this list of conditions and the following disclaimer.
|
|
Packit |
345191 |
* 2. Redistributions in binary form must reproduce the above copyright notice(s),
|
|
Packit |
345191 |
* this list of conditions and the following disclaimer in the documentation
|
|
Packit |
345191 |
* and/or other materials provided with the distribution.
|
|
Packit |
345191 |
*
|
|
Packit |
345191 |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY EXPRESS
|
|
Packit |
345191 |
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
Packit |
345191 |
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
|
Packit |
345191 |
* EVENT SHALL THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
Packit |
345191 |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
Packit |
345191 |
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
Packit |
345191 |
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
Packit |
345191 |
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
|
Packit |
345191 |
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
|
Packit |
345191 |
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
Packit |
345191 |
*/
|
|
Packit |
345191 |
|
|
Packit |
345191 |
#include <errno.h>
|
|
Packit |
345191 |
#include <limits.h>
|
|
Packit |
345191 |
#include <stdint.h>
|
|
Packit |
345191 |
|
|
Packit |
345191 |
#include <memkind/internal/memkind_log.h>
|
|
Packit |
345191 |
#include <memkind/internal/memkind_private.h>
|
|
Packit |
345191 |
#include <memkind/internal/memkind_bandwidth.h>
|
|
Packit |
345191 |
|
|
Packit |
345191 |
struct numanode_bandwidth_t {
|
|
Packit |
345191 |
int numanode;
|
|
Packit |
345191 |
int bandwidth;
|
|
Packit |
345191 |
};
|
|
Packit |
345191 |
|
|
Packit |
345191 |
struct bandwidth_nodes_t {
|
|
Packit |
345191 |
int bandwidth;
|
|
Packit |
345191 |
int num_numanodes;
|
|
Packit |
345191 |
int *numanodes;
|
|
Packit |
345191 |
};
|
|
Packit |
345191 |
|
|
Packit |
345191 |
VEC(vec_cpu_node, int);
|
|
Packit |
345191 |
|
|
Packit |
345191 |
#define BANDWIDTH_NODE_HIGH_VAL 2
|
|
Packit |
345191 |
#define BANDWIDTH_NODE_LOW_VAL 1
|
|
Packit |
345191 |
#define BANDWIDTH_NODE_NOT_PRESENT 0
|
|
Packit |
345191 |
|
|
Packit |
345191 |
static void bandwidth_assign_arbitrary_values(int *bandwidth,
|
|
Packit |
345191 |
struct bitmask *numa_nodes_bm)
|
|
Packit |
345191 |
{
|
|
Packit |
345191 |
unsigned i;
|
|
Packit |
345191 |
int nodes_num = numa_num_configured_nodes();
|
|
Packit |
345191 |
|
|
Packit |
345191 |
for (i = 0; i
|
|
Packit |
345191 |
if (numa_bitmask_isbitset(numa_nodes_bm, i)) {
|
|
Packit |
345191 |
bandwidth[i] = BANDWIDTH_NODE_HIGH_VAL;
|
|
Packit |
345191 |
nodes_num--;
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
for (i = 0; i
|
|
Packit |
345191 |
if (!numa_bitmask_isbitset(numa_nodes_bm, i)) {
|
|
Packit |
345191 |
bandwidth[i] = BANDWIDTH_NODE_LOW_VAL;
|
|
Packit |
345191 |
nodes_num--;
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
if (nodes_num==0) break;
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
int bandwidth_fill(int *bandwidth, get_node_bitmask get_bitmask)
|
|
Packit |
345191 |
{
|
|
Packit |
345191 |
struct bitmask *high_val_node_mask = numa_allocate_nodemask();
|
|
Packit |
345191 |
int ret = get_bitmask(high_val_node_mask);
|
|
Packit |
345191 |
if(ret == 0) {
|
|
Packit |
345191 |
bandwidth_assign_arbitrary_values(bandwidth, high_val_node_mask);
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
numa_bitmask_free(high_val_node_mask);
|
|
Packit |
345191 |
|
|
Packit |
345191 |
return ret;
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
static int bandwidth_fill_values_from_enviroment(int *bandwidth,
|
|
Packit |
345191 |
char *nodes_env)
|
|
Packit |
345191 |
{
|
|
Packit |
345191 |
struct bitmask *numa_nodes_bm = numa_parse_nodestring(nodes_env);
|
|
Packit |
345191 |
|
|
Packit |
345191 |
if (!numa_nodes_bm) {
|
|
Packit |
345191 |
log_err("Invalid value of environment variable.");
|
|
Packit |
345191 |
return MEMKIND_ERROR_ENVIRON;
|
|
Packit |
345191 |
} else {
|
|
Packit |
345191 |
bandwidth_assign_arbitrary_values(bandwidth, numa_nodes_bm);
|
|
Packit |
345191 |
numa_bitmask_free(numa_nodes_bm);
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
return 0;
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
static int bandwidth_fill_nodes(int *bandwidth, fill_bandwidth_values fill,
|
|
Packit |
345191 |
const char *env)
|
|
Packit |
345191 |
{
|
|
Packit |
345191 |
char *high_value_nodes_env = secure_getenv(env);
|
|
Packit |
345191 |
if (high_value_nodes_env) {
|
|
Packit |
345191 |
log_info("Environment variable %s detected: %s.", env, high_value_nodes_env);
|
|
Packit |
345191 |
return bandwidth_fill_values_from_enviroment(bandwidth, high_value_nodes_env);
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
return fill(bandwidth);
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
static int bandwidth_compare_numanode(const void *a, const void *b)
|
|
Packit |
345191 |
{
|
|
Packit |
345191 |
/***************************************************************************
|
|
Packit |
345191 |
* qsort comparison function for numa_node_bandwidth structures. Sorts in *
|
|
Packit |
345191 |
* order of bandwidth and then numanode. *
|
|
Packit |
345191 |
***************************************************************************/
|
|
Packit |
345191 |
int result;
|
|
Packit |
345191 |
struct numanode_bandwidth_t *aa = (struct numanode_bandwidth_t *)(a);
|
|
Packit |
345191 |
struct numanode_bandwidth_t *bb = (struct numanode_bandwidth_t *)(b);
|
|
Packit |
345191 |
result = (aa->bandwidth > bb->bandwidth) - (aa->bandwidth < bb->bandwidth);
|
|
Packit |
345191 |
if (result == 0) {
|
|
Packit |
345191 |
result = (aa->numanode > bb->numanode) - (aa->numanode < bb->numanode);
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
return result;
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
static int bandwidth_create_nodes(const int *bandwidth, int *num_unique,
|
|
Packit |
345191 |
struct bandwidth_nodes_t **bandwidth_nodes)
|
|
Packit |
345191 |
{
|
|
Packit |
345191 |
/***************************************************************************
|
|
Packit |
345191 |
* bandwidth (IN): *
|
|
Packit |
345191 |
* A vector of length equal NUMA_NUM_NODES that gives bandwidth for *
|
|
Packit |
345191 |
* each numa node, zero if numa node has unknown bandwidth. *
|
|
Packit |
345191 |
* num_unique (OUT): *
|
|
Packit |
345191 |
* number of unique non-zero bandwidth values in bandwidth *
|
|
Packit |
345191 |
* vector. *
|
|
Packit |
345191 |
* bandwidth_nodes (OUT): *
|
|
Packit |
345191 |
* A list of length num_unique sorted by bandwidth value where *
|
|
Packit |
345191 |
* each element gives a list of the numa nodes that have the *
|
|
Packit |
345191 |
* given bandwidth. *
|
|
Packit |
345191 |
* RETURNS MEMKIND_SUCCESS on success, error code on failure *
|
|
Packit |
345191 |
***************************************************************************/
|
|
Packit |
345191 |
int err = MEMKIND_SUCCESS;
|
|
Packit |
345191 |
int i, last_bandwidth;
|
|
Packit |
345191 |
*bandwidth_nodes = NULL;
|
|
Packit |
345191 |
/* allocate space for sorting array */
|
|
Packit |
345191 |
int nodes_num = numa_num_configured_nodes();
|
|
Packit |
345191 |
struct numanode_bandwidth_t *numanode_bandwidth = malloc(sizeof(
|
|
Packit |
345191 |
struct numanode_bandwidth_t) * nodes_num);
|
|
Packit |
345191 |
if (!numanode_bandwidth) {
|
|
Packit |
345191 |
err = MEMKIND_ERROR_MALLOC;
|
|
Packit |
345191 |
log_err("malloc() failed.");
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
if (!err) {
|
|
Packit |
345191 |
/* set sorting array */
|
|
Packit |
345191 |
int j = 0;
|
|
Packit |
345191 |
for (i = 0; i < NUMA_NUM_NODES; ++i) {
|
|
Packit |
345191 |
if (bandwidth[i] != BANDWIDTH_NODE_NOT_PRESENT) {
|
|
Packit |
345191 |
numanode_bandwidth[j].numanode = i;
|
|
Packit |
345191 |
numanode_bandwidth[j].bandwidth = bandwidth[i];
|
|
Packit |
345191 |
++j;
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
if (j == 0) {
|
|
Packit |
345191 |
err = MEMKIND_ERROR_UNAVAILABLE;
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
if (!err) {
|
|
Packit |
345191 |
qsort(numanode_bandwidth, nodes_num, sizeof(struct numanode_bandwidth_t),
|
|
Packit |
345191 |
bandwidth_compare_numanode);
|
|
Packit |
345191 |
/* calculate the number of unique bandwidths */
|
|
Packit |
345191 |
*num_unique = 1;
|
|
Packit |
345191 |
last_bandwidth = numanode_bandwidth[0].bandwidth;
|
|
Packit |
345191 |
for (i = 1; i < nodes_num; ++i) {
|
|
Packit |
345191 |
if (numanode_bandwidth[i].bandwidth != last_bandwidth) {
|
|
Packit |
345191 |
last_bandwidth = numanode_bandwidth[i].bandwidth;
|
|
Packit |
345191 |
++*num_unique;
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
/* allocate output array */
|
|
Packit |
345191 |
*bandwidth_nodes = (struct bandwidth_nodes_t *)malloc(sizeof(
|
|
Packit |
345191 |
struct bandwidth_nodes_t) * (*num_unique) + sizeof(int) * nodes_num);
|
|
Packit |
345191 |
if (!*bandwidth_nodes) {
|
|
Packit |
345191 |
err = MEMKIND_ERROR_MALLOC;
|
|
Packit |
345191 |
log_err("malloc() failed.");
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
if (!err) {
|
|
Packit |
345191 |
/* populate output */
|
|
Packit |
345191 |
(*bandwidth_nodes)[0].numanodes = (int *)(*bandwidth_nodes + *num_unique);
|
|
Packit |
345191 |
last_bandwidth = numanode_bandwidth[0].bandwidth;
|
|
Packit |
345191 |
int k = 0;
|
|
Packit |
345191 |
int l = 0;
|
|
Packit |
345191 |
for (i = 0; i < nodes_num; ++i, ++l) {
|
|
Packit |
345191 |
(*bandwidth_nodes)[0].numanodes[i] = numanode_bandwidth[i].numanode;
|
|
Packit |
345191 |
if (numanode_bandwidth[i].bandwidth != last_bandwidth) {
|
|
Packit |
345191 |
(*bandwidth_nodes)[k].num_numanodes = l;
|
|
Packit |
345191 |
(*bandwidth_nodes)[k].bandwidth = last_bandwidth;
|
|
Packit |
345191 |
l = 0;
|
|
Packit |
345191 |
++k;
|
|
Packit |
345191 |
(*bandwidth_nodes)[k].numanodes = (*bandwidth_nodes)[0].numanodes + i;
|
|
Packit |
345191 |
last_bandwidth = numanode_bandwidth[i].bandwidth;
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
(*bandwidth_nodes)[k].num_numanodes = l;
|
|
Packit |
345191 |
(*bandwidth_nodes)[k].bandwidth = last_bandwidth;
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
if (numanode_bandwidth) {
|
|
Packit |
345191 |
free(numanode_bandwidth);
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
if (err) {
|
|
Packit |
345191 |
if (*bandwidth_nodes) {
|
|
Packit |
345191 |
free(*bandwidth_nodes);
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
return err;
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
static int bandwidth_set_closest_numanode(int num_unique,
|
|
Packit |
345191 |
const struct bandwidth_nodes_t *bandwidth_nodes, bool is_single_node,
|
|
Packit |
345191 |
int num_cpunode, struct vec_cpu_node **closest_numanode)
|
|
Packit |
345191 |
{
|
|
Packit |
345191 |
/***************************************************************************
|
|
Packit |
345191 |
* num_unique (IN): *
|
|
Packit |
345191 |
* Length of bandwidth_nodes vector. *
|
|
Packit |
345191 |
* bandwidth_nodes (IN): *
|
|
Packit |
345191 |
* Output vector from bandwidth_create_nodes(). *
|
|
Packit |
345191 |
* is_single_node (IN): *
|
|
Packit |
345191 |
* Flag used to mark is only single closest numanode *
|
|
Packit |
345191 |
* is a valid configuration *
|
|
Packit |
345191 |
* num_cpunode (IN): *
|
|
Packit |
345191 |
* Number of cpu's and length of closest_numanode. *
|
|
Packit |
345191 |
* closest_numanode (OUT): *
|
|
Packit |
345191 |
* Vector that maps cpu index to closest numa node(s) *
|
|
Packit |
345191 |
* of the specified bandwidth. *
|
|
Packit |
345191 |
* RETURNS zero on success, error code on failure *
|
|
Packit |
345191 |
***************************************************************************/
|
|
Packit |
345191 |
int err = MEMKIND_SUCCESS;
|
|
Packit |
345191 |
int min_distance, distance, i, j, old_errno;
|
|
Packit |
345191 |
struct bandwidth_nodes_t match;
|
|
Packit |
345191 |
match.bandwidth = -1;
|
|
Packit |
345191 |
int target_bandwidth = bandwidth_nodes[num_unique-1].bandwidth;
|
|
Packit |
345191 |
|
|
Packit |
345191 |
struct vec_cpu_node *node_arr = (struct vec_cpu_node *) calloc(num_cpunode,
|
|
Packit |
345191 |
sizeof(struct vec_cpu_node));
|
|
Packit |
345191 |
|
|
Packit |
345191 |
if (!node_arr) {
|
|
Packit |
345191 |
log_err("calloc() failed.");
|
|
Packit |
345191 |
return MEMKIND_ERROR_MALLOC;
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
for (i = 0; i < num_unique; ++i) {
|
|
Packit |
345191 |
if (bandwidth_nodes[i].bandwidth == target_bandwidth) {
|
|
Packit |
345191 |
match = bandwidth_nodes[i];
|
|
Packit |
345191 |
break;
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
if (match.bandwidth == -1) {
|
|
Packit |
345191 |
err = MEMKIND_ERROR_UNAVAILABLE;
|
|
Packit |
345191 |
} else {
|
|
Packit |
345191 |
for (i = 0; i < num_cpunode; ++i) {
|
|
Packit |
345191 |
min_distance = INT_MAX;
|
|
Packit |
345191 |
for (j = 0; j < match.num_numanodes; ++j) {
|
|
Packit |
345191 |
old_errno = errno;
|
|
Packit |
345191 |
distance = numa_distance(numa_node_of_cpu(i), match.numanodes[j]);
|
|
Packit |
345191 |
errno = old_errno;
|
|
Packit |
345191 |
if (distance < min_distance) {
|
|
Packit |
345191 |
min_distance = distance;
|
|
Packit |
345191 |
VEC_CLEAR(&node_arr[i]);
|
|
Packit |
345191 |
VEC_PUSH_BACK(&node_arr[i], match.numanodes[j]);
|
|
Packit |
345191 |
} else if (distance == min_distance) {
|
|
Packit |
345191 |
VEC_PUSH_BACK(&node_arr[i], match.numanodes[j]);
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
if (VEC_SIZE(&node_arr[i]) > 1 && is_single_node &&
|
|
Packit |
345191 |
numa_bitmask_isbitset(numa_all_cpus_ptr, i)) {
|
|
Packit |
345191 |
log_err("Invalid Numa Configuration for cpu %d", i);
|
|
Packit |
345191 |
int node = -1;
|
|
Packit |
345191 |
VEC_FOREACH(node, &node_arr[i]) {
|
|
Packit |
345191 |
log_err("Node %d", node);
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
err = MEMKIND_ERROR_RUNTIME;
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
if (err) {
|
|
Packit |
345191 |
for (i = 0; i < num_cpunode; ++i) {
|
|
Packit |
345191 |
VEC_DELETE(&node_arr[i]);
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
free(node_arr);
|
|
Packit |
345191 |
node_arr = NULL;
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
*closest_numanode = node_arr;
|
|
Packit |
345191 |
|
|
Packit |
345191 |
return err;
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
int set_closest_numanode(fill_bandwidth_values fill_values, const char *env,
|
|
Packit |
345191 |
struct vec_cpu_node **closest_numanode, int num_cpu, bool is_single_node)
|
|
Packit |
345191 |
{
|
|
Packit |
345191 |
int status;
|
|
Packit |
345191 |
int num_unique = 0;
|
|
Packit |
345191 |
int i;
|
|
Packit |
345191 |
struct bandwidth_nodes_t *bandwidth_nodes = NULL;
|
|
Packit |
345191 |
int *bandwidth = (int *)calloc(NUMA_NUM_NODES, sizeof(int));
|
|
Packit |
345191 |
|
|
Packit |
345191 |
if (!bandwidth) {
|
|
Packit |
345191 |
log_err("calloc() failed.");
|
|
Packit |
345191 |
return MEMKIND_ERROR_MALLOC;
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
status = bandwidth_fill_nodes(bandwidth, fill_values, env);
|
|
Packit |
345191 |
if (status)
|
|
Packit |
345191 |
goto exit;
|
|
Packit |
345191 |
|
|
Packit |
345191 |
status = bandwidth_create_nodes(bandwidth, &num_unique, &bandwidth_nodes);
|
|
Packit |
345191 |
if (status)
|
|
Packit |
345191 |
goto exit;
|
|
Packit |
345191 |
|
|
Packit |
345191 |
status = bandwidth_set_closest_numanode(num_unique, bandwidth_nodes,
|
|
Packit |
345191 |
is_single_node, num_cpu, closest_numanode);
|
|
Packit |
345191 |
|
|
Packit |
345191 |
for(i = 0; i < bandwidth_nodes[num_unique-1].num_numanodes; ++i) {
|
|
Packit |
345191 |
log_info("NUMA node %d is high-bandwidth/dax-kmem memory.",
|
|
Packit |
345191 |
bandwidth_nodes[num_unique-1].numanodes[i]);
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
exit:
|
|
Packit |
345191 |
|
|
Packit |
345191 |
free(bandwidth_nodes);
|
|
Packit |
345191 |
free(bandwidth);
|
|
Packit |
345191 |
|
|
Packit |
345191 |
return status;
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
void set_bitmask_for_all_closest_numanodes(unsigned long *nodemask,
|
|
Packit |
345191 |
unsigned long maxnode, const struct vec_cpu_node *closest_numanode, int num_cpu)
|
|
Packit |
345191 |
{
|
|
Packit |
345191 |
if (MEMKIND_LIKELY(nodemask)) {
|
|
Packit |
345191 |
struct bitmask nodemask_bm = {maxnode, nodemask};
|
|
Packit |
345191 |
int cpu;
|
|
Packit |
345191 |
int node = -1;
|
|
Packit |
345191 |
numa_bitmask_clearall(&nodemask_bm);
|
|
Packit |
345191 |
for (cpu = 0; cpu < num_cpu; ++cpu) {
|
|
Packit |
345191 |
VEC_FOREACH(node, &closest_numanode[cpu]) {
|
|
Packit |
345191 |
numa_bitmask_setbit(&nodemask_bm, node);
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
int set_bitmask_for_current_closest_numanode(unsigned long *nodemask,
|
|
Packit |
345191 |
unsigned long maxnode, const struct vec_cpu_node *closest_numanode, int num_cpu)
|
|
Packit |
345191 |
{
|
|
Packit |
345191 |
if (MEMKIND_LIKELY(nodemask)) {
|
|
Packit |
345191 |
struct bitmask nodemask_bm = {maxnode, nodemask};
|
|
Packit |
345191 |
numa_bitmask_clearall(&nodemask_bm);
|
|
Packit |
345191 |
int cpu = sched_getcpu();
|
|
Packit |
345191 |
if (MEMKIND_LIKELY(cpu < num_cpu)) {
|
|
Packit |
345191 |
int node = -1;
|
|
Packit |
345191 |
VEC_FOREACH(node, &closest_numanode[cpu]) {
|
|
Packit |
345191 |
numa_bitmask_setbit(&nodemask_bm, node);
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
} else {
|
|
Packit |
345191 |
return MEMKIND_ERROR_RUNTIME;
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
return MEMKIND_SUCCESS;
|
|
Packit |
345191 |
}
|