xref: /dpdk/drivers/net/sfc/sfc_service.c (revision 7c041f971ba7dc6a2228834c1aae1707837aae60)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  *
3  * Copyright(c) 2020-2021 Xilinx, Inc.
4  */
5 
6 #include <stdint.h>
7 
8 #include <rte_common.h>
9 #include <rte_spinlock.h>
10 #include <rte_lcore.h>
11 #include <rte_service.h>
12 #include <rte_memory.h>
13 
14 #include "sfc_log.h"
15 #include "sfc_service.h"
16 #include "sfc_debug.h"
17 
18 static uint32_t sfc_service_lcore[RTE_MAX_NUMA_NODES];
19 static rte_spinlock_t sfc_service_lcore_lock = RTE_SPINLOCK_INITIALIZER;
20 
RTE_INIT(sfc_service_lcore_init)21 RTE_INIT(sfc_service_lcore_init)
22 {
23 	size_t i;
24 
25 	for (i = 0; i < RTE_DIM(sfc_service_lcore); ++i)
26 		sfc_service_lcore[i] = RTE_MAX_LCORE;
27 }
28 
29 static uint32_t
sfc_find_service_lcore(int * socket_id)30 sfc_find_service_lcore(int *socket_id)
31 {
32 	uint32_t service_core_list[RTE_MAX_LCORE];
33 	uint32_t lcore_id;
34 	int num;
35 	int i;
36 
37 	SFC_ASSERT(rte_spinlock_is_locked(&sfc_service_lcore_lock));
38 
39 	num = rte_service_lcore_list(service_core_list,
40 				    RTE_DIM(service_core_list));
41 	if (num == 0) {
42 		SFC_GENERIC_LOG(WARNING, "No service cores available");
43 		return RTE_MAX_LCORE;
44 	}
45 	if (num < 0) {
46 		SFC_GENERIC_LOG(ERR, "Failed to get service core list");
47 		return RTE_MAX_LCORE;
48 	}
49 
50 	for (i = 0; i < num; ++i) {
51 		lcore_id = service_core_list[i];
52 
53 		if (*socket_id == SOCKET_ID_ANY) {
54 			*socket_id = rte_lcore_to_socket_id(lcore_id);
55 			break;
56 		} else if (rte_lcore_to_socket_id(lcore_id) ==
57 			   (unsigned int)*socket_id) {
58 			break;
59 		}
60 	}
61 
62 	if (i == num) {
63 		SFC_GENERIC_LOG(WARNING,
64 			"No service cores reserved at socket %d", *socket_id);
65 		return RTE_MAX_LCORE;
66 	}
67 
68 	return lcore_id;
69 }
70 
71 uint32_t
sfc_get_service_lcore(int socket_id)72 sfc_get_service_lcore(int socket_id)
73 {
74 	uint32_t lcore_id = RTE_MAX_LCORE;
75 
76 	rte_spinlock_lock(&sfc_service_lcore_lock);
77 
78 	if (socket_id != SOCKET_ID_ANY) {
79 		lcore_id = sfc_service_lcore[socket_id];
80 	} else {
81 		size_t i;
82 
83 		for (i = 0; i < RTE_DIM(sfc_service_lcore); ++i) {
84 			if (sfc_service_lcore[i] != RTE_MAX_LCORE) {
85 				lcore_id = sfc_service_lcore[i];
86 				break;
87 			}
88 		}
89 	}
90 
91 	if (lcore_id == RTE_MAX_LCORE) {
92 		lcore_id = sfc_find_service_lcore(&socket_id);
93 		if (lcore_id != RTE_MAX_LCORE)
94 			sfc_service_lcore[socket_id] = lcore_id;
95 	}
96 
97 	rte_spinlock_unlock(&sfc_service_lcore_lock);
98 	return lcore_id;
99 }
100