xref: /spdk/lib/env_dpdk/threads.c (revision 479507e8f0795f09bd5166900f54c3bf0d26c91e)
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