FD.io VPP  v17.07.01-10-g3be13f0
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/unix/physmem.h>
24 #include <vlib/pci/pci.h>
25 
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <unistd.h>
29 #include <sys/stat.h>
30 #include <sys/mount.h>
31 #include <string.h>
32 #include <fcntl.h>
33 
34 #include <dpdk/device/dpdk_priv.h>
35 
36 #include <vlibapi/api.h>
37 #include <vlibmemory/api.h>
38 
39 /* define message IDs */
40 #include <dpdk/api/dpdk_msg_enum.h>
41 
42 #define vl_typedefs /* define message structures */
44 #undef vl_typedefs
45 
46 #define vl_endianfun /* define message structures */
48 #undef vl_endianfun
49 
50 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
51 
52 /* Get the API version number. */
53 #define vl_api_version(n,v) static u32 api_version=(v);
55 #undef vl_api_version
56 
57 /* Macro to finish up custom dump fns */
58 #define FINISH \
59  vec_add1 (s, 0); \
60  vl_print (handle, (char *)s); \
61  vec_free (s); \
62  return handle;
63 
65 
66 static void
69 {
70  vl_api_sw_interface_set_dpdk_hqos_pipe_reply_t *rmp;
71  int rv = 0;
72 
73  dpdk_main_t *dm = &dpdk_main;
74  dpdk_device_t *xd;
75 
76  u32 sw_if_index = ntohl (mp->sw_if_index);
77  u32 subport = ntohl (mp->subport);
78  u32 pipe = ntohl (mp->pipe);
79  u32 profile = ntohl (mp->profile);
81 
83 
84  /* hw_if & dpdk device */
85  hw = vnet_get_sup_hw_interface (dm->vnet_main, sw_if_index);
86 
87  xd = vec_elt_at_index (dm->devices, hw->dev_instance);
88 
89  rv = rte_sched_pipe_config (xd->hqos_ht->hqos, subport, pipe, profile);
90 
92 
93  REPLY_MACRO (VL_API_SW_INTERFACE_SET_DPDK_HQOS_PIPE_REPLY);
94 }
95 
98 {
99  u8 *s;
100 
101  s = format (0, "SCRIPT: sw_interface_set_dpdk_hqos_pipe ");
102 
103  s = format (s, "sw_if_index %u ", ntohl (mp->sw_if_index));
104 
105  s = format (s, "subport %u pipe %u profile %u ",
106  ntohl (mp->subport), ntohl (mp->pipe), ntohl (mp->profile));
107 
108  FINISH;
109 }
110 
111 static void
114 {
115  vl_api_sw_interface_set_dpdk_hqos_subport_reply_t *rmp;
116  int rv = 0;
117 
118  dpdk_main_t *dm = &dpdk_main;
119  dpdk_device_t *xd;
120  struct rte_sched_subport_params p;
121 
122  u32 sw_if_index = ntohl (mp->sw_if_index);
123  u32 subport = ntohl (mp->subport);
124  p.tb_rate = ntohl (mp->tb_rate);
125  p.tb_size = ntohl (mp->tb_size);
126  p.tc_rate[0] = ntohl (mp->tc_rate[0]);
127  p.tc_rate[1] = ntohl (mp->tc_rate[1]);
128  p.tc_rate[2] = ntohl (mp->tc_rate[2]);
129  p.tc_rate[3] = ntohl (mp->tc_rate[3]);
130  p.tc_period = ntohl (mp->tc_period);
131 
133 
135 
136  /* hw_if & dpdk device */
137  hw = vnet_get_sup_hw_interface (dm->vnet_main, sw_if_index);
138 
139  xd = vec_elt_at_index (dm->devices, hw->dev_instance);
140 
141  rv = rte_sched_subport_config (xd->hqos_ht->hqos, subport, &p);
142 
144 
145  REPLY_MACRO (VL_API_SW_INTERFACE_SET_DPDK_HQOS_SUBPORT_REPLY);
146 }
147 
150 {
151  u8 *s;
152 
153  s = format (0, "SCRIPT: sw_interface_set_dpdk_hqos_subport ");
154 
155  s = format (s, "sw_if_index %u ", ntohl (mp->sw_if_index));
156 
157  s =
158  format (s,
159  "subport %u rate %u bkt_size %u tc0 %u tc1 %u tc2 %u tc3 %u period %u",
160  ntohl (mp->subport), ntohl (mp->tb_rate), ntohl (mp->tb_size),
161  ntohl (mp->tc_rate[0]), ntohl (mp->tc_rate[1]),
162  ntohl (mp->tc_rate[2]), ntohl (mp->tc_rate[3]),
163  ntohl (mp->tc_period));
164 
165  FINISH;
166 }
167 
168 static void
171 {
172  vl_api_sw_interface_set_dpdk_hqos_tctbl_reply_t *rmp;
173  int rv = 0;
174 
175  dpdk_main_t *dm = &dpdk_main;
177  dpdk_device_t *xd;
178 
179  u32 sw_if_index = ntohl (mp->sw_if_index);
180  u32 entry = ntohl (mp->entry);
181  u32 tc = ntohl (mp->tc);
182  u32 queue = ntohl (mp->queue);
183  u32 val, i;
184 
186 
188 
189  /* hw_if & dpdk device */
190  hw = vnet_get_sup_hw_interface (dm->vnet_main, sw_if_index);
191 
192  xd = vec_elt_at_index (dm->devices, hw->dev_instance);
193 
194  if (tc >= RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE)
195  {
196  clib_warning ("invalid traffic class !!");
197  rv = VNET_API_ERROR_INVALID_VALUE;
198  goto done;
199  }
200  if (queue >= RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS)
201  {
202  clib_warning ("invalid queue !!");
203  rv = VNET_API_ERROR_INVALID_VALUE;
204  goto done;
205  }
206 
207  /* Detect the set of worker threads */
208  uword *p = hash_get_mem (tm->thread_registrations_by_name, "workers");
209 
210  if (p == 0)
211  {
212  clib_warning ("worker thread registration AWOL !!");
213  rv = VNET_API_ERROR_INVALID_VALUE_2;
214  goto done;
215  }
216 
218  int worker_thread_first = tr->first_index;
219  int worker_thread_count = tr->count;
220 
221  val = tc * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS + queue;
222  for (i = 0; i < worker_thread_count; i++)
223  xd->hqos_wt[worker_thread_first + i].hqos_tc_table[entry] = val;
224 
226 done:
227 
228  REPLY_MACRO (VL_API_SW_INTERFACE_SET_DPDK_HQOS_TCTBL_REPLY);
229 }
230 
233 {
234  u8 *s;
235 
236  s = format (0, "SCRIPT: sw_interface_set_dpdk_hqos_tctbl ");
237 
238  s = format (s, "sw_if_index %u ", ntohl (mp->sw_if_index));
239 
240  s = format (s, "entry %u tc %u queue %u",
241  ntohl (mp->entry), ntohl (mp->tc), ntohl (mp->queue));
242 
243  FINISH;
244 }
245 
246 #define foreach_dpdk_plugin_api_msg \
247 _(SW_INTERFACE_SET_DPDK_HQOS_PIPE, sw_interface_set_dpdk_hqos_pipe) \
248 _(SW_INTERFACE_SET_DPDK_HQOS_SUBPORT, sw_interface_set_dpdk_hqos_subport) \
249 _(SW_INTERFACE_SET_DPDK_HQOS_TCTBL, sw_interface_set_dpdk_hqos_tctbl)
250 
251 /* Set up the API message handling tables */
252 static clib_error_t *
254 {
255  dpdk_main_t *dm __attribute__ ((unused)) = &dpdk_main;
256 #define _(N,n) \
257  vl_msg_api_set_handlers((VL_API_##N + dm->msg_id_base), \
258  #n, \
259  vl_api_##n##_t_handler, \
260  vl_noop_handler, \
261  vl_api_##n##_t_endian, \
262  vl_api_##n##_t_print, \
263  sizeof(vl_api_##n##_t), 1);
265 #undef _
266  return 0;
267 }
268 
269 #define vl_msg_name_crc_list
270 #include <dpdk/api/dpdk_all_api_h.h>
271 #undef vl_msg_name_crc_list
272 
273 static void
275 {
276 #define _(id,n,crc) \
277  vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id + dm->msg_id_base);
278  foreach_vl_msg_name_crc_dpdk;
279 #undef _
280 }
281 
282 // TODO
283 /*
284 static void plugin_custom_dump_configure (dpdk_main_t * dm)
285 {
286 #define _(n,f) dm->api_main->msg_print_handlers \
287  [VL_API_##n + dm->msg_id_base] \
288  = (void *) vl_api_##f##_t_print;
289  foreach_dpdk_plugin_api_msg;
290 #undef _
291 }
292 */
293 /* force linker to link functions used by vlib and declared weak */
294 
295 static clib_error_t *
297 {
298  dpdk_main_t *dm = &dpdk_main;
299  clib_error_t *error = 0;
300 
301  /* init CLI */
302  if ((error = vlib_call_init_function (vm, dpdk_init)))
303  return error;
304 
305  u8 *name;
306  name = format (0, "dpdk_%08x%c", api_version, 0);
307 
308  /* Ask for a correctly-sized block of API message decode slots */
310  ((char *) name, VL_MSG_FIRST_AVAILABLE);
311  vec_free (name);
312 
313  error = dpdk_plugin_api_hookup (vm);
314 
315  /* Add our API messages to the global name_crc hash table */
317 
318 // TODO
319 // plugin_custom_dump_configure (dm);
320 
321  return error;
322 }
323 
325 
326 
327 /*
328  * fd.io coding-style-patch-verification: ON
329  *
330  * Local Variables:
331  * eval: (c-set-style "gnu")
332  * End:
333  */
DPDK interface HQoS subport parameters set request.
Definition: dpdk.api:43
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:170
static void setup_message_id_table(dpdk_main_t *dm, api_main_t *am)
Definition: dpdk_api.c:274
u16 vl_msg_api_get_msg_ids(const char *name, int n)
Definition: api_shared.c:837
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:232
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:337
static clib_error_t * dpdk_plugin_api_hookup(vlib_main_t *vm)
Definition: dpdk_api.c:253
dpdk_main_t dpdk_main
Definition: init.c:36
static vnet_hw_interface_t * vnet_get_sup_hw_interface(vnet_main_t *vnm, u32 sw_if_index)
static clib_error_t * dpdk_api_init(vlib_main_t *vm)
Definition: dpdk_api.c:296
struct rte_sched_port * hqos
Definition: dpdk.h:137
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:111
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
#define vlib_call_init_function(vm, x)
Definition: init.h:162
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:113
dpdk_device_hqos_per_worker_thread_t * hqos_wt
Definition: dpdk.h:197
static clib_error_t * dpdk_init(vlib_main_t *vm)
Definition: init.c:1516
#define REPLY_MACRO(t)
#define BAD_SW_IF_INDEX_LABEL
api_main_t api_main
Definition: api_shared.c:35
dpdk_device_t * devices
Definition: dpdk.h:337
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:97
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:340
DPDK interface HQoS tctbl entry set request.
Definition: dpdk.api:62
#define clib_warning(format, args...)
Definition: error.h:59
#define foreach_dpdk_plugin_api_msg
Definition: dpdk_api.c:246
#define FINISH
Definition: dpdk_api.c:58
unsigned int u32
Definition: types.h:88
Bitmaps built as vectors of machine words.
dpdk_device_hqos_per_hqos_thread_t * hqos_ht
Definition: dpdk.h:198
uword * thread_registrations_by_name
Definition: threads.h:261
u64 uword
Definition: types.h:112
unsigned char u8
Definition: types.h:56
#define hash_get_mem(h, key)
Definition: hash.h:268
static vlib_thread_main_t * vlib_get_thread_main()
Definition: global_funcs.h:32
DPDK interface HQoS pipe profile set request.
Definition: dpdk.api:24
u16 msg_id_base
Definition: dpdk.h:390
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:68
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:149
vnet_main_t * vnet_main
Definition: dpdk.h:383
CLIB vectors are ubiquitous dynamically resized arrays with by user defined "headers".
#define VALIDATE_SW_IF_INDEX(mp)