net/i40e: fix Rx packet statistics
[dpdk.git] / drivers / net / sfc / sfc_service.c
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
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
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
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 }