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 RybchenkoRTE_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 Rybchenkosfc_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 Rybchenkosfc_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