/** * Copyright (C) Mellanox Technologies Ltd. 2001-2018. ALL RIGHTS RESERVED. * * See file LICENSE for terms. */ #include "numa.h" #include #include #include #include const char *ucs_numa_policy_names[] = { [UCS_NUMA_POLICY_DEFAULT] = "default", [UCS_NUMA_POLICY_PREFERRED] = "preferred", [UCS_NUMA_POLICY_BIND] = "bind", [UCS_NUMA_POLICY_LAST] = NULL, }; #if HAVE_NUMA static void ucs_numa_populate_cpumap(int16_t cpu_numa_nodes[]) { struct bitmask *cpumask; int numa_node, cpu; int ret; cpumask = numa_allocate_cpumask(); for (numa_node = 0; numa_node <= numa_max_node(); ++numa_node) { if (!numa_bitmask_isbitset(numa_all_nodes_ptr, numa_node)) { continue; } ret = numa_node_to_cpus(numa_node, cpumask); if (ret == -1) { ucs_warn("failed to get CPUs for NUMA node %d: %m", numa_node); continue; } for (cpu = 0; cpu < numa_num_configured_cpus(); ++cpu) { if (numa_bitmask_isbitset(cpumask, cpu)) { cpu_numa_nodes[cpu] = numa_node + 1; } } } numa_free_cpumask(cpumask); } int ucs_numa_node_of_cpu(int cpu) { /* we can initialize statically only to the value 0, so the NUMA node * numbers will be stored as 1..N instead of 0..N-1 */ static int16_t cpu_numa_nodes[__CPU_SETSIZE] = {0}; UCS_STATIC_ASSERT(NUMA_NUM_NODES <= INT16_MAX); ucs_assert(cpu < __CPU_SETSIZE); if (cpu_numa_nodes[cpu] == 0) { ucs_numa_populate_cpumap(cpu_numa_nodes); } return cpu_numa_nodes[cpu] - 1; } #endif