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 18static uint32_t sfc_service_lcore[RTE_MAX_NUMA_NODES]; 19static rte_spinlock_t sfc_service_lcore_lock = RTE_SPINLOCK_INITIALIZER; 20 21RTE_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 29static uint32_t 30sfc_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 71uint32_t 72sfc_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