1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (C) 2017 Intel Corporation. 3 * All rights reserved. 4 */ 5 6 #include "env_internal.h" 7 8 #include <rte_config.h> 9 #include <rte_lcore.h> 10 11 #include "spdk/cpuset.h" 12 #include "spdk/log.h" 13 #include "spdk/string.h" 14 15 #define THREAD_SIBLINGS_FILE \ 16 "/sys/devices/system/cpu/cpu%d/topology/thread_siblings" 17 18 uint32_t 19 spdk_env_get_core_count(void) 20 { 21 return rte_lcore_count(); 22 } 23 24 uint32_t 25 spdk_env_get_current_core(void) 26 { 27 return rte_lcore_id(); 28 } 29 30 uint32_t 31 spdk_env_get_main_core(void) 32 { 33 return rte_get_main_lcore(); 34 } 35 36 uint32_t 37 spdk_env_get_first_core(void) 38 { 39 return rte_get_next_lcore(-1, 0, 0); 40 } 41 42 uint32_t 43 spdk_env_get_last_core(void) 44 { 45 uint32_t i; 46 uint32_t last_core = UINT32_MAX; 47 48 SPDK_ENV_FOREACH_CORE(i) { 49 last_core = i; 50 } 51 52 assert(last_core != UINT32_MAX); 53 54 return last_core; 55 } 56 57 uint32_t 58 spdk_env_get_next_core(uint32_t prev_core) 59 { 60 unsigned lcore; 61 62 lcore = rte_get_next_lcore(prev_core, 0, 0); 63 if (lcore == RTE_MAX_LCORE) { 64 return UINT32_MAX; 65 } 66 return lcore; 67 } 68 69 int32_t 70 spdk_env_get_numa_id(uint32_t core) 71 { 72 if (core >= RTE_MAX_LCORE) { 73 return SPDK_ENV_NUMA_ID_ANY; 74 } 75 76 return rte_lcore_to_socket_id(core); 77 } 78 79 SPDK_LOG_DEPRECATION_REGISTER(env_socket_id, "spdk_env_get_socket_id", "v25.05", 0); 80 81 uint32_t 82 spdk_env_get_socket_id(uint32_t core) 83 { 84 SPDK_LOG_DEPRECATED(env_socket_id); 85 return spdk_env_get_numa_id(core); 86 } 87 88 int32_t 89 spdk_env_get_first_numa_id(void) 90 { 91 assert(rte_socket_count() > 0); 92 93 return rte_socket_id_by_idx(0); 94 } 95 96 int32_t 97 spdk_env_get_last_numa_id(void) 98 { 99 assert(rte_socket_count() > 0); 100 101 return rte_socket_id_by_idx(rte_socket_count() - 1); 102 } 103 104 int32_t 105 spdk_env_get_next_numa_id(int32_t prev_numa_id) 106 { 107 uint32_t i; 108 109 for (i = 0; i < rte_socket_count(); i++) { 110 if (rte_socket_id_by_idx(i) == prev_numa_id) { 111 break; 112 } 113 } 114 115 if ((i + 1) < rte_socket_count()) { 116 return rte_socket_id_by_idx(i + 1); 117 } else { 118 return INT32_MAX; 119 } 120 } 121 122 void 123 spdk_env_get_cpuset(struct spdk_cpuset *cpuset) 124 { 125 uint32_t i; 126 127 spdk_cpuset_zero(cpuset); 128 SPDK_ENV_FOREACH_CORE(i) { 129 spdk_cpuset_set_cpu(cpuset, i, true); 130 } 131 } 132 133 static bool 134 env_core_get_smt_cpuset(struct spdk_cpuset *cpuset, uint32_t core) 135 { 136 #ifdef __linux__ 137 struct spdk_cpuset smt_siblings; 138 char path[PATH_MAX]; 139 FILE *f; 140 char *line = NULL; 141 size_t len = 0; 142 ssize_t read; 143 bool valid = false; 144 145 snprintf(path, sizeof(path), THREAD_SIBLINGS_FILE, core); 146 f = fopen(path, "r"); 147 if (f == NULL) { 148 SPDK_ERRLOG("Could not fopen('%s'): %s\n", path, spdk_strerror(errno)); 149 return false; 150 } 151 read = getline(&line, &len, f); 152 if (read == -1) { 153 SPDK_ERRLOG("Could not getline() for '%s': %s\n", path, spdk_strerror(errno)); 154 goto ret; 155 } 156 157 /* Remove trailing newline */ 158 line[strlen(line) - 1] = 0; 159 if (spdk_cpuset_parse(&smt_siblings, line)) { 160 SPDK_ERRLOG("Could not parse '%s' from '%s'\n", line, path); 161 goto ret; 162 } 163 164 valid = true; 165 spdk_cpuset_or(cpuset, &smt_siblings); 166 ret: 167 free(line); 168 fclose(f); 169 return valid; 170 #else 171 return false; 172 #endif 173 } 174 175 bool 176 spdk_env_core_get_smt_cpuset(struct spdk_cpuset *cpuset, uint32_t core) 177 { 178 uint32_t i; 179 180 spdk_cpuset_zero(cpuset); 181 182 if (core != UINT32_MAX) { 183 return env_core_get_smt_cpuset(cpuset, core); 184 } 185 186 SPDK_ENV_FOREACH_CORE(i) { 187 if (!env_core_get_smt_cpuset(cpuset, i)) { 188 return false; 189 } 190 } 191 192 return true; 193 } 194 195 int 196 spdk_env_thread_launch_pinned(uint32_t core, thread_start_fn fn, void *arg) 197 { 198 int rc; 199 200 rc = rte_eal_remote_launch(fn, arg, core); 201 202 return rc; 203 } 204 205 void 206 spdk_env_thread_wait_all(void) 207 { 208 rte_eal_mp_wait_lcore(); 209 } 210