net/sfc: reserve queues for port representors
[dpdk.git] / drivers / net / sfc / sfc_repr_proxy.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  *
3  * Copyright(c) 2019-2021 Xilinx, Inc.
4  * Copyright(c) 2019 Solarflare Communications Inc.
5  *
6  * This software was jointly developed between OKTET Labs (under contract
7  * for Solarflare) and Solarflare Communications, Inc.
8  */
9
10 #include <rte_service.h>
11 #include <rte_service_component.h>
12
13 #include "sfc_log.h"
14 #include "sfc_service.h"
15 #include "sfc_repr_proxy.h"
16 #include "sfc.h"
17
18 static int32_t
19 sfc_repr_proxy_routine(void *arg)
20 {
21         struct sfc_repr_proxy *rp = arg;
22
23         /* Representor proxy boilerplate will be here */
24         RTE_SET_USED(rp);
25
26         return 0;
27 }
28
29 int
30 sfc_repr_proxy_attach(struct sfc_adapter *sa)
31 {
32         struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
33         struct sfc_repr_proxy *rp = &sa->repr_proxy;
34         struct rte_service_spec service;
35         uint32_t cid;
36         uint32_t sid;
37         int rc;
38
39         sfc_log_init(sa, "entry");
40
41         if (!sfc_repr_available(sas)) {
42                 sfc_log_init(sa, "representors not supported - skip");
43                 return 0;
44         }
45
46         cid = sfc_get_service_lcore(sa->socket_id);
47         if (cid == RTE_MAX_LCORE && sa->socket_id != SOCKET_ID_ANY) {
48                 /* Warn and try to allocate on any NUMA node */
49                 sfc_warn(sa,
50                         "repr proxy: unable to get service lcore at socket %d",
51                         sa->socket_id);
52
53                 cid = sfc_get_service_lcore(SOCKET_ID_ANY);
54         }
55         if (cid == RTE_MAX_LCORE) {
56                 rc = ENOTSUP;
57                 sfc_err(sa, "repr proxy: failed to get service lcore");
58                 goto fail_get_service_lcore;
59         }
60
61         memset(&service, 0, sizeof(service));
62         snprintf(service.name, sizeof(service.name),
63                  "net_sfc_%hu_repr_proxy", sfc_sa2shared(sa)->port_id);
64         service.socket_id = rte_lcore_to_socket_id(cid);
65         service.callback = sfc_repr_proxy_routine;
66         service.callback_userdata = rp;
67
68         rc = rte_service_component_register(&service, &sid);
69         if (rc != 0) {
70                 rc = ENOEXEC;
71                 sfc_err(sa, "repr proxy: failed to register service component");
72                 goto fail_register;
73         }
74
75         rc = rte_service_map_lcore_set(sid, cid, 1);
76         if (rc != 0) {
77                 rc = -rc;
78                 sfc_err(sa, "repr proxy: failed to map lcore");
79                 goto fail_map_lcore;
80         }
81
82         rp->service_core_id = cid;
83         rp->service_id = sid;
84
85         sfc_log_init(sa, "done");
86
87         return 0;
88
89 fail_map_lcore:
90         rte_service_component_unregister(sid);
91
92 fail_register:
93         /*
94          * No need to rollback service lcore get since
95          * it just makes socket_id based search and remembers it.
96          */
97
98 fail_get_service_lcore:
99         sfc_log_init(sa, "failed: %s", rte_strerror(rc));
100         return rc;
101 }
102
103 void
104 sfc_repr_proxy_detach(struct sfc_adapter *sa)
105 {
106         struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
107         struct sfc_repr_proxy *rp = &sa->repr_proxy;
108
109         sfc_log_init(sa, "entry");
110
111         if (!sfc_repr_available(sas)) {
112                 sfc_log_init(sa, "representors not supported - skip");
113                 return;
114         }
115
116         rte_service_map_lcore_set(rp->service_id, rp->service_core_id, 0);
117         rte_service_component_unregister(rp->service_id);
118
119         sfc_log_init(sa, "done");
120 }
121
122 int
123 sfc_repr_proxy_start(struct sfc_adapter *sa)
124 {
125         struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
126         struct sfc_repr_proxy *rp = &sa->repr_proxy;
127         int rc;
128
129         sfc_log_init(sa, "entry");
130
131         /*
132          * The condition to start the proxy is insufficient. It will be
133          * complemented with representor port start/stop support.
134          */
135         if (!sfc_repr_available(sas)) {
136                 sfc_log_init(sa, "representors not supported - skip");
137                 return 0;
138         }
139
140         /* Service core may be in "stopped" state, start it */
141         rc = rte_service_lcore_start(rp->service_core_id);
142         if (rc != 0 && rc != -EALREADY) {
143                 rc = -rc;
144                 sfc_err(sa, "failed to start service core for %s: %s",
145                         rte_service_get_name(rp->service_id),
146                         rte_strerror(rc));
147                 goto fail_start_core;
148         }
149
150         /* Run the service */
151         rc = rte_service_component_runstate_set(rp->service_id, 1);
152         if (rc < 0) {
153                 rc = -rc;
154                 sfc_err(sa, "failed to run %s component: %s",
155                         rte_service_get_name(rp->service_id),
156                         rte_strerror(rc));
157                 goto fail_component_runstate_set;
158         }
159         rc = rte_service_runstate_set(rp->service_id, 1);
160         if (rc < 0) {
161                 rc = -rc;
162                 sfc_err(sa, "failed to run %s: %s",
163                         rte_service_get_name(rp->service_id),
164                         rte_strerror(rc));
165                 goto fail_runstate_set;
166         }
167
168         sfc_log_init(sa, "done");
169
170         return 0;
171
172 fail_runstate_set:
173         rte_service_component_runstate_set(rp->service_id, 0);
174
175 fail_component_runstate_set:
176         /* Service lcore may be shared and we never stop it */
177
178 fail_start_core:
179         sfc_log_init(sa, "failed: %s", rte_strerror(rc));
180         return rc;
181 }
182
183 void
184 sfc_repr_proxy_stop(struct sfc_adapter *sa)
185 {
186         struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
187         struct sfc_repr_proxy *rp = &sa->repr_proxy;
188         int rc;
189
190         sfc_log_init(sa, "entry");
191
192         if (!sfc_repr_available(sas)) {
193                 sfc_log_init(sa, "representors not supported - skip");
194                 return;
195         }
196
197         rc = rte_service_runstate_set(rp->service_id, 0);
198         if (rc < 0) {
199                 sfc_err(sa, "failed to stop %s: %s",
200                         rte_service_get_name(rp->service_id),
201                         rte_strerror(-rc));
202         }
203
204         rc = rte_service_component_runstate_set(rp->service_id, 0);
205         if (rc < 0) {
206                 sfc_err(sa, "failed to stop %s component: %s",
207                         rte_service_get_name(rp->service_id),
208                         rte_strerror(-rc));
209         }
210
211         /* Service lcore may be shared and we never stop it */
212
213         sfc_log_init(sa, "done");
214 }