1488570ebSJim Harris /* SPDX-License-Identifier: BSD-3-Clause 2a6dbe372Spaul luse * Copyright (C) 2017 Intel Corporation. 316ae5879SBen Walker * All rights reserved. 416ae5879SBen Walker */ 516ae5879SBen Walker 6ab12e36bSDarek Stojaczyk #include "env_internal.h" 716ae5879SBen Walker 816ae5879SBen Walker #include <rte_config.h> 916ae5879SBen Walker #include <rte_lcore.h> 1016ae5879SBen Walker 117ee16130SJim Harris #include "spdk/cpuset.h" 12f838343cSJim Harris #include "spdk/log.h" 13f838343cSJim Harris #include "spdk/string.h" 14f838343cSJim Harris 15f838343cSJim Harris #define THREAD_SIBLINGS_FILE \ 16f838343cSJim Harris "/sys/devices/system/cpu/cpu%d/topology/thread_siblings" 177ee16130SJim Harris 1816ae5879SBen Walker uint32_t 1916ae5879SBen Walker spdk_env_get_core_count(void) 2016ae5879SBen Walker { 2116ae5879SBen Walker return rte_lcore_count(); 2216ae5879SBen Walker } 2316ae5879SBen Walker 2416ae5879SBen Walker uint32_t 2516ae5879SBen Walker spdk_env_get_current_core(void) 2616ae5879SBen Walker { 2716ae5879SBen Walker return rte_lcore_id(); 2816ae5879SBen Walker } 2916ae5879SBen Walker 3016ae5879SBen Walker uint32_t 3137b5d87bSJacek Kalwas spdk_env_get_main_core(void) 3237b5d87bSJacek Kalwas { 3337b5d87bSJacek Kalwas return rte_get_main_lcore(); 3437b5d87bSJacek Kalwas } 3537b5d87bSJacek Kalwas 3637b5d87bSJacek Kalwas uint32_t 3716ae5879SBen Walker spdk_env_get_first_core(void) 3816ae5879SBen Walker { 3916ae5879SBen Walker return rte_get_next_lcore(-1, 0, 0); 4016ae5879SBen Walker } 4116ae5879SBen Walker 4216ae5879SBen Walker uint32_t 431b7ce805SZiye Yang spdk_env_get_last_core(void) 441b7ce805SZiye Yang { 451b7ce805SZiye Yang uint32_t i; 462b8c23c7SDaniel Verkamp uint32_t last_core = UINT32_MAX; 471b7ce805SZiye Yang 481b7ce805SZiye Yang SPDK_ENV_FOREACH_CORE(i) { 491b7ce805SZiye Yang last_core = i; 501b7ce805SZiye Yang } 511b7ce805SZiye Yang 523bfd7d2bSZiye Yang assert(last_core != UINT32_MAX); 533bfd7d2bSZiye Yang 541b7ce805SZiye Yang return last_core; 551b7ce805SZiye Yang } 561b7ce805SZiye Yang 571b7ce805SZiye Yang uint32_t 5816ae5879SBen Walker spdk_env_get_next_core(uint32_t prev_core) 5916ae5879SBen Walker { 6016ae5879SBen Walker unsigned lcore; 6116ae5879SBen Walker 6216ae5879SBen Walker lcore = rte_get_next_lcore(prev_core, 0, 0); 6316ae5879SBen Walker if (lcore == RTE_MAX_LCORE) { 6416ae5879SBen Walker return UINT32_MAX; 6516ae5879SBen Walker } 6616ae5879SBen Walker return lcore; 6716ae5879SBen Walker } 6816ae5879SBen Walker 6938b1eaa4SJim Harris int32_t 7038b1eaa4SJim Harris spdk_env_get_numa_id(uint32_t core) 7116ae5879SBen Walker { 7233ccbba4SDariusz Stojaczyk if (core >= RTE_MAX_LCORE) { 73186b109dSJim Harris return SPDK_ENV_NUMA_ID_ANY; 7433ccbba4SDariusz Stojaczyk } 7533ccbba4SDariusz Stojaczyk 7616ae5879SBen Walker return rte_lcore_to_socket_id(core); 7716ae5879SBen Walker } 78ef60d87bSBen Walker 7938b1eaa4SJim Harris SPDK_LOG_DEPRECATION_REGISTER(env_socket_id, "spdk_env_get_socket_id", "v25.05", 0); 8038b1eaa4SJim Harris 8138b1eaa4SJim Harris uint32_t 8238b1eaa4SJim Harris spdk_env_get_socket_id(uint32_t core) 8338b1eaa4SJim Harris { 8438b1eaa4SJim Harris SPDK_LOG_DEPRECATED(env_socket_id); 8538b1eaa4SJim Harris return spdk_env_get_numa_id(core); 8638b1eaa4SJim Harris } 8738b1eaa4SJim Harris 88*479507e8SJim Harris int32_t 89*479507e8SJim Harris spdk_env_get_first_numa_id(void) 90*479507e8SJim Harris { 91*479507e8SJim Harris assert(rte_socket_count() > 0); 92*479507e8SJim Harris 93*479507e8SJim Harris return rte_socket_id_by_idx(0); 94*479507e8SJim Harris } 95*479507e8SJim Harris 96*479507e8SJim Harris int32_t 97*479507e8SJim Harris spdk_env_get_last_numa_id(void) 98*479507e8SJim Harris { 99*479507e8SJim Harris assert(rte_socket_count() > 0); 100*479507e8SJim Harris 101*479507e8SJim Harris return rte_socket_id_by_idx(rte_socket_count() - 1); 102*479507e8SJim Harris } 103*479507e8SJim Harris 104*479507e8SJim Harris int32_t 105*479507e8SJim Harris spdk_env_get_next_numa_id(int32_t prev_numa_id) 106*479507e8SJim Harris { 107*479507e8SJim Harris uint32_t i; 108*479507e8SJim Harris 109*479507e8SJim Harris for (i = 0; i < rte_socket_count(); i++) { 110*479507e8SJim Harris if (rte_socket_id_by_idx(i) == prev_numa_id) { 111*479507e8SJim Harris break; 112*479507e8SJim Harris } 113*479507e8SJim Harris } 114*479507e8SJim Harris 115*479507e8SJim Harris if ((i + 1) < rte_socket_count()) { 116*479507e8SJim Harris return rte_socket_id_by_idx(i + 1); 117*479507e8SJim Harris } else { 118*479507e8SJim Harris return INT32_MAX; 119*479507e8SJim Harris } 120*479507e8SJim Harris } 121*479507e8SJim Harris 1227ee16130SJim Harris void 1237ee16130SJim Harris spdk_env_get_cpuset(struct spdk_cpuset *cpuset) 1247ee16130SJim Harris { 1257ee16130SJim Harris uint32_t i; 1267ee16130SJim Harris 1277ee16130SJim Harris spdk_cpuset_zero(cpuset); 1287ee16130SJim Harris SPDK_ENV_FOREACH_CORE(i) { 1297ee16130SJim Harris spdk_cpuset_set_cpu(cpuset, i, true); 1307ee16130SJim Harris } 1317ee16130SJim Harris } 1327ee16130SJim Harris 133f838343cSJim Harris static bool 134f838343cSJim Harris env_core_get_smt_cpuset(struct spdk_cpuset *cpuset, uint32_t core) 135f838343cSJim Harris { 136f838343cSJim Harris #ifdef __linux__ 137f838343cSJim Harris struct spdk_cpuset smt_siblings; 138f838343cSJim Harris char path[PATH_MAX]; 139f838343cSJim Harris FILE *f; 140f838343cSJim Harris char *line = NULL; 141f838343cSJim Harris size_t len = 0; 142f838343cSJim Harris ssize_t read; 143f838343cSJim Harris bool valid = false; 144f838343cSJim Harris 145f838343cSJim Harris snprintf(path, sizeof(path), THREAD_SIBLINGS_FILE, core); 146f838343cSJim Harris f = fopen(path, "r"); 147f838343cSJim Harris if (f == NULL) { 148f838343cSJim Harris SPDK_ERRLOG("Could not fopen('%s'): %s\n", path, spdk_strerror(errno)); 149f838343cSJim Harris return false; 150f838343cSJim Harris } 151f838343cSJim Harris read = getline(&line, &len, f); 152f838343cSJim Harris if (read == -1) { 153f838343cSJim Harris SPDK_ERRLOG("Could not getline() for '%s': %s\n", path, spdk_strerror(errno)); 154f838343cSJim Harris goto ret; 155f838343cSJim Harris } 156f838343cSJim Harris 157f838343cSJim Harris /* Remove trailing newline */ 158f838343cSJim Harris line[strlen(line) - 1] = 0; 159f838343cSJim Harris if (spdk_cpuset_parse(&smt_siblings, line)) { 160f838343cSJim Harris SPDK_ERRLOG("Could not parse '%s' from '%s'\n", line, path); 161f838343cSJim Harris goto ret; 162f838343cSJim Harris } 163f838343cSJim Harris 164f838343cSJim Harris valid = true; 165f838343cSJim Harris spdk_cpuset_or(cpuset, &smt_siblings); 166f838343cSJim Harris ret: 167f838343cSJim Harris free(line); 168f838343cSJim Harris fclose(f); 169f838343cSJim Harris return valid; 170f838343cSJim Harris #else 171f838343cSJim Harris return false; 172f838343cSJim Harris #endif 173f838343cSJim Harris } 174f838343cSJim Harris 175f838343cSJim Harris bool 176f838343cSJim Harris spdk_env_core_get_smt_cpuset(struct spdk_cpuset *cpuset, uint32_t core) 177f838343cSJim Harris { 178f838343cSJim Harris uint32_t i; 179f838343cSJim Harris 180f838343cSJim Harris spdk_cpuset_zero(cpuset); 181f838343cSJim Harris 182f838343cSJim Harris if (core != UINT32_MAX) { 183f838343cSJim Harris return env_core_get_smt_cpuset(cpuset, core); 184f838343cSJim Harris } 185f838343cSJim Harris 186f838343cSJim Harris SPDK_ENV_FOREACH_CORE(i) { 187f838343cSJim Harris if (!env_core_get_smt_cpuset(cpuset, i)) { 188f838343cSJim Harris return false; 189f838343cSJim Harris } 190f838343cSJim Harris } 191f838343cSJim Harris 192f838343cSJim Harris return true; 193f838343cSJim Harris } 194f838343cSJim Harris 195ef60d87bSBen Walker int 196ef60d87bSBen Walker spdk_env_thread_launch_pinned(uint32_t core, thread_start_fn fn, void *arg) 197ef60d87bSBen Walker { 198ef60d87bSBen Walker int rc; 199ef60d87bSBen Walker 200ef60d87bSBen Walker rc = rte_eal_remote_launch(fn, arg, core); 201ef60d87bSBen Walker 202ef60d87bSBen Walker return rc; 203ef60d87bSBen Walker } 204ef60d87bSBen Walker 205ef60d87bSBen Walker void 206ef60d87bSBen Walker spdk_env_thread_wait_all(void) 207ef60d87bSBen Walker { 208ef60d87bSBen Walker rte_eal_mp_wait_lcore(); 209ef60d87bSBen Walker } 210