FD.io VPP  v19.08.3-2-gbabecb413
Vector Packet Processing
dpdk_api.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include <vnet/vnet.h>
16 #include <vppinfra/vec.h>
17 #include <vppinfra/error.h>
18 #include <vppinfra/format.h>
19 #include <vppinfra/bitmap.h>
20 
21 #include <vnet/ethernet/ethernet.h>
22 #include <dpdk/device/dpdk.h>
23 #include <vlib/pci/pci.h>
24 
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <unistd.h>
28 #include <sys/stat.h>
29 #include <sys/mount.h>
30 #include <string.h>
31 #include <fcntl.h>
32 
33 #include <dpdk/device/dpdk_priv.h>
34 
35 #include <vlibapi/api.h>
36 #include <vlibmemory/api.h>
37 
38 /* define message IDs */
39 #include <dpdk/api/dpdk_msg_enum.h>
40 
41 #define vl_typedefs /* define message structures */
43 #undef vl_typedefs
44 
45 #define vl_endianfun /* define message structures */
47 #undef vl_endianfun
48 
49 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
50 
51 /* Get the API version number. */
52 #define vl_api_version(n,v) static u32 api_version=(v);
54 #undef vl_api_version
55 
56 /* Macro to finish up custom dump fns */
57 #define FINISH \
58  vec_add1 (s, 0); \
59  vl_print (handle, (char *)s); \
60  vec_free (s); \
61  return handle;
62 
64 
65 static void
68 {
69  vl_api_sw_interface_set_dpdk_hqos_pipe_reply_t *rmp;
70  int rv = 0;
71 
72  dpdk_main_t *dm = &dpdk_main;
73  dpdk_device_t *xd;
74 
75  u32 sw_if_index = ntohl (mp->sw_if_index);
76  u32 subport = ntohl (mp->subport);
77  u32 pipe = ntohl (mp->pipe);
78  u32 profile = ntohl (mp->profile);
80 
82 
83  /* hw_if & dpdk device */
84  hw = vnet_get_sup_hw_interface (dm->vnet_main, sw_if_index);
85 
86  xd = vec_elt_at_index (dm->devices, hw->dev_instance);
87 
88  rv = rte_sched_pipe_config (xd->hqos_ht->hqos, subport, pipe, profile);
89 
91 
92  REPLY_MACRO (VL_API_SW_INTERFACE_SET_DPDK_HQOS_PIPE_REPLY);
93 }
94 
97 {
98  u8 *s;
99 
100  s = format (0, "SCRIPT: sw_interface_set_dpdk_hqos_pipe ");
101 
102  s = format (s, "sw_if_index %u ", ntohl (mp->sw_if_index));
103 
104  s = format (s, "subport %u pipe %u profile %u ",
105  ntohl (mp->subport), ntohl (mp->pipe), ntohl (mp->profile));
106 
107  FINISH;
108 }
109 
110 static void
113 {
114  vl_api_sw_interface_set_dpdk_hqos_subport_reply_t *rmp;
115  int rv = 0;
116 
117  dpdk_main_t *dm = &dpdk_main;
118  dpdk_device_t *xd;
119  struct rte_sched_subport_params p;
120 
121  u32 sw_if_index = ntohl (mp->sw_if_index);
122  u32 subport = ntohl (mp->subport);
123  p.tb_rate = ntohl (mp->tb_rate);
124  p.tb_size = ntohl (mp->tb_size);
125  p.tc_rate[0] = ntohl (mp->tc_rate[0]);
126  p.tc_rate[1] = ntohl (mp->tc_rate[1]);
127  p.tc_rate[2] = ntohl (mp->tc_rate[2]);
128  p.tc_rate[3] = ntohl (mp->tc_rate[3]);
129  p.tc_period = ntohl (mp->tc_period);
130 
132 
134 
135  /* hw_if & dpdk device */
136  hw = vnet_get_sup_hw_interface (dm->vnet_main, sw_if_index);
137 
138  xd = vec_elt_at_index (dm->devices, hw->dev_instance);
139 
140  rv = rte_sched_subport_config (xd->hqos_ht->hqos, subport, &p);
141 
143 
144  REPLY_MACRO (VL_API_SW_INTERFACE_SET_DPDK_HQOS_SUBPORT_REPLY);
145 }
146 
149 {
150  u8 *s;
151 
152  s = format (0, "SCRIPT: sw_interface_set_dpdk_hqos_subport ");
153 
154  s = format (s, "sw_if_index %u ", ntohl (mp->sw_if_index));
155 
156  s =
157  format (s,
158  "subport %u rate %u bkt_size %u tc0 %u tc1 %u tc2 %u tc3 %u period %u",
159  ntohl (mp->subport), ntohl (mp->tb_rate), ntohl (mp->tb_size),
160  ntohl (mp->tc_rate[0]), ntohl (mp->tc_rate[1]),
161  ntohl (mp->tc_rate[2]), ntohl (mp->tc_rate[3]),
162  ntohl (mp->tc_period));
163 
164  FINISH;
165 }
166 
167 static void
170 {
171  vl_api_sw_interface_set_dpdk_hqos_tctbl_reply_t *rmp;
172  int rv = 0;
173 
174  dpdk_main_t *dm = &dpdk_main;
176  dpdk_device_t *xd;
177 
178  u32 sw_if_index = ntohl (mp->sw_if_index);
179  u32 entry = ntohl (mp->entry);
180  u32 tc = ntohl (mp->tc);
181  u32 queue = ntohl (mp->queue);
182  u32 val, i;
183 
185 
187 
188  /* hw_if & dpdk device */
189  hw = vnet_get_sup_hw_interface (dm->vnet_main, sw_if_index);
190 
191  xd = vec_elt_at_index (dm->devices, hw->dev_instance);
192 
193  if (tc >= RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE)
194  {
195  clib_warning ("invalid traffic class !!");
196  rv = VNET_API_ERROR_INVALID_VALUE;
197  goto done;
198  }
199  if (queue >= RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS)
200  {
201  clib_warning ("invalid queue !!");
202  rv = VNET_API_ERROR_INVALID_VALUE;
203  goto done;
204  }
205 
206  /* Detect the set of worker threads */
207  uword *p = hash_get_mem (tm->thread_registrations_by_name, "workers");
208 
209  if (p == 0)
210  {
211  clib_warning ("worker thread registration AWOL !!");
212  rv = VNET_API_ERROR_INVALID_VALUE_2;
213  goto done;
214  }
215 
217  int worker_thread_first = tr->first_index;
218  int worker_thread_count = tr->count;
219 
220  val = tc * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS + queue;
221  for (i = 0; i < worker_thread_count; i++)
222  xd->hqos_wt[worker_thread_first + i].hqos_tc_table[entry] = val;
223 
225 done:
226 
227  REPLY_MACRO (VL_API_SW_INTERFACE_SET_DPDK_HQOS_TCTBL_REPLY);
228 }
229 
232 {
233  u8 *s;
234 
235  s = format (0, "SCRIPT: sw_interface_set_dpdk_hqos_tctbl ");
236 
237  s = format (s, "sw_if_index %u ", ntohl (mp->sw_if_index));
238 
239  s = format (s, "entry %u tc %u queue %u",
240  ntohl (mp->entry), ntohl (mp->tc), ntohl (mp->queue));
241 
242  FINISH;
243 }
244 
245 #define foreach_dpdk_plugin_api_msg \
246 _(SW_INTERFACE_SET_DPDK_HQOS_PIPE, sw_interface_set_dpdk_hqos_pipe) \
247 _(SW_INTERFACE_SET_DPDK_HQOS_SUBPORT, sw_interface_set_dpdk_hqos_subport) \
248 _(SW_INTERFACE_SET_DPDK_HQOS_TCTBL, sw_interface_set_dpdk_hqos_tctbl)
249 
250 /* Set up the API message handling tables */
251 static clib_error_t *
253 {
254  dpdk_main_t *dm __attribute__ ((unused)) = &dpdk_main;
255 #define _(N,n) \
256  vl_msg_api_set_handlers((VL_API_##N + dm->msg_id_base), \
257  #n, \
258  vl_api_##n##_t_handler, \
259  vl_noop_handler, \
260  vl_api_##n##_t_endian, \
261  vl_api_##n##_t_print, \
262  sizeof(vl_api_##n##_t), 1);
264 #undef _
265  return 0;
266 }
267 
268 #define vl_msg_name_crc_list
269 #include <dpdk/api/dpdk_all_api_h.h>
270 #undef vl_msg_name_crc_list
271 
272 static void
274 {
275 #define _(id,n,crc) \
276  vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id + dm->msg_id_base);
277  foreach_vl_msg_name_crc_dpdk;
278 #undef _
279 }
280 
281 // TODO
282 /*
283 static void plugin_custom_dump_configure (dpdk_main_t * dm)
284 {
285 #define _(n,f) dm->api_main->msg_print_handlers \
286  [VL_API_##n + dm->msg_id_base] \
287  = (void *) vl_api_##f##_t_print;
288  foreach_dpdk_plugin_api_msg;
289 #undef _
290 }
291 */
292 /* force linker to link functions used by vlib and declared weak */
293 
294 static clib_error_t *
296 {
297  dpdk_main_t *dm = &dpdk_main;
298  clib_error_t *error = 0;
299 
300  u8 *name;
301  name = format (0, "dpdk_%08x%c", api_version, 0);
302 
303  /* Ask for a correctly-sized block of API message decode slots */
305  ((char *) name, VL_MSG_FIRST_AVAILABLE);
306  vec_free (name);
307 
308  error = dpdk_plugin_api_hookup (vm);
309 
310  /* Add our API messages to the global name_crc hash table */
312 
313 // TODO
314 // plugin_custom_dump_configure (dm);
315 
316  return error;
317 }
318 
319 /* *INDENT-OFF* */
321 {
322  .runs_after = VLIB_INITS ("dpdk_init"),
323 /* *INDENT-OFF* */
324 
325 /*
326  * fd.io coding-style-patch-verification: ON
327  *
328  * Local Variables:
329  * eval: (c-set-style "gnu")
330  * End:
331  */
DPDK interface HQoS subport parameters set request.
Definition: dpdk.api:45
static void vl_api_sw_interface_set_dpdk_hqos_tctbl_t_handler(vl_api_sw_interface_set_dpdk_hqos_tctbl_t *mp)
Definition: dpdk_api.c:169
static void setup_message_id_table(dpdk_main_t *dm, api_main_t *am)
Definition: dpdk_api.c:273
static void * vl_api_sw_interface_set_dpdk_hqos_tctbl_t_print(vl_api_sw_interface_set_dpdk_hqos_tctbl_t *mp, void *handle)
Definition: dpdk_api.c:231
static clib_error_t * dpdk_plugin_api_hookup(vlib_main_t *vm)
Definition: dpdk_api.c:252
dpdk_main_t dpdk_main
Definition: init.c:45
static vnet_hw_interface_t * vnet_get_sup_hw_interface(vnet_main_t *vnm, u32 sw_if_index)
Optimized string handling code, including c11-compliant "safe C library" variants.
static clib_error_t * dpdk_api_init(vlib_main_t *vm)
Definition: dpdk_api.c:295
int i
struct rte_sched_port * hqos
Definition: dpdk.h:147
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
unsigned char u8
Definition: types.h:56
vl_api_interface_index_t sw_if_index
Definition: gre.api:50
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:173
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
unsigned int u32
Definition: types.h:88
static void vl_api_sw_interface_set_dpdk_hqos_subport_t_handler(vl_api_sw_interface_set_dpdk_hqos_subport_t *mp)
Definition: dpdk_api.c:112
dpdk_device_hqos_per_worker_thread_t * hqos_wt
Definition: dpdk.h:238
#define REPLY_MACRO(t)
u8 name[64]
Definition: memclnt.api:152
API main structure, used by both vpp and binary API clients.
Definition: api_common.h:203
#define BAD_SW_IF_INDEX_LABEL
dpdk_device_t * devices
Definition: dpdk.h:396
vlib_main_t * vm
Definition: buffer.c:323
static void * vl_api_sw_interface_set_dpdk_hqos_pipe_t_print(vl_api_sw_interface_set_dpdk_hqos_pipe_t *mp, void *handle)
Definition: dpdk_api.c:96
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:341
DPDK interface HQoS tctbl entry set request.
Definition: dpdk.api:64
#define clib_warning(format, args...)
Definition: error.h:59
#define foreach_dpdk_plugin_api_msg
Definition: dpdk_api.c:245
#define FINISH
Definition: dpdk_api.c:57
Bitmaps built as vectors of machine words.
dpdk_device_hqos_per_hqos_thread_t * hqos_ht
Definition: dpdk.h:239
uword * thread_registrations_by_name
Definition: threads.h:294
u64 uword
Definition: types.h:112
#define hash_get_mem(h, key)
Definition: hash.h:269
static vlib_thread_main_t * vlib_get_thread_main()
Definition: global_funcs.h:32
DPDK interface HQoS pipe profile set request.
Definition: dpdk.api:26
u16 msg_id_base
Definition: dpdk.h:423
static void vl_api_sw_interface_set_dpdk_hqos_pipe_t_handler(vl_api_sw_interface_set_dpdk_hqos_pipe_t *mp)
Definition: dpdk_api.c:67
static void * vl_api_sw_interface_set_dpdk_hqos_subport_t_print(vl_api_sw_interface_set_dpdk_hqos_subport_t *mp, void *handle)
Definition: dpdk_api.c:148
vnet_main_t * vnet_main
Definition: dpdk.h:419
api_main_t api_main
Definition: api_shared.c:35
#define VLIB_INITS(...)
Definition: init.h:344
CLIB vectors are ubiquitous dynamically resized arrays with by user defined "headers".
#define VALIDATE_SW_IF_INDEX(mp)
u16 vl_msg_api_get_msg_ids(const char *name, int n)
Definition: api_shared.c:957