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