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