FD.io VPP  v16.12-rc0-308-g931be3a
Vector Packet Processing
cli.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 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/xxhash.h>
20 
21 #include <vnet/ethernet/ethernet.h>
22 #include <vnet/devices/dpdk/dpdk.h>
24 #include <vnet/mpls/packet.h>
25 
26 #include "dpdk_priv.h"
27 
28 static clib_error_t *
30  unformat_input_t * input, vlib_cli_command_t * cmd)
31 {
32  dpdk_main_t *dm = &dpdk_main;
33  u8 *filename;
34  u32 max;
35  int matched = 0;
36  clib_error_t *error = 0;
37 
39  {
40  if (unformat (input, "on"))
41  {
42  if (dm->tx_pcap_enable == 0)
43  {
44  if (dm->pcap_filename == 0)
45  dm->pcap_filename = format (0, "/tmp/vpe.pcap%c", 0);
46 
47  memset (&dm->pcap_main, 0, sizeof (dm->pcap_main));
48  dm->pcap_main.file_name = (char *) dm->pcap_filename;
50  if (dm->pcap_pkts_to_capture)
52 
53  dm->pcap_main.packet_type = PCAP_PACKET_TYPE_ethernet;
54  dm->tx_pcap_enable = 1;
55  matched = 1;
56  vlib_cli_output (vm, "pcap tx capture on...");
57  }
58  else
59  {
60  vlib_cli_output (vm, "pcap tx capture already on...");
61  }
62  matched = 1;
63  }
64  else if (unformat (input, "off"))
65  {
66  if (dm->tx_pcap_enable)
67  {
68  vlib_cli_output (vm, "captured %d pkts...",
71  {
74  error = pcap_write (&dm->pcap_main);
75  if (error)
76  clib_error_report (error);
77  else
78  vlib_cli_output (vm, "saved to %s...", dm->pcap_filename);
79  }
80  }
81  else
82  {
83  vlib_cli_output (vm, "pcap tx capture already off...");
84  }
85 
86  dm->tx_pcap_enable = 0;
87  matched = 1;
88  }
89  else if (unformat (input, "max %d", &max))
90  {
91  dm->pcap_pkts_to_capture = max;
92  matched = 1;
93  }
94 
95  else if (unformat (input, "intfc %U",
97  &dm->pcap_sw_if_index))
98  matched = 1;
99  else if (unformat (input, "intfc any"))
100  {
101  dm->pcap_sw_if_index = 0;
102  matched = 1;
103  }
104  else if (unformat (input, "file %s", &filename))
105  {
106  u8 *chroot_filename;
107  /* Brain-police user path input */
108  if (strstr ((char *) filename, "..")
109  || index ((char *) filename, '/'))
110  {
111  vlib_cli_output (vm, "illegal characters in filename '%s'",
112  filename);
113  continue;
114  }
115 
116  chroot_filename = format (0, "/tmp/%s%c", filename, 0);
117  vec_free (filename);
118 
119  if (dm->pcap_filename)
120  vec_free (dm->pcap_filename);
121  vec_add1 (filename, 0);
122  dm->pcap_filename = chroot_filename;
123  matched = 1;
124  }
125  else if (unformat (input, "status"))
126  {
127  if (dm->tx_pcap_enable == 0)
128  {
129  vlib_cli_output (vm, "pcap tx capture is off...");
130  continue;
131  }
132 
133  vlib_cli_output (vm, "pcap tx capture: %d of %d pkts...",
136  matched = 1;
137  }
138 
139  else
140  break;
141  }
142 
143  if (matched == 0)
144  return clib_error_return (0, "unknown input `%U'",
145  format_unformat_error, input);
146 
147  return 0;
148 }
149 
150 /* *INDENT-OFF* */
151 VLIB_CLI_COMMAND (pcap_trace_command, static) = {
152  .path = "pcap tx trace",
153  .short_help =
154  "pcap tx trace on off max <nn> intfc <intfc> file <name> status",
155  .function = pcap_trace_command_fn,
156 };
157 /* *INDENT-ON* */
158 
159 
160 static clib_error_t *
162  vlib_cli_command_t * cmd)
163 {
164  struct rte_mempool *rmp;
165  int i;
166 
167  for (i = 0; i < vec_len (vm->buffer_main->pktmbuf_pools); i++)
168  {
169  rmp = vm->buffer_main->pktmbuf_pools[i];
170  if (rmp)
171  {
172  unsigned count = rte_mempool_avail_count (rmp);
173  unsigned free_count = rte_mempool_in_use_count (rmp);
174 
175  vlib_cli_output (vm,
176  "name=\"%s\" available = %7d allocated = %7d total = %7d\n",
177  rmp->name, (u32) count, (u32) free_count,
178  (u32) (count + free_count));
179  }
180  else
181  {
182  vlib_cli_output (vm, "rte_mempool is NULL (!)\n");
183  }
184  }
185  return 0;
186 }
187 
188 /* *INDENT-OFF* */
189 VLIB_CLI_COMMAND (cmd_show_dpdk_bufferr,static) = {
190  .path = "show dpdk buffer",
191  .short_help = "show dpdk buffer state",
192  .function = show_dpdk_buffer,
193  .is_mp_safe = 1,
194 };
195 /* *INDENT-ON* */
196 
197 static clib_error_t *
199  vlib_cli_command_t * cmd)
200 {
201  static u32 *allocated_buffers;
202  u32 n_alloc = 0;
203  u32 n_free = 0;
204  u32 first, actual_alloc;
205 
207  {
208  if (unformat (input, "allocate %d", &n_alloc))
209  ;
210  else if (unformat (input, "free %d", &n_free))
211  ;
212  else
213  break;
214  }
215 
216  if (n_free)
217  {
218  if (vec_len (allocated_buffers) < n_free)
219  return clib_error_return (0, "Can't free %d, only %d allocated",
220  n_free, vec_len (allocated_buffers));
221 
222  first = vec_len (allocated_buffers) - n_free;
223  vlib_buffer_free (vm, allocated_buffers + first, n_free);
224  _vec_len (allocated_buffers) = first;
225  }
226  if (n_alloc)
227  {
228  first = vec_len (allocated_buffers);
229  vec_validate (allocated_buffers,
230  vec_len (allocated_buffers) + n_alloc - 1);
231 
232  actual_alloc = vlib_buffer_alloc (vm, allocated_buffers + first,
233  n_alloc);
234  _vec_len (allocated_buffers) = first + actual_alloc;
235 
236  if (actual_alloc < n_alloc)
237  vlib_cli_output (vm, "WARNING: only allocated %d buffers",
238  actual_alloc);
239  }
240 
241  vlib_cli_output (vm, "Currently %d buffers allocated",
242  vec_len (allocated_buffers));
243 
244  if (allocated_buffers && vec_len (allocated_buffers) == 0)
245  vec_free (allocated_buffers);
246 
247  return 0;
248 }
249 
250 /* *INDENT-OFF* */
251 VLIB_CLI_COMMAND (cmd_test_dpdk_buffer,static) = {
252  .path = "test dpdk buffer",
253  .short_help = "test dpdk buffer [allocate <nn>][free <nn>]",
254  .function = test_dpdk_buffer,
255  .is_mp_safe = 1,
256 };
257 /* *INDENT-ON* */
258 
259 static void
261 {
262  vlib_cli_output (vm,
263  "device_index %d\n"
264  " last_burst_sz %d\n"
265  " max_burst_sz %d\n"
266  " full_frames_cnt %u\n"
267  " consec_full_frames_cnt %u\n"
268  " congestion_cnt %d\n"
269  " last_poll_time %llu\n"
270  " max_poll_delay %llu\n"
271  " discard_cnt %u\n"
272  " total_packet_cnt %u\n",
273  xd->device_index,
282 
283  u32 device_queue_sz = rte_eth_rx_queue_count (xd->device_index,
284  0 /* queue_id */ );
285  vlib_cli_output (vm, " device_queue_sz %u\n", device_queue_sz);
286 }
287 
288 static void
290 {
292  dpdk_main_t *dm = &dpdk_main;
293 
294  vlib_cli_output (vm,
295  "dpdk: (0x%04x) enabled:%d monitor:%d drop_all:%d\n"
296  " dpdk_queue_hi_thresh %d\n"
297  " consec_full_frames_hi_thresh %d\n"
298  "---------\n"
299  "worker: (0x%04x) enabled:%d monitor:%d\n"
300  " worker_queue_hi_thresh %d\n",
301  dm->efd.enabled,
302  ((dm->efd.enabled & DPDK_EFD_DISCARD_ENABLED) ? 1 : 0),
303  ((dm->efd.enabled & DPDK_EFD_MONITOR_ENABLED) ? 1 : 0),
304  ((dm->efd.enabled & DPDK_EFD_DROPALL_ENABLED) ? 1 : 0),
305  dm->efd.queue_hi_thresh,
307  tm->efd.enabled,
308  ((tm->efd.enabled & VLIB_EFD_DISCARD_ENABLED) ? 1 : 0),
309  ((dm->efd.enabled & VLIB_EFD_MONITOR_ENABLED) ? 1 : 0),
310  tm->efd.queue_hi_thresh);
311  vlib_cli_output (vm,
312  "---------\n"
313  "ip_prec_bitmap 0x%02x\n"
314  "mpls_exp_bitmap 0x%02x\n"
315  "vlan_cos_bitmap 0x%02x\n",
316  tm->efd.ip_prec_bitmap,
318 }
319 
320 static clib_error_t *
322  unformat_input_t * input, vlib_cli_command_t * cmd)
323 {
324 
325  if (unformat (input, "config"))
326  {
327  show_efd_config (vm);
328  }
329  else if (unformat (input, "dpdk"))
330  {
331  dpdk_main_t *dm = &dpdk_main;
332  dpdk_device_t *xd;
333  u32 device_id = ~0;
334 
335  (void) unformat (input, "device %d", &device_id);
336  /* *INDENT-OFF* */
337  vec_foreach (xd, dm->devices)
338  {
339  if ((xd->device_index == device_id) || (device_id == ~0))
340  {
341  show_dpdk_device_stats(vm, xd);
342  }
343  }
344  /* *INDENT-ON* */
345  }
346  else if (unformat (input, "worker"))
347  {
349  vlib_frame_queue_t *fq;
351  int thread_id;
352  u32 num_workers = 0;
353  u32 first_worker_index = 0;
354  uword *p;
355 
356  p = hash_get_mem (tm->thread_registrations_by_name, "workers");
357  ASSERT (p);
358  tr = (vlib_thread_registration_t *) p[0];
359  if (tr)
360  {
361  num_workers = tr->count;
362  first_worker_index = tr->first_index;
363  }
364 
365  vlib_cli_output (vm,
366  "num_workers %d\n"
367  "first_worker_index %d\n"
368  "vlib_frame_queues[%d]:\n",
369  num_workers, first_worker_index, tm->n_vlib_mains);
370 
371  for (thread_id = 0; thread_id < tm->n_vlib_mains; thread_id++)
372  {
373  fq = vlib_frame_queues[thread_id];
374  if (fq)
375  {
376  vlib_cli_output (vm,
377  "%2d: frames_queued %u\n"
378  " frames_queued_hint %u\n"
379  " enqueue_full_events %u\n"
380  " enqueue_efd_discards %u\n",
381  thread_id,
382  (fq->tail - fq->head),
383  (fq->tail - fq->head_hint),
386  }
387  }
388  }
389  else if (unformat (input, "help"))
390  {
391  vlib_cli_output (vm, "Usage: show efd config | "
392  "dpdk [device <id>] | worker\n");
393  }
394  else
395  {
396  show_efd_config (vm);
397  }
398 
399  return 0;
400 }
401 
402 /* *INDENT-OFF* */
403 VLIB_CLI_COMMAND (show_efd_command, static) = {
404  .path = "show efd",
405  .short_help = "Show efd [device <id>] | [config]",
406  .function = show_efd,
407 };
408 /* *INDENT-ON* */
409 
410 static clib_error_t *
412  unformat_input_t * input, vlib_cli_command_t * cmd)
413 {
414  dpdk_main_t *dm = &dpdk_main;
415  dpdk_device_t *xd;
417  vlib_frame_queue_t *fq;
418  int thread_id;
419 
420  /* *INDENT-OFF* */
421  vec_foreach (xd, dm->devices)
422  {
423  xd->efd_agent.last_burst_sz = 0;
424  xd->efd_agent.max_burst_sz = 0;
425  xd->efd_agent.full_frames_cnt = 0;
427  xd->efd_agent.congestion_cnt = 0;
428  xd->efd_agent.last_poll_time = 0;
429  xd->efd_agent.max_poll_delay = 0;
430  xd->efd_agent.discard_cnt = 0;
431  xd->efd_agent.total_packet_cnt = 0;
432  }
433  /* *INDENT-ON* */
434 
435  for (thread_id = 0; thread_id < tm->n_vlib_mains; thread_id++)
436  {
437  fq = vlib_frame_queues[thread_id];
438  if (fq)
439  {
440  fq->enqueue_full_events = 0;
441  fq->enqueue_efd_discards = 0;
442  }
443  }
444 
445  return 0;
446 }
447 
448 /* *INDENT-OFF* */
449 VLIB_CLI_COMMAND (clear_efd_command,static) = {
450  .path = "clear efd",
451  .short_help = "Clear early-fast-discard counters",
452  .function = clear_efd,
453 };
454 /* *INDENT-ON* */
455 
456 static clib_error_t *
458  vlib_cli_command_t * cmd,
459  char *prec_type, u8 * prec_bitmap)
460 {
461  clib_error_t *error = NULL;
462  u8 op = 0;
463  u8 prec = 0;
464 
465  if (unformat (input, "ge"))
466  {
468  }
469  else if (unformat (input, "lt"))
470  {
472  }
473  else if (unformat (input, "help"))
474  {
475  vlib_cli_output (vm, "enter operation [ge | lt] and precedence <0-7>)");
476  return (error);
477  }
478  else
479  {
480  return clib_error_return (0, "unknown input `%U'",
481  format_unformat_error, input);
482  }
483 
484  if (unformat (input, "%u", &prec))
485  {
486  if (prec > 7)
487  {
488  return clib_error_return (0, "precedence %d is out of range <0-7>",
489  prec);
490  }
491  }
492  else
493  {
494  return clib_error_return (0, "unknown input `%U'",
495  format_unformat_error, input);
496  }
497 
498  set_efd_bitmap (prec_bitmap, prec, op);
499 
500  vlib_cli_output (vm,
501  "EFD will be set for %s precedence %s%u%s.",
502  prec_type,
503  (op == EFD_OPERATION_LESS_THAN) ? "less than " : "",
504  prec,
505  (op ==
506  EFD_OPERATION_GREATER_OR_EQUAL) ? " and greater" : "");
507 
508  return (error);
509 }
510 
511 
512 static clib_error_t *
514 {
515  dpdk_main_t *dm = &dpdk_main;
517  clib_error_t *error = NULL;
519 
520  if (unformat (input, "enable"))
521  {
522  if (unformat (input, "dpdk"))
523  {
525  }
526  else if (unformat (input, "worker"))
527  {
529  }
530  else if (unformat (input, "monitor"))
531  {
534  }
535  else if (unformat (input, "drop_all"))
536  {
538  }
539  else if (unformat (input, "default"))
540  {
545  }
546  else
547  {
548  return clib_error_return (0, "Usage: set efd enable [dpdk | "
549  "worker | monitor | drop_all | default]");
550  }
551  }
552  else if (unformat (input, "disable"))
553  {
554  if (unformat (input, "dpdk"))
555  {
557  }
558  else if (unformat (input, "worker"))
559  {
561  }
562  else if (unformat (input, "monitor"))
563  {
566  }
567  else if (unformat (input, "drop_all"))
568  {
570  }
571  else if (unformat (input, "all"))
572  {
573  dm->efd.enabled = 0;
574  tm->efd.enabled = 0;
575  }
576  else
577  {
578  return clib_error_return (0, "Usage: set efd disable [dpdk | "
579  "worker | monitor | drop_all | all]");
580  }
581  }
582  else if (unformat (input, "worker_queue_hi_thresh"))
583  {
584  u32 mark;
585  if (unformat (input, "%u", &mark))
586  {
587  tm->efd.queue_hi_thresh = mark;
588  }
589  else
590  {
591  return clib_error_return (0, "unknown input `%U'",
592  format_unformat_error, input);
593  }
594  }
595  else if (unformat (input, "dpdk_device_hi_thresh"))
596  {
597  u32 thresh;
598  if (unformat (input, "%u", &thresh))
599  {
600  dm->efd.queue_hi_thresh = thresh;
601  }
602  else
603  {
604  return clib_error_return (0, "unknown input `%U'",
605  format_unformat_error, input);
606  }
607  }
608  else if (unformat (input, "consec_full_frames_hi_thresh"))
609  {
610  u32 thresh;
611  if (unformat (input, "%u", &thresh))
612  {
613  dm->efd.consec_full_frames_hi_thresh = thresh;
614  }
615  else
616  {
617  return clib_error_return (0, "unknown input `%U'",
618  format_unformat_error, input);
619  }
620  }
621  else if (unformat (input, "ip-prec"))
622  {
623  return (parse_op_and_prec (vm, input, cmd,
624  "ip", &tm->efd.ip_prec_bitmap));
625  }
626  else if (unformat (input, "mpls-exp"))
627  {
628  return (parse_op_and_prec (vm, input, cmd,
629  "mpls", &tm->efd.mpls_exp_bitmap));
630  }
631  else if (unformat (input, "vlan-cos"))
632  {
633  return (parse_op_and_prec (vm, input, cmd,
634  "vlan", &tm->efd.vlan_cos_bitmap));
635  }
636  else if (unformat (input, "help"))
637  {
638  vlib_cli_output (vm,
639  "Usage:\n"
640  " set efd enable <dpdk | worker | monitor | drop_all | default> |\n"
641  " set efd disable <dpdk | worker | monitor | drop_all | all> |\n"
642  " set efd <ip-prec | mpls-exp | vlan-cos> <ge | lt> <0-7>\n"
643  " set efd worker_queue_hi_thresh <0-32> |\n"
644  " set efd dpdk_device_hi_thresh <0-%d> |\n"
645  " set efd consec_full_frames_hi_thresh <count> |\n",
647  }
648  else
649  {
650  return clib_error_return (0, "unknown input `%U'",
651  format_unformat_error, input);
652  }
653 
654  if (dm->efd.enabled)
656  else if (dm->use_rss)
658  else
660 
661  return error;
662 }
663 
664 /* *INDENT-OFF* */
665 VLIB_CLI_COMMAND (cmd_set_efd,static) = {
666  .path = "set efd",
667  .short_help = "set early-fast-discard commands",
668  .function = set_efd,
669 };
670 /* *INDENT-ON* */
671 
672 static clib_error_t *
674  vlib_cli_command_t * cmd)
675 {
676  unformat_input_t _line_input, *line_input = &_line_input;
677  dpdk_main_t *dm = &dpdk_main;
679  dpdk_device_t *xd;
680  u32 hw_if_index = (u32) ~ 0;
681  u32 nb_rx_desc = (u32) ~ 0;
682  u32 nb_tx_desc = (u32) ~ 0;
683  clib_error_t *rv;
684 
685  if (!unformat_user (input, unformat_line_input, line_input))
686  return 0;
687 
688  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
689  {
690  if (unformat
691  (line_input, "%U", unformat_vnet_hw_interface, dm->vnet_main,
692  &hw_if_index))
693  ;
694  else if (unformat (line_input, "tx %d", &nb_tx_desc))
695  ;
696  else if (unformat (line_input, "rx %d", &nb_rx_desc))
697  ;
698  else
699  return clib_error_return (0, "parse error: '%U'",
700  format_unformat_error, line_input);
701  }
702 
703  unformat_free (line_input);
704 
705  if (hw_if_index == (u32) ~ 0)
706  return clib_error_return (0, "please specify valid interface name");
707 
708  hw = vnet_get_hw_interface (dm->vnet_main, hw_if_index);
709  xd = vec_elt_at_index (dm->devices, hw->dev_instance);
710 
711  if ((xd->flags & DPDK_DEVICE_FLAG_PMD) == 0)
712  return clib_error_return (0, "number of descriptors can be set only for "
713  "physical devices");
714 
715  if ((nb_rx_desc == (u32) ~ 0 || nb_rx_desc == xd->nb_rx_desc) &&
716  (nb_tx_desc == (u32) ~ 0 || nb_tx_desc == xd->nb_tx_desc))
717  return clib_error_return (0, "nothing changed");
718 
719  if (nb_rx_desc != (u32) ~ 0)
720  xd->nb_rx_desc = nb_rx_desc;
721 
722  if (nb_tx_desc != (u32) ~ 0)
723  xd->nb_rx_desc = nb_rx_desc;
724 
725  rv = dpdk_port_setup (dm, xd);
726 
727  return rv;
728 }
729 
730 /* *INDENT-OFF* */
731 VLIB_CLI_COMMAND (cmd_set_dpdk_if_desc,static) = {
732  .path = "set dpdk interface descriptors",
733  .short_help = "set dpdk interface descriptors <if-name> [rx <n>] [tx <n>]",
734  .function = set_dpdk_if_desc,
735 };
736 /* *INDENT-ON* */
737 
738 static clib_error_t *
740  vlib_cli_command_t * cmd)
741 {
743  dpdk_main_t *dm = &dpdk_main;
745  int cpu;
746 
747  if (tm->n_vlib_mains == 1)
748  vlib_cli_output (vm, "All interfaces are handled by main thread");
749 
750  for (cpu = 0; cpu < vec_len (dm->devices_by_cpu); cpu++)
751  {
752  if (vec_len (dm->devices_by_cpu[cpu]))
753  vlib_cli_output (vm, "Thread %u (%s at lcore %u):", cpu,
754  vlib_worker_threads[cpu].name,
755  vlib_worker_threads[cpu].lcore_id);
756 
757  /* *INDENT-OFF* */
758  vec_foreach(dq, dm->devices_by_cpu[cpu])
759  {
760  u32 hw_if_index = dm->devices[dq->device].vlib_hw_if_index;
762  vlib_cli_output(vm, " %v queue %u", hi->name, dq->queue_id);
763  }
764  /* *INDENT-ON* */
765  }
766  return 0;
767 }
768 
769 /* *INDENT-OFF* */
770 VLIB_CLI_COMMAND (cmd_show_dpdk_if_placement,static) = {
771  .path = "show dpdk interface placement",
772  .short_help = "show dpdk interface placement",
773  .function = show_dpdk_if_placement,
774 };
775 /* *INDENT-ON* */
776 
777 static int
778 dpdk_device_queue_sort (void *a1, void *a2)
779 {
780  dpdk_device_and_queue_t *dq1 = a1;
781  dpdk_device_and_queue_t *dq2 = a2;
782 
783  if (dq1->device > dq2->device)
784  return 1;
785  else if (dq1->device < dq2->device)
786  return -1;
787  else if (dq1->queue_id > dq2->queue_id)
788  return 1;
789  else if (dq1->queue_id < dq2->queue_id)
790  return -1;
791  else
792  return 0;
793 }
794 
795 static clib_error_t *
797  vlib_cli_command_t * cmd)
798 {
799  unformat_input_t _line_input, *line_input = &_line_input;
800  dpdk_main_t *dm = &dpdk_main;
803  dpdk_device_t *xd;
804  u32 hw_if_index = (u32) ~ 0;
805  u32 queue = (u32) 0;
806  u32 cpu = (u32) ~ 0;
807  int i;
808 
809  if (!unformat_user (input, unformat_line_input, line_input))
810  return 0;
811 
812  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
813  {
814  if (unformat
815  (line_input, "%U", unformat_vnet_hw_interface, dm->vnet_main,
816  &hw_if_index))
817  ;
818  else if (unformat (line_input, "queue %d", &queue))
819  ;
820  else if (unformat (line_input, "thread %d", &cpu))
821  ;
822  else
823  return clib_error_return (0, "parse error: '%U'",
824  format_unformat_error, line_input);
825  }
826 
827  unformat_free (line_input);
828 
829  if (hw_if_index == (u32) ~ 0)
830  return clib_error_return (0, "please specify valid interface name");
831 
832  if (cpu < dm->input_cpu_first_index ||
833  cpu >= (dm->input_cpu_first_index + dm->input_cpu_count))
834  return clib_error_return (0, "please specify valid thread id");
835 
836  hw = vnet_get_hw_interface (dm->vnet_main, hw_if_index);
837  xd = vec_elt_at_index (dm->devices, hw->dev_instance);
838 
839  for (i = 0; i < vec_len (dm->devices_by_cpu); i++)
840  {
841  /* *INDENT-OFF* */
842  vec_foreach(dq, dm->devices_by_cpu[i])
843  {
844  if (hw_if_index == dm->devices[dq->device].vlib_hw_if_index &&
845  queue == dq->queue_id)
846  {
847  if (cpu == i) /* nothing to do */
848  return 0;
849 
850  vec_del1(dm->devices_by_cpu[i], dq - dm->devices_by_cpu[i]);
851  vec_add2(dm->devices_by_cpu[cpu], dq, 1);
852  dq->queue_id = queue;
853  dq->device = xd->device_index;
854  xd->cpu_socket_id_by_queue[queue] =
855  rte_lcore_to_socket_id(vlib_worker_threads[cpu].lcore_id);
856 
859 
862 
863  if (vec_len(dm->devices_by_cpu[i]) == 0)
865  VLIB_NODE_STATE_DISABLED);
866 
867  if (vec_len(dm->devices_by_cpu[cpu]) == 1)
869  VLIB_NODE_STATE_POLLING);
870 
871  return 0;
872  }
873  }
874  /* *INDENT-ON* */
875  }
876 
877  return clib_error_return (0, "not found");
878 }
879 
880 /* *INDENT-OFF* */
881 VLIB_CLI_COMMAND (cmd_set_dpdk_if_placement,static) = {
882  .path = "set dpdk interface placement",
883  .short_help = "set dpdk interface placement <if-name> [queue <n>] thread <n>",
884  .function = set_dpdk_if_placement,
885 };
886 /* *INDENT-ON* */
887 
888 static clib_error_t *
890  vlib_cli_command_t * cmd)
891 {
893  dpdk_main_t *dm = &dpdk_main;
895  int cpu;
896 
897  if (tm->n_vlib_mains == 1)
898  vlib_cli_output (vm, "All interfaces are handled by main thread");
899 
900  for (cpu = 0; cpu < vec_len (dm->devices_by_hqos_cpu); cpu++)
901  {
902  if (vec_len (dm->devices_by_hqos_cpu[cpu]))
903  vlib_cli_output (vm, "Thread %u (%s at lcore %u):", cpu,
904  vlib_worker_threads[cpu].name,
905  vlib_worker_threads[cpu].lcore_id);
906 
907  vec_foreach (dq, dm->devices_by_hqos_cpu[cpu])
908  {
909  u32 hw_if_index = dm->devices[dq->device].vlib_hw_if_index;
911  vnet_get_hw_interface (dm->vnet_main, hw_if_index);
912  vlib_cli_output (vm, " %v queue %u", hi->name, dq->queue_id);
913  }
914  }
915  return 0;
916 }
917 
918 /* *INDENT-OFF* */
919 VLIB_CLI_COMMAND (cmd_show_dpdk_if_hqos_placement, static) = {
920  .path = "show dpdk interface hqos placement",
921  .short_help = "show dpdk interface hqos placement",
922  .function = show_dpdk_if_hqos_placement,
923 };
924 /* *INDENT-ON* */
925 
926 static clib_error_t *
928  vlib_cli_command_t * cmd)
929 {
930  unformat_input_t _line_input, *line_input = &_line_input;
931  dpdk_main_t *dm = &dpdk_main;
934  dpdk_device_t *xd;
935  u32 hw_if_index = (u32) ~ 0;
936  u32 cpu = (u32) ~ 0;
937  int i;
938 
939  if (!unformat_user (input, unformat_line_input, line_input))
940  return 0;
941 
942  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
943  {
944  if (unformat
945  (line_input, "%U", unformat_vnet_hw_interface, dm->vnet_main,
946  &hw_if_index))
947  ;
948  else if (unformat (line_input, "thread %d", &cpu))
949  ;
950  else
951  return clib_error_return (0, "parse error: '%U'",
952  format_unformat_error, line_input);
953  }
954 
955  unformat_free (line_input);
956 
957  if (hw_if_index == (u32) ~ 0)
958  return clib_error_return (0, "please specify valid interface name");
959 
960  if (cpu < dm->hqos_cpu_first_index ||
961  cpu >= (dm->hqos_cpu_first_index + dm->hqos_cpu_count))
962  return clib_error_return (0, "please specify valid thread id");
963 
964  hw = vnet_get_hw_interface (dm->vnet_main, hw_if_index);
965  xd = vec_elt_at_index (dm->devices, hw->dev_instance);
966 
967  for (i = 0; i < vec_len (dm->devices_by_hqos_cpu); i++)
968  {
969  vec_foreach (dq, dm->devices_by_hqos_cpu[i])
970  {
971  if (hw_if_index == dm->devices[dq->device].vlib_hw_if_index)
972  {
973  if (cpu == i) /* nothing to do */
974  return 0;
975 
977  dq - dm->devices_by_hqos_cpu[i]);
978  vec_add2 (dm->devices_by_hqos_cpu[cpu], dq, 1);
979  dq->queue_id = 0;
980  dq->device = xd->device_index;
981 
984 
987 
988  return 0;
989  }
990  }
991  }
992 
993  return clib_error_return (0, "not found");
994 }
995 
996 /* *INDENT-OFF* */
997 VLIB_CLI_COMMAND (cmd_set_dpdk_if_hqos_placement, static) = {
998  .path = "set dpdk interface hqos placement",
999  .short_help = "set dpdk interface hqos placement <if-name> thread <n>",
1000  .function = set_dpdk_if_hqos_placement,
1001 };
1002 /* *INDENT-ON* */
1003 
1004 static clib_error_t *
1006  vlib_cli_command_t * cmd)
1007 {
1008  unformat_input_t _line_input, *line_input = &_line_input;
1009  dpdk_main_t *dm = &dpdk_main;
1010  vnet_hw_interface_t *hw;
1011  dpdk_device_t *xd;
1012  u32 hw_if_index = (u32) ~ 0;
1013  u32 subport_id = (u32) ~ 0;
1014  u32 pipe_id = (u32) ~ 0;
1015  u32 profile_id = (u32) ~ 0;
1016  int rv;
1017 
1018  if (!unformat_user (input, unformat_line_input, line_input))
1019  return 0;
1020 
1021  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1022  {
1023  if (unformat
1024  (line_input, "%U", unformat_vnet_hw_interface, dm->vnet_main,
1025  &hw_if_index))
1026  ;
1027  else if (unformat (line_input, "subport %d", &subport_id))
1028  ;
1029  else if (unformat (line_input, "pipe %d", &pipe_id))
1030  ;
1031  else if (unformat (line_input, "profile %d", &profile_id))
1032  ;
1033  else
1034  return clib_error_return (0, "parse error: '%U'",
1035  format_unformat_error, line_input);
1036  }
1037 
1038  unformat_free (line_input);
1039 
1040  if (hw_if_index == (u32) ~ 0)
1041  return clib_error_return (0, "please specify valid interface name");
1042 
1043  hw = vnet_get_hw_interface (dm->vnet_main, hw_if_index);
1044  xd = vec_elt_at_index (dm->devices, hw->dev_instance);
1045 
1046  rv =
1047  rte_sched_pipe_config (xd->hqos_ht->hqos, subport_id, pipe_id,
1048  profile_id);
1049  if (rv)
1050  return clib_error_return (0, "pipe configuration failed");
1051 
1052  return 0;
1053 }
1054 
1055 /* *INDENT-OFF* */
1056 VLIB_CLI_COMMAND (cmd_set_dpdk_if_hqos_pipe, static) =
1057 {
1058  .path = "set dpdk interface hqos pipe",
1059  .short_help = "set dpdk interface hqos pipe <if-name> subport <n> pipe <n> "
1060  "profile <n>",
1061  .function = set_dpdk_if_hqos_pipe,
1062 };
1063 /* *INDENT-ON* */
1064 
1065 static clib_error_t *
1067  vlib_cli_command_t * cmd)
1068 {
1069  unformat_input_t _line_input, *line_input = &_line_input;
1070  dpdk_main_t *dm = &dpdk_main;
1071  vnet_hw_interface_t *hw;
1072  dpdk_device_t *xd;
1073  u32 hw_if_index = (u32) ~ 0;
1074  u32 subport_id = (u32) ~ 0;
1075  struct rte_sched_subport_params p = {
1076  .tb_rate = 1250000000, /* 10GbE */
1077  .tb_size = 1000000,
1078  .tc_rate = {1250000000, 1250000000, 1250000000, 1250000000},
1079  .tc_period = 10,
1080  };
1081  int rv;
1082 
1083  if (!unformat_user (input, unformat_line_input, line_input))
1084  return 0;
1085 
1086  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1087  {
1088  if (unformat
1089  (line_input, "%U", unformat_vnet_hw_interface, dm->vnet_main,
1090  &hw_if_index))
1091  ;
1092  else if (unformat (line_input, "subport %d", &subport_id))
1093  ;
1094  else if (unformat (line_input, "rate %d", &p.tb_rate))
1095  {
1096  p.tc_rate[0] = p.tb_rate;
1097  p.tc_rate[1] = p.tb_rate;
1098  p.tc_rate[2] = p.tb_rate;
1099  p.tc_rate[3] = p.tb_rate;
1100  }
1101  else if (unformat (line_input, "bktsize %d", &p.tb_size))
1102  ;
1103  else if (unformat (line_input, "tc0 %d", &p.tc_rate[0]))
1104  ;
1105  else if (unformat (line_input, "tc1 %d", &p.tc_rate[1]))
1106  ;
1107  else if (unformat (line_input, "tc2 %d", &p.tc_rate[2]))
1108  ;
1109  else if (unformat (line_input, "tc3 %d", &p.tc_rate[3]))
1110  ;
1111  else if (unformat (line_input, "period %d", &p.tc_period))
1112  ;
1113  else
1114  return clib_error_return (0, "parse error: '%U'",
1115  format_unformat_error, line_input);
1116  }
1117 
1118  unformat_free (line_input);
1119 
1120  if (hw_if_index == (u32) ~ 0)
1121  return clib_error_return (0, "please specify valid interface name");
1122 
1123  hw = vnet_get_hw_interface (dm->vnet_main, hw_if_index);
1124  xd = vec_elt_at_index (dm->devices, hw->dev_instance);
1125 
1126  rv = rte_sched_subport_config (xd->hqos_ht->hqos, subport_id, &p);
1127  if (rv)
1128  return clib_error_return (0, "subport configuration failed");
1129 
1130  return 0;
1131 }
1132 
1133 /* *INDENT-OFF* */
1134 VLIB_CLI_COMMAND (cmd_set_dpdk_if_hqos_subport, static) = {
1135  .path = "set dpdk interface hqos subport",
1136  .short_help = "set dpdk interface hqos subport <if-name> subport <n> "
1137  "[rate <n>] [bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] "
1138  "[period <n>]",
1139  .function = set_dpdk_if_hqos_subport,
1140 };
1141 /* *INDENT-ON* */
1142 
1143 static clib_error_t *
1145  vlib_cli_command_t * cmd)
1146 {
1147  unformat_input_t _line_input, *line_input = &_line_input;
1149  dpdk_main_t *dm = &dpdk_main;
1150  vnet_hw_interface_t *hw;
1151  dpdk_device_t *xd;
1152  u32 hw_if_index = (u32) ~ 0;
1153  u32 entry, tc, queue, val, i;
1154 
1155  if (!unformat_user (input, unformat_line_input, line_input))
1156  return 0;
1157 
1158  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1159  {
1160  if (unformat
1161  (line_input, "%U", unformat_vnet_hw_interface, dm->vnet_main,
1162  &hw_if_index))
1163  ;
1164  else if (unformat (line_input, "entry %d", &entry))
1165  ;
1166  else if (unformat (line_input, "tc %d", &tc))
1167  ;
1168  else if (unformat (line_input, "queue %d", &queue))
1169  ;
1170  else
1171  return clib_error_return (0, "parse error: '%U'",
1172  format_unformat_error, line_input);
1173  }
1174 
1175  unformat_free (line_input);
1176 
1177  if (hw_if_index == (u32) ~ 0)
1178  return clib_error_return (0, "please specify valid interface name");
1179  if (entry >= 64)
1180  return clib_error_return (0, "invalid entry");
1181  if (tc >= RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE)
1182  return clib_error_return (0, "invalid traffic class");
1183  if (queue >= RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS)
1184  return clib_error_return (0, "invalid traffic class");
1185 
1186  hw = vnet_get_hw_interface (dm->vnet_main, hw_if_index);
1187  xd = vec_elt_at_index (dm->devices, hw->dev_instance);
1188 
1189  /* Detect the set of worker threads */
1190  uword *p = hash_get_mem (tm->thread_registrations_by_name, "workers");
1192  int worker_thread_first = tr->first_index;
1193  int worker_thread_count = tr->count;
1194 
1195  val = tc * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS + queue;
1196  for (i = 0; i < worker_thread_count; i++)
1197  xd->hqos_wt[worker_thread_first + i].hqos_tc_table[entry] = val;
1198 
1199  return 0;
1200 }
1201 
1202 /* *INDENT-OFF* */
1203 VLIB_CLI_COMMAND (cmd_set_dpdk_if_hqos_tctbl, static) = {
1204  .path = "set dpdk interface hqos tctbl",
1205  .short_help = "set dpdk interface hqos tctbl <if-name> entry <n> tc <n> queue <n>",
1206  .function = set_dpdk_if_hqos_tctbl,
1207 };
1208 /* *INDENT-ON* */
1209 
1210 static clib_error_t *
1212  vlib_cli_command_t * cmd)
1213 {
1214  unformat_input_t _line_input, *line_input = &_line_input;
1216  dpdk_main_t *dm = &dpdk_main;
1217 
1218  /* Device specific data */
1219  struct rte_eth_dev_info dev_info;
1220  dpdk_device_config_t *devconf = 0;
1221  vnet_hw_interface_t *hw;
1222  dpdk_device_t *xd;
1223  u32 hw_if_index = (u32) ~ 0;
1224 
1225  /* Detect the set of worker threads */
1226  uword *p = hash_get_mem (tm->thread_registrations_by_name, "workers");
1228  int worker_thread_first = tr->first_index;
1229  int worker_thread_count = tr->count;
1230 
1231  /* Packet field configuration */
1232  u64 mask;
1233  u32 id, offset;
1234 
1235  /* HQoS params */
1236  u32 n_subports_per_port, n_pipes_per_subport, tctbl_size;
1237 
1238  u32 i;
1239 
1240  /* Parse input arguments */
1241  if (!unformat_user (input, unformat_line_input, line_input))
1242  return 0;
1243 
1244  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1245  {
1246  if (unformat
1247  (line_input, "%U", unformat_vnet_hw_interface, dm->vnet_main,
1248  &hw_if_index))
1249  ;
1250  else if (unformat (line_input, "id %d", &id))
1251  ;
1252  else if (unformat (line_input, "offset %d", &offset))
1253  ;
1254  else if (unformat (line_input, "mask %llx", &mask))
1255  ;
1256  else
1257  return clib_error_return (0, "parse error: '%U'",
1258  format_unformat_error, line_input);
1259  }
1260 
1261  unformat_free (line_input);
1262 
1263  /* Get interface */
1264  if (hw_if_index == (u32) ~ 0)
1265  return clib_error_return (0, "please specify valid interface name");
1266 
1267  hw = vnet_get_hw_interface (dm->vnet_main, hw_if_index);
1268  xd = vec_elt_at_index (dm->devices, hw->dev_instance);
1269 
1270  rte_eth_dev_info_get (xd->device_index, &dev_info);
1271  if (dev_info.pci_dev)
1272  { /* bonded interface has no pci info */
1273  vlib_pci_addr_t pci_addr;
1274 
1275  pci_addr.domain = dev_info.pci_dev->addr.domain;
1276  pci_addr.bus = dev_info.pci_dev->addr.bus;
1277  pci_addr.slot = dev_info.pci_dev->addr.devid;
1278  pci_addr.function = dev_info.pci_dev->addr.function;
1279 
1280  p =
1281  hash_get (dm->conf->device_config_index_by_pci_addr, pci_addr.as_u32);
1282  }
1283 
1284  if (p)
1285  devconf = pool_elt_at_index (dm->conf->dev_confs, p[0]);
1286  else
1287  devconf = &dm->conf->default_devconf;
1288 
1289  if (devconf->hqos_enabled == 0)
1290  {
1291  vlib_cli_output (vm, "HQoS disabled for this interface");
1292  return 0;
1293  }
1294 
1295  n_subports_per_port = devconf->hqos.port.n_subports_per_port;
1296  n_pipes_per_subport = devconf->hqos.port.n_pipes_per_subport;
1297  tctbl_size = RTE_DIM (devconf->hqos.tc_table);
1298 
1299  /* Validate packet field configuration: id, offset and mask */
1300  if (id >= 3)
1301  return clib_error_return (0, "invalid packet field id");
1302 
1303  switch (id)
1304  {
1305  case 0:
1306  if (dpdk_hqos_validate_mask (mask, n_subports_per_port) != 0)
1307  return clib_error_return (0, "invalid subport ID mask "
1308  "(n_subports_per_port = %u)",
1309  n_subports_per_port);
1310  break;
1311  case 1:
1312  if (dpdk_hqos_validate_mask (mask, n_pipes_per_subport) != 0)
1313  return clib_error_return (0, "invalid pipe ID mask "
1314  "(n_pipes_per_subport = %u)",
1315  n_pipes_per_subport);
1316  break;
1317  case 2:
1318  default:
1319  if (dpdk_hqos_validate_mask (mask, tctbl_size) != 0)
1320  return clib_error_return (0, "invalid TC table index mask "
1321  "(TC table size = %u)", tctbl_size);
1322  }
1323 
1324  /* Propagate packet field configuration to all workers */
1325  for (i = 0; i < worker_thread_count; i++)
1326  switch (id)
1327  {
1328  case 0:
1329  xd->hqos_wt[worker_thread_first + i].hqos_field0_slabpos = offset;
1330  xd->hqos_wt[worker_thread_first + i].hqos_field0_slabmask = mask;
1331  xd->hqos_wt[worker_thread_first + i].hqos_field0_slabshr =
1332  __builtin_ctzll (mask);
1333  break;
1334  case 1:
1335  xd->hqos_wt[worker_thread_first + i].hqos_field1_slabpos = offset;
1336  xd->hqos_wt[worker_thread_first + i].hqos_field1_slabmask = mask;
1337  xd->hqos_wt[worker_thread_first + i].hqos_field1_slabshr =
1338  __builtin_ctzll (mask);
1339  break;
1340  case 2:
1341  default:
1342  xd->hqos_wt[worker_thread_first + i].hqos_field2_slabpos = offset;
1343  xd->hqos_wt[worker_thread_first + i].hqos_field2_slabmask = mask;
1344  xd->hqos_wt[worker_thread_first + i].hqos_field2_slabshr =
1345  __builtin_ctzll (mask);
1346  }
1347 
1348  return 0;
1349 }
1350 
1351 /* *INDENT-OFF* */
1352 VLIB_CLI_COMMAND (cmd_set_dpdk_if_hqos_pktfield, static) = {
1353  .path = "set dpdk interface hqos pktfield",
1354  .short_help = "set dpdk interface hqos pktfield <if-name> id <n> offset <n> "
1355  "mask <n>",
1356  .function = set_dpdk_if_hqos_pktfield,
1357 };
1358 /* *INDENT-ON* */
1359 
1360 static clib_error_t *
1362  vlib_cli_command_t * cmd)
1363 {
1364  unformat_input_t _line_input, *line_input = &_line_input;
1366  dpdk_main_t *dm = &dpdk_main;
1367  vnet_hw_interface_t *hw;
1368  dpdk_device_t *xd;
1372  u32 *tctbl;
1373  u32 hw_if_index = (u32) ~ 0;
1374  u32 profile_id, i;
1375  struct rte_eth_dev_info dev_info;
1376  dpdk_device_config_t *devconf = 0;
1378  uword *p = 0;
1379 
1380  if (!unformat_user (input, unformat_line_input, line_input))
1381  return 0;
1382 
1383  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1384  {
1385  if (unformat
1386  (line_input, "%U", unformat_vnet_hw_interface, dm->vnet_main,
1387  &hw_if_index))
1388  ;
1389  else
1390  return clib_error_return (0, "parse error: '%U'",
1391  format_unformat_error, line_input);
1392  }
1393 
1394  unformat_free (line_input);
1395 
1396  if (hw_if_index == (u32) ~ 0)
1397  return clib_error_return (0, "please specify interface name!!");
1398 
1399  hw = vnet_get_hw_interface (dm->vnet_main, hw_if_index);
1400  xd = vec_elt_at_index (dm->devices, hw->dev_instance);
1401 
1402  rte_eth_dev_info_get (xd->device_index, &dev_info);
1403  if (dev_info.pci_dev)
1404  { /* bonded interface has no pci info */
1405  vlib_pci_addr_t pci_addr;
1406 
1407  pci_addr.domain = dev_info.pci_dev->addr.domain;
1408  pci_addr.bus = dev_info.pci_dev->addr.bus;
1409  pci_addr.slot = dev_info.pci_dev->addr.devid;
1410  pci_addr.function = dev_info.pci_dev->addr.function;
1411 
1412  p =
1413  hash_get (dm->conf->device_config_index_by_pci_addr, pci_addr.as_u32);
1414  }
1415 
1416  if (p)
1417  devconf = pool_elt_at_index (dm->conf->dev_confs, p[0]);
1418  else
1419  devconf = &dm->conf->default_devconf;
1420 
1421  if (devconf->hqos_enabled == 0)
1422  {
1423  vlib_cli_output (vm, "HQoS disabled for this interface");
1424  return 0;
1425  }
1426 
1427  /* Detect the set of worker threads */
1428  p = hash_get_mem (tm->thread_registrations_by_name, "workers");
1429  tr = (vlib_thread_registration_t *) p[0];
1430 
1431  cfg = &devconf->hqos;
1432  ht = xd->hqos_ht;
1433  wk = &xd->hqos_wt[tr->first_index];
1434  tctbl = wk->hqos_tc_table;
1435 
1436  vlib_cli_output (vm, " Thread:");
1437  vlib_cli_output (vm, " Input SWQ size = %u packets", cfg->swq_size);
1438  vlib_cli_output (vm, " Enqueue burst size = %u packets",
1439  ht->hqos_burst_enq);
1440  vlib_cli_output (vm, " Dequeue burst size = %u packets",
1441  ht->hqos_burst_deq);
1442 
1443  vlib_cli_output (vm,
1444  " Packet field 0: slab position = %4u, slab bitmask = 0x%016llx",
1446  vlib_cli_output (vm,
1447  " Packet field 1: slab position = %4u, slab bitmask = 0x%016llx",
1449  vlib_cli_output (vm,
1450  " Packet field 2: slab position = %4u, slab bitmask = 0x%016llx",
1452  vlib_cli_output (vm, " Packet field 2 translation table:");
1453  vlib_cli_output (vm, " [ 0 .. 15]: "
1454  "%2u %2u %2u %2u %2u %2u %2u %2u %2u %2u %2u %2u %2u %2u %2u %2u",
1455  tctbl[0], tctbl[1], tctbl[2], tctbl[3],
1456  tctbl[4], tctbl[5], tctbl[6], tctbl[7],
1457  tctbl[8], tctbl[9], tctbl[10], tctbl[11],
1458  tctbl[12], tctbl[13], tctbl[14], tctbl[15]);
1459  vlib_cli_output (vm, " [16 .. 31]: "
1460  "%2u %2u %2u %2u %2u %2u %2u %2u %2u %2u %2u %2u %2u %2u %2u %2u",
1461  tctbl[16], tctbl[17], tctbl[18], tctbl[19],
1462  tctbl[20], tctbl[21], tctbl[22], tctbl[23],
1463  tctbl[24], tctbl[25], tctbl[26], tctbl[27],
1464  tctbl[28], tctbl[29], tctbl[30], tctbl[31]);
1465  vlib_cli_output (vm, " [32 .. 47]: "
1466  "%2u %2u %2u %2u %2u %2u %2u %2u %2u %2u %2u %2u %2u %2u %2u %2u",
1467  tctbl[32], tctbl[33], tctbl[34], tctbl[35],
1468  tctbl[36], tctbl[37], tctbl[38], tctbl[39],
1469  tctbl[40], tctbl[41], tctbl[42], tctbl[43],
1470  tctbl[44], tctbl[45], tctbl[46], tctbl[47]);
1471  vlib_cli_output (vm, " [48 .. 63]: "
1472  "%2u %2u %2u %2u %2u %2u %2u %2u %2u %2u %2u %2u %2u %2u %2u %2u",
1473  tctbl[48], tctbl[49], tctbl[50], tctbl[51],
1474  tctbl[52], tctbl[53], tctbl[54], tctbl[55],
1475  tctbl[56], tctbl[57], tctbl[58], tctbl[59],
1476  tctbl[60], tctbl[61], tctbl[62], tctbl[63]);
1477 
1478  vlib_cli_output (vm, " Port:");
1479  vlib_cli_output (vm, " Rate = %u bytes/second", cfg->port.rate);
1480  vlib_cli_output (vm, " MTU = %u bytes", cfg->port.mtu);
1481  vlib_cli_output (vm, " Frame overhead = %u bytes",
1482  cfg->port.frame_overhead);
1483  vlib_cli_output (vm, " Number of subports = %u",
1484  cfg->port.n_subports_per_port);
1485  vlib_cli_output (vm, " Number of pipes per subport = %u",
1486  cfg->port.n_pipes_per_subport);
1487  vlib_cli_output (vm,
1488  " Packet queue size: TC0 = %u, TC1 = %u, TC2 = %u, TC3 = %u packets",
1489  cfg->port.qsize[0], cfg->port.qsize[1], cfg->port.qsize[2],
1490  cfg->port.qsize[3]);
1491  vlib_cli_output (vm, " Number of pipe profiles = %u",
1492  cfg->port.n_pipe_profiles);
1493 
1494  for (profile_id = 0; profile_id < vec_len (cfg->pipe); profile_id++)
1495  {
1496  vlib_cli_output (vm, " Pipe profile %u:", profile_id);
1497  vlib_cli_output (vm, " Rate = %u bytes/second",
1498  cfg->pipe[profile_id].tb_rate);
1499  vlib_cli_output (vm, " Token bucket size = %u bytes",
1500  cfg->pipe[profile_id].tb_size);
1501  vlib_cli_output (vm,
1502  " Traffic class rate: TC0 = %u, TC1 = %u, TC2 = %u, TC3 = %u bytes/second",
1503  cfg->pipe[profile_id].tc_rate[0],
1504  cfg->pipe[profile_id].tc_rate[1],
1505  cfg->pipe[profile_id].tc_rate[2],
1506  cfg->pipe[profile_id].tc_rate[3]);
1507  vlib_cli_output (vm, " TC period = %u milliseconds",
1508  cfg->pipe[profile_id].tc_period);
1509 #ifdef RTE_SCHED_SUBPORT_TC_OV
1510  vlib_cli_output (vm, " TC3 oversubscription_weight = %u",
1511  cfg->pipe[profile_id].tc_ov_weight);
1512 #endif
1513 
1514  for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++)
1515  {
1516  vlib_cli_output (vm,
1517  " TC%u WRR weights: Q0 = %u, Q1 = %u, Q2 = %u, Q3 = %u",
1518  i, cfg->pipe[profile_id].wrr_weights[i * 4],
1519  cfg->pipe[profile_id].wrr_weights[i * 4 + 1],
1520  cfg->pipe[profile_id].wrr_weights[i * 4 + 2],
1521  cfg->pipe[profile_id].wrr_weights[i * 4 + 3]);
1522  }
1523  }
1524 
1525 #ifdef RTE_SCHED_RED
1526  vlib_cli_output (vm, " Weighted Random Early Detection (WRED):");
1527  for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++)
1528  {
1529  vlib_cli_output (vm, " TC%u min: G = %u, Y = %u, R = %u", i,
1530  cfg->port.red_params[i][e_RTE_METER_GREEN].min_th,
1531  cfg->port.red_params[i][e_RTE_METER_YELLOW].min_th,
1532  cfg->port.red_params[i][e_RTE_METER_RED].min_th);
1533 
1534  vlib_cli_output (vm, " TC%u max: G = %u, Y = %u, R = %u", i,
1535  cfg->port.red_params[i][e_RTE_METER_GREEN].max_th,
1536  cfg->port.red_params[i][e_RTE_METER_YELLOW].max_th,
1537  cfg->port.red_params[i][e_RTE_METER_RED].max_th);
1538 
1539  vlib_cli_output (vm,
1540  " TC%u inverted probability: G = %u, Y = %u, R = %u",
1541  i, cfg->port.red_params[i][e_RTE_METER_GREEN].maxp_inv,
1542  cfg->port.red_params[i][e_RTE_METER_YELLOW].maxp_inv,
1543  cfg->port.red_params[i][e_RTE_METER_RED].maxp_inv);
1544 
1545  vlib_cli_output (vm, " TC%u weight: R = %u, Y = %u, R = %u", i,
1546  cfg->port.red_params[i][e_RTE_METER_GREEN].wq_log2,
1547  cfg->port.red_params[i][e_RTE_METER_YELLOW].wq_log2,
1548  cfg->port.red_params[i][e_RTE_METER_RED].wq_log2);
1549  }
1550 #endif
1551 
1552  return 0;
1553 }
1554 
1555 /* *INDENT-OFF* */
1556 VLIB_CLI_COMMAND (cmd_show_dpdk_if_hqos, static) = {
1557  .path = "show dpdk interface hqos",
1558  .short_help = "show dpdk interface hqos <if-name>",
1559  .function = show_dpdk_if_hqos,
1560 };
1561 /* *INDENT-ON* */
1562 
1563 clib_error_t *
1565 {
1566  return 0;
1567 }
1568 
1570 
1571 /*
1572  * fd.io coding-style-patch-verification: ON
1573  *
1574  * Local Variables:
1575  * eval: (c-set-style "gnu")
1576  * End:
1577  */
unformat_function_t unformat_vnet_hw_interface
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:396
vmrglw vmrglh hi
u16 enabled
Definition: dpdk.h:299
char * file_name
File name of pcap output.
Definition: pcap.h:124
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:343
uword unformat(unformat_input_t *i, char *fmt,...)
Definition: unformat.c:966
static void show_dpdk_device_stats(vlib_main_t *vm, dpdk_device_t *xd)
Definition: cli.c:260
u32 n_packets_to_capture
Number of packets to capture.
Definition: pcap.h:127
u16 max_burst_sz
Definition: dpdk.h:138
dpdk_main_t dpdk_main
Definition: dpdk.h:476
static clib_error_t * show_dpdk_if_placement(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:739
#define VLIB_EFD_DISCARD_ENABLED
Definition: threads.h:246
int dpdk_hqos_validate_mask(u64 mask, u32 n)
Definition: hqos.c:171
u8 use_rss
Definition: dpdk.h:453
u64 last_poll_time
Definition: dpdk.h:142
static clib_error_t * set_dpdk_if_placement(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:796
#define UNFORMAT_END_OF_INPUT
Definition: format.h:143
static clib_error_t * set_dpdk_if_hqos_placement(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:927
#define NULL
Definition: clib.h:55
u16 flags
Definition: dpdk.h:215
static vnet_hw_interface_t * vnet_get_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:482
dpdk_device_and_queue_t ** devices_by_hqos_cpu
Definition: dpdk.h:408
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
Definition: vec.h:521
static clib_error_t * parse_op_and_prec(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd, char *prec_type, u8 *prec_bitmap)
Definition: cli.c:457
struct rte_sched_port_params port
Definition: dpdk.h:330
vlib_buffer_main_t * buffer_main
Definition: main.h:104
vlib_worker_thread_t * vlib_worker_threads
Definition: threads.h:112
struct rte_sched_port * hqos
Definition: dpdk.h:183
unformat_function_t unformat_vnet_sw_interface
static clib_error_t * show_dpdk_buffer(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:161
#define clib_error_report(e)
Definition: error.h:125
u32 congestion_cnt
Definition: dpdk.h:141
u8 * pcap_filename
Definition: dpdk.h:434
#define DPDK_DEVICE_FLAG_PMD
Definition: dpdk.h:218
clib_error_t * dpdk_port_setup(dpdk_main_t *dm, dpdk_device_t *xd)
Definition: init.c:65
u8 mpls_exp_bitmap
Definition: threads.h:257
struct rte_sched_pipe_params * pipe
Definition: dpdk.h:332
void * dpdk_input_efd_multiarch_select()
vlib_node_function_t * function
Definition: node.h:416
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:111
vlib_node_registration_t dpdk_input_node
(constructor) VLIB_REGISTER_NODE (dpdk_input_node)
Definition: node.c:707
dpdk_device_config_t default_devconf
Definition: dpdk.h:394
u32 pcap_pkts_to_capture
Definition: dpdk.h:436
u16 queue_hi_thresh
Definition: threads.h:255
int input_cpu_first_index
Definition: dpdk.h:456
static clib_error_t * set_dpdk_if_hqos_subport(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:1066
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
static void unformat_free(unformat_input_t *i)
Definition: format.h:161
unsigned long u64
Definition: types.h:89
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:977
vlib_frame_queue_t ** vlib_frame_queues
Definition: threads.h:144
u32 device_index
Definition: dpdk.h:197
static clib_error_t * show_dpdk_if_hqos(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:1361
dpdk_device_hqos_per_worker_thread_t * hqos_wt
Definition: dpdk.h:240
#define VLIB_EFD_MONITOR_ENABLED
Definition: threads.h:247
void * dpdk_input_multiarch_select()
static heap_elt_t * first(heap_header_t *h)
Definition: heap.c:59
u32 pcap_sw_if_index
Definition: dpdk.h:435
u16 consec_full_frames_hi_thresh
Definition: dpdk.h:301
vlib_main_t ** vlib_mains
Definition: dpdk_buffer.c:157
char * name
Definition: main.h:98
static clib_error_t * pcap_trace_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:29
#define hash_get(h, key)
Definition: hash.h:248
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:369
volatile u64 head
Definition: threads.h:126
dpdk_device_and_queue_t ** devices_by_cpu
Definition: dpdk.h:407
u64 max_poll_delay
Definition: dpdk.h:143
static clib_error_t * clear_efd(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:411
u32 consec_full_frames_cnt
Definition: dpdk.h:140
static clib_error_t * set_dpdk_if_hqos_pipe(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:1005
u32 vlib_hw_if_index
Definition: dpdk.h:199
#define DPDK_EFD_DISCARD_ENABLED
Definition: dpdk.h:290
pcap_main_t pcap_main
Definition: dpdk.h:433
u16 last_burst_sz
Definition: dpdk.h:137
#define DPDK_EFD_MONITOR_ENABLED
Definition: dpdk.h:291
#define vec_del1(v, i)
Delete the element at index I.
Definition: vec.h:765
u32 full_frames_cnt
Definition: dpdk.h:139
int input_cpu_count
Definition: dpdk.h:457
u16 nb_rx_desc
Definition: dpdk.h:234
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:575
static clib_error_t * set_dpdk_if_hqos_pktfield(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:1211
struct rte_mempool ** pktmbuf_pools
Definition: buffer.h:324
volatile u64 tail
Definition: threads.h:117
dpdk_device_t * devices
Definition: dpdk.h:406
u8 ip_prec_bitmap
Definition: threads.h:256
u16 * cpu_socket_id_by_queue
Definition: dpdk.h:235
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:300
static clib_error_t * test_dpdk_buffer(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:198
dpdk_device_config_t * dev_confs
Definition: dpdk.h:395
static vlib_thread_main_t * vlib_get_thread_main()
Definition: global_funcs.h:32
u16 queue_hi_thresh
Definition: dpdk.h:300
u8 vlan_cos_bitmap
Definition: threads.h:258
static vlib_node_runtime_t * vlib_node_get_runtime(vlib_main_t *vm, u32 node_index)
Get node runtime by node index.
Definition: node_funcs.h:88
static int dpdk_device_queue_sort(void *a1, void *a2)
Definition: cli.c:778
clib_error_t * pcap_write(pcap_main_t *pm)
Write PCAP file.
Definition: pcap.c:89
static clib_error_t * set_dpdk_if_desc(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:673
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:154
#define EFD_OPERATION_GREATER_OR_EQUAL
Definition: dpdk.h:581
u32 discard_cnt
Definition: dpdk.h:144
#define ASSERT(truth)
unsigned int u32
Definition: types.h:88
int hqos_cpu_count
Definition: dpdk.h:461
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
static clib_error_t * show_dpdk_if_hqos_placement(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:889
void * dpdk_input_rss_multiarch_select()
dpdk_efd_t efd
Definition: dpdk.h:445
void vlib_buffer_free(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Free buffers Frees the entire buffer chain for each buffer.
Definition: dpdk_buffer.c:766
static clib_error_t * set_dpdk_if_hqos_tctbl(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:1144
dpdk_device_hqos_per_hqos_thread_t * hqos_ht
Definition: dpdk.h:241
static void vlib_node_set_state(vlib_main_t *vm, u32 node_index, vlib_node_state_t new_state)
Set node dispatch state.
Definition: node_funcs.h:146
uword * thread_registrations_by_name
Definition: threads.h:285
u32 vlib_buffer_alloc(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Allocate buffers into supplied array.
Definition: dpdk_buffer.c:643
#define DPDK_NB_RX_DESC_10GE
Definition: dpdk_priv.h:20
u64 uword
Definition: types.h:112
static clib_error_t * show_efd(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:321
pcap_packet_type_t packet_type
Packet type.
Definition: pcap.h:130
u32 enqueue_full_events
Definition: threads.h:121
static clib_error_t * set_efd(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:513
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
unsigned char u8
Definition: types.h:56
dpdk_efd_agent_t efd_agent
Definition: dpdk.h:257
#define DPDK_EFD_DROPALL_ENABLED
Definition: dpdk.h:292
void set_efd_bitmap(u8 *bitmap, u32 value, u32 op)
Definition: node.c:741
#define vec_sort_with_function(vec, f)
Sort a vector using the supplied element comparison function.
Definition: vec.h:920
u32 enqueue_efd_discards
Definition: threads.h:122
volatile u64 head_hint
Definition: threads.h:135
#define hash_get_mem(h, key)
Definition: hash.h:268
struct clib_bihash_value offset
template key/value backing page structure
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:169
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:418
int hqos_cpu_first_index
Definition: dpdk.h:460
#define vec_foreach(var, vec)
Vector iterator.
#define EFD_OPERATION_LESS_THAN
Definition: dpdk.h:580
u32 total_packet_cnt
Definition: dpdk.h:145
#define clib_error_return(e, args...)
Definition: error.h:111
struct _unformat_input_t unformat_input_t
int tx_pcap_enable
Definition: dpdk.h:432
vnet_main_t * vnet_main
Definition: dpdk.h:472
u16 nb_tx_desc
Definition: dpdk.h:223
unformat_function_t unformat_line_input
Definition: format.h:281
uword * device_config_index_by_pci_addr
Definition: dpdk.h:396
static void show_efd_config(vlib_main_t *vm)
Definition: cli.c:289
u32 n_packets_captured
Number of packets currently captured.
Definition: pcap.h:133
u16 enabled
Definition: threads.h:254
vlib_efd_t efd
Definition: threads.h:322
CLIB vectors are ubiquitous dynamically resized arrays with by user defined "headers".
clib_error_t * dpdk_cli_init(vlib_main_t *vm)
Definition: cli.c:1564
dpdk_config_main_t * conf
Definition: dpdk.h:473