1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2015 Intel Corporation
10 #include <rte_lcore.h>
12 #include "cpu_core_map.h"
15 uint32_t n_max_sockets;
16 uint32_t n_max_cores_per_socket;
17 uint32_t n_max_ht_per_core;
19 uint32_t n_cores_per_socket;
20 uint32_t n_ht_per_core;
24 static inline uint32_t
25 cpu_core_map_pos(struct cpu_core_map *map,
30 return (socket_id * map->n_max_cores_per_socket + core_id) *
31 map->n_max_ht_per_core + ht_id;
35 cpu_core_map_compute_eal(struct cpu_core_map *map);
38 cpu_core_map_compute_linux(struct cpu_core_map *map);
41 cpu_core_map_compute_and_check(struct cpu_core_map *map);
44 cpu_core_map_init(uint32_t n_max_sockets,
45 uint32_t n_max_cores_per_socket,
46 uint32_t n_max_ht_per_core,
47 uint32_t eal_initialized)
49 uint32_t map_size, map_mem_size, i;
50 struct cpu_core_map *map;
53 /* Check input arguments */
54 if ((n_max_sockets == 0) ||
55 (n_max_cores_per_socket == 0) ||
56 (n_max_ht_per_core == 0))
59 /* Memory allocation */
60 map_size = n_max_sockets * n_max_cores_per_socket * n_max_ht_per_core;
61 map_mem_size = sizeof(struct cpu_core_map) + map_size * sizeof(int);
62 map = (struct cpu_core_map *) malloc(map_mem_size);
67 map->n_max_sockets = n_max_sockets;
68 map->n_max_cores_per_socket = n_max_cores_per_socket;
69 map->n_max_ht_per_core = n_max_ht_per_core;
71 map->n_cores_per_socket = 0;
72 map->n_ht_per_core = 0;
74 for (i = 0; i < map_size; i++)
77 status = (eal_initialized) ?
78 cpu_core_map_compute_eal(map) :
79 cpu_core_map_compute_linux(map);
86 status = cpu_core_map_compute_and_check(map);
96 cpu_core_map_compute_eal(struct cpu_core_map *map)
98 uint32_t socket_id, core_id, ht_id;
101 for (socket_id = 0; socket_id < map->n_max_sockets; socket_id++) {
102 uint32_t n_detected, core_id_contig;
106 for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
107 struct lcore_config *p = &lcore_config[lcore_id];
109 if ((p->detected) && (p->socket_id == socket_id))
115 for (core_id = 0; n_detected ; core_id++) {
119 lcore_id < RTE_MAX_LCORE;
121 struct lcore_config *p =
122 &lcore_config[lcore_id];
125 (p->socket_id == socket_id) &&
126 (p->core_id == core_id)) {
127 uint32_t pos = cpu_core_map_pos(map,
132 map->map[pos] = lcore_id;
140 if (core_id_contig ==
141 map->n_max_cores_per_socket)
151 cpu_core_map_compute_and_check(struct cpu_core_map *map)
153 uint32_t socket_id, core_id, ht_id;
155 /* Compute n_ht_per_core, n_cores_per_socket, n_sockets */
156 for (ht_id = 0; ht_id < map->n_max_ht_per_core; ht_id++) {
157 if (map->map[ht_id] == -1)
160 map->n_ht_per_core++;
163 if (map->n_ht_per_core == 0)
166 for (core_id = 0; core_id < map->n_max_cores_per_socket; core_id++) {
167 uint32_t pos = core_id * map->n_max_ht_per_core;
169 if (map->map[pos] == -1)
172 map->n_cores_per_socket++;
175 if (map->n_cores_per_socket == 0)
178 for (socket_id = 0; socket_id < map->n_max_sockets; socket_id++) {
179 uint32_t pos = socket_id * map->n_max_cores_per_socket *
180 map->n_max_ht_per_core;
182 if (map->map[pos] == -1)
188 if (map->n_sockets == 0)
191 /* Check that each socket has exactly the same number of cores
192 and that each core has exactly the same number of hyper-threads */
193 for (socket_id = 0; socket_id < map->n_sockets; socket_id++) {
194 for (core_id = 0; core_id < map->n_cores_per_socket; core_id++)
196 ht_id < map->n_max_ht_per_core;
198 uint32_t pos = (socket_id *
199 map->n_max_cores_per_socket + core_id) *
200 map->n_max_ht_per_core + ht_id;
202 if (((ht_id < map->n_ht_per_core) &&
203 (map->map[pos] == -1)) ||
204 ((ht_id >= map->n_ht_per_core) &&
205 (map->map[pos] != -1)))
209 for ( ; core_id < map->n_max_cores_per_socket; core_id++)
211 ht_id < map->n_max_ht_per_core;
213 uint32_t pos = cpu_core_map_pos(map,
218 if (map->map[pos] != -1)
226 #define FILE_LINUX_CPU_N_LCORES \
227 "/sys/devices/system/cpu/present"
230 cpu_core_map_get_n_lcores_linux(void)
232 char buffer[64], *string;
235 fd = fopen(FILE_LINUX_CPU_N_LCORES, "r");
239 if (fgets(buffer, sizeof(buffer), fd) == NULL) {
246 string = index(buffer, '-');
250 return atoi(++string) + 1;
253 #define FILE_LINUX_CPU_CORE_ID \
254 "/sys/devices/system/cpu/cpu%" PRIu32 "/topology/core_id"
257 cpu_core_map_get_core_id_linux(int lcore_id)
263 snprintf(buffer, sizeof(buffer), FILE_LINUX_CPU_CORE_ID, lcore_id);
264 fd = fopen(buffer, "r");
268 if (fgets(buffer, sizeof(buffer), fd) == NULL) {
275 core_id = atoi(buffer);
279 #define FILE_LINUX_CPU_SOCKET_ID \
280 "/sys/devices/system/cpu/cpu%" PRIu32 "/topology/physical_package_id"
283 cpu_core_map_get_socket_id_linux(int lcore_id)
289 snprintf(buffer, sizeof(buffer), FILE_LINUX_CPU_SOCKET_ID, lcore_id);
290 fd = fopen(buffer, "r");
294 if (fgets(buffer, sizeof(buffer), fd) == NULL) {
301 socket_id = atoi(buffer);
306 cpu_core_map_compute_linux(struct cpu_core_map *map)
308 uint32_t socket_id, core_id, ht_id;
311 n_lcores = cpu_core_map_get_n_lcores_linux();
316 for (socket_id = 0; socket_id < map->n_max_sockets; socket_id++) {
317 uint32_t n_detected, core_id_contig;
321 for (lcore_id = 0; lcore_id < n_lcores; lcore_id++) {
322 int lcore_socket_id =
323 cpu_core_map_get_socket_id_linux(lcore_id);
325 #if !defined(RTE_ARCH_PPC_64)
326 if (lcore_socket_id < 0)
330 if (((uint32_t) lcore_socket_id) == socket_id)
336 for (core_id = 0; n_detected ; core_id++) {
339 for (lcore_id = 0; lcore_id < n_lcores; lcore_id++) {
340 int lcore_socket_id =
341 cpu_core_map_get_socket_id_linux(
344 #if !defined(RTE_ARCH_PPC_64)
345 if (lcore_socket_id < 0)
349 cpu_core_map_get_core_id_linux(
352 if (lcore_core_id < 0)
356 #if !defined(RTE_ARCH_PPC_64)
357 if (((uint32_t) lcore_socket_id == socket_id) &&
358 ((uint32_t) lcore_core_id == core_id)) {
360 if (((uint32_t) lcore_socket_id == socket_id)) {
362 uint32_t pos = cpu_core_map_pos(map,
367 map->map[pos] = lcore_id;
375 if (core_id_contig ==
376 map->n_max_cores_per_socket)
386 cpu_core_map_print(struct cpu_core_map *map)
388 uint32_t socket_id, core_id, ht_id;
393 for (socket_id = 0; socket_id < map->n_sockets; socket_id++) {
394 printf("Socket %" PRIu32 ":\n", socket_id);
397 core_id < map->n_cores_per_socket;
399 printf("[%" PRIu32 "] = [", core_id);
401 for (ht_id = 0; ht_id < map->n_ht_per_core; ht_id++) {
402 int lcore_id = cpu_core_map_get_lcore_id(map,
407 uint32_t core_id_noncontig =
408 cpu_core_map_get_core_id_linux(
411 printf(" %" PRId32 " (%" PRIu32 ") ",
422 cpu_core_map_get_n_sockets(struct cpu_core_map *map)
427 return map->n_sockets;
431 cpu_core_map_get_n_cores_per_socket(struct cpu_core_map *map)
436 return map->n_cores_per_socket;
440 cpu_core_map_get_n_ht_per_core(struct cpu_core_map *map)
445 return map->n_ht_per_core;
449 cpu_core_map_get_lcore_id(struct cpu_core_map *map,
457 (socket_id >= map->n_sockets) ||
458 (core_id >= map->n_cores_per_socket) ||
459 (ht_id >= map->n_ht_per_core))
462 pos = cpu_core_map_pos(map, socket_id, core_id, ht_id);
464 return map->map[pos];
468 cpu_core_map_free(struct cpu_core_map *map)