"show (rxq|txq) info (port_id) (queue_id)\n"
" Display information for configured RX/TX queue.\n\n"
- "show config (rxtx|cores|fwd|rxpkts|txpkts)\n"
+ "show config (rxtx|cores|fwd|rxoffs|rxpkts|txpkts)\n"
" Display the given configuration.\n\n"
"read rxd (port_id) (queue_id) (rxd_id)\n"
" Set the transmit delay time and number of retries,"
" effective when retry is enabled.\n\n"
+ "set rxoffs (x[,y]*)\n"
+ " Set the offset of each packet segment on"
+ " receiving if split feature is engaged."
+ " Affects only the queues configured with split"
+ " offloads.\n\n"
+
"set rxpkts (x[,y]*)\n"
" Set the length of each segment to scatter"
" packets on receiving if split feature is engaged."
},
};
+/* *** SET SEGMENT OFFSETS OF RX PACKETS SPLIT *** */
+
+struct cmd_set_rxoffs_result {
+ cmdline_fixed_string_t cmd_keyword;
+ cmdline_fixed_string_t rxoffs;
+ cmdline_fixed_string_t seg_offsets;
+};
+
+static void
+cmd_set_rxoffs_parsed(void *parsed_result,
+ __rte_unused struct cmdline *cl,
+ __rte_unused void *data)
+{
+ struct cmd_set_rxoffs_result *res;
+ unsigned int seg_offsets[MAX_SEGS_BUFFER_SPLIT];
+ unsigned int nb_segs;
+
+ res = parsed_result;
+ nb_segs = parse_item_list(res->seg_offsets, "segment offsets",
+ MAX_SEGS_BUFFER_SPLIT, seg_offsets, 0);
+ if (nb_segs > 0)
+ set_rx_pkt_offsets(seg_offsets, nb_segs);
+}
+
+cmdline_parse_token_string_t cmd_set_rxoffs_keyword =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_rxoffs_result,
+ cmd_keyword, "set");
+cmdline_parse_token_string_t cmd_set_rxoffs_name =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_rxoffs_result,
+ rxoffs, "rxoffs");
+cmdline_parse_token_string_t cmd_set_rxoffs_offsets =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_rxoffs_result,
+ seg_offsets, NULL);
+
+cmdline_parse_inst_t cmd_set_rxoffs = {
+ .f = cmd_set_rxoffs_parsed,
+ .data = NULL,
+ .help_str = "set rxoffs <len0[,len1]*>",
+ .tokens = {
+ (void *)&cmd_set_rxoffs_keyword,
+ (void *)&cmd_set_rxoffs_name,
+ (void *)&cmd_set_rxoffs_offsets,
+ NULL,
+ },
+};
+
/* *** SET SEGMENT LENGTHS OF RX PACKETS SPLIT *** */
struct cmd_set_rxpkts_result {
fwd_lcores_config_display();
else if (!strcmp(res->what, "fwd"))
pkt_fwd_config_display(&cur_fwd_config);
+ else if (!strcmp(res->what, "rxoffs"))
+ show_rx_pkt_offsets();
else if (!strcmp(res->what, "rxpkts"))
show_rx_pkt_segments();
else if (!strcmp(res->what, "txpkts"))
TOKEN_STRING_INITIALIZER(struct cmd_showcfg_result, cfg, "config");
cmdline_parse_token_string_t cmd_showcfg_what =
TOKEN_STRING_INITIALIZER(struct cmd_showcfg_result, what,
- "rxtx#cores#fwd#rxpkts#txpkts#txtimes");
+ "rxtx#cores#fwd#rxoffs#rxpkts#txpkts#txtimes");
cmdline_parse_inst_t cmd_showcfg = {
.f = cmd_showcfg_parsed,
.data = NULL,
- .help_str = "show config rxtx|cores|fwd|rxpkts|txpkts|txtimes",
+ .help_str = "show config rxtx|cores|fwd|rxoffs|rxpkts|txpkts|txtimes",
.tokens = {
(void *)&cmd_showcfg_show,
(void *)&cmd_showcfg_port,
(cmdline_parse_inst_t *)&cmd_reset,
(cmdline_parse_inst_t *)&cmd_set_numbers,
(cmdline_parse_inst_t *)&cmd_set_log,
+ (cmdline_parse_inst_t *)&cmd_set_rxoffs,
(cmdline_parse_inst_t *)&cmd_set_rxpkts,
(cmdline_parse_inst_t *)&cmd_set_txpkts,
(cmdline_parse_inst_t *)&cmd_set_txsplit,
}
}
+void
+show_rx_pkt_offsets(void)
+{
+ uint32_t i, n;
+
+ n = rx_pkt_nb_offs;
+ printf("Number of offsets: %u\n", n);
+ if (n) {
+ printf("Segment offsets: ");
+ for (i = 0; i != n - 1; i++)
+ printf("%hu,", rx_pkt_seg_offsets[i]);
+ printf("%hu\n", rx_pkt_seg_lengths[i]);
+ }
+}
+
+void
+set_rx_pkt_offsets(unsigned int *seg_offsets, unsigned int nb_offs)
+{
+ unsigned int i;
+
+ if (nb_offs >= MAX_SEGS_BUFFER_SPLIT) {
+ printf("nb segments per RX packets=%u >= "
+ "MAX_SEGS_BUFFER_SPLIT - ignored\n", nb_offs);
+ return;
+ }
+
+ /*
+ * No extra check here, the segment length will be checked by PMD
+ * in the extended queue setup.
+ */
+ for (i = 0; i < nb_offs; i++) {
+ if (seg_offsets[i] >= UINT16_MAX) {
+ printf("offset[%u]=%u > UINT16_MAX - give up\n",
+ i, seg_offsets[i]);
+ return;
+ }
+ }
+
+ for (i = 0; i < nb_offs; i++)
+ rx_pkt_seg_offsets[i] = (uint16_t) seg_offsets[i];
+
+ rx_pkt_nb_offs = (uint8_t) nb_offs;
+}
+
void
show_rx_pkt_segments(void)
{
"(0 <= mapping <= %d).\n", RTE_ETHDEV_QUEUE_STAT_CNTRS - 1);
printf(" --no-flush-rx: Don't flush RX streams before forwarding."
" Used mainly with PCAP drivers.\n");
+ printf(" --rxoffs=X[,Y]*: set RX segment offsets for split.\n");
printf(" --rxpkts=X[,Y]*: set RX segment sizes to split.\n");
printf(" --txpkts=X[,Y]*: set TX segment sizes"
" or total packet length.\n");
{ "rx-queue-stats-mapping", 1, 0, 0 },
{ "no-flush-rx", 0, 0, 0 },
{ "flow-isolate-all", 0, 0, 0 },
+ { "rxoffs", 1, 0, 0 },
{ "rxpkts", 1, 0, 0 },
{ "txpkts", 1, 0, 0 },
{ "txonly-multi-flow", 0, 0, 0 },
"invalid RX queue statistics mapping config entered\n");
}
}
+ if (!strcmp(lgopts[opt_idx].name, "rxoffs")) {
+ unsigned int seg_off[MAX_SEGS_BUFFER_SPLIT];
+ unsigned int nb_offs;
+
+ nb_offs = parse_item_list
+ (optarg, "rxpkt offsets",
+ MAX_SEGS_BUFFER_SPLIT,
+ seg_off, 0);
+ if (nb_offs > 0)
+ set_rx_pkt_offsets(seg_off, nb_offs);
+ else
+ rte_exit(EXIT_FAILURE, "bad rxoffs\n");
+ }
if (!strcmp(lgopts[opt_idx].name, "rxpkts")) {
unsigned int seg_len[MAX_SEGS_BUFFER_SPLIT];
unsigned int nb_segs;
*/
uint16_t rx_pkt_seg_lengths[MAX_SEGS_BUFFER_SPLIT];
uint8_t rx_pkt_nb_segs; /**< Number of segments to split */
+uint16_t rx_pkt_seg_offsets[MAX_SEGS_BUFFER_SPLIT];
+uint8_t rx_pkt_nb_offs; /**< Number of specified offsets */
/*
* Configuration of packet segments used by the "txonly" processing engine.
*/
extern uint16_t rx_pkt_seg_lengths[MAX_SEGS_BUFFER_SPLIT];
extern uint8_t rx_pkt_nb_segs; /**< Number of segments to split */
+extern uint16_t rx_pkt_seg_offsets[MAX_SEGS_BUFFER_SPLIT];
+extern uint8_t rx_pkt_nb_offs; /**< Number of specified offsets */
/*
* Configuration of packet segments used by the "txonly" processing engine.
void set_verbose_level(uint16_t vb_level);
void set_rx_pkt_segments(unsigned int *seg_lengths, unsigned int nb_segs);
void show_rx_pkt_segments(void);
+void set_rx_pkt_offsets(unsigned int *seg_offsets, unsigned int nb_offs);
+void show_rx_pkt_offsets(void);
void set_tx_pkt_segments(unsigned int *seg_lengths, unsigned int nb_segs);
void show_tx_pkt_segments(void);
void set_tx_pkt_times(unsigned int *tx_times);
Don't flush the RX streams before starting forwarding. Used mainly with the PCAP PMD.
+* ``--rxoffs=X[,Y]``
+
+ Set the offsets of packet segments on receiving if split
+ feature is engaged. Affects only the queues configured
+ with split offloads (currently BUFFER_SPLIT is supported only).
+
* ``--rxpkts=X[,Y]``
Set the length of segments to scatter packets on receiving if split
Displays the configuration of the application.
The configuration comes from the command-line, the runtime or the application defaults::
- testpmd> show config (rxtx|cores|fwd|rxpkts|txpkts|txtimes)
+ testpmd> show config (rxtx|cores|fwd|rxoffs|rxpkts|txpkts|txtimes)
The available information categories are:
* ``fwd``: Packet forwarding configuration.
+* ``rxoffs``: Packet offsets for RX split.
+
* ``rxpkts``: Packets to RX split configuration.
* ``txpkts``: Packets to TX configuration.
testpmd> set burst tx delay (microseconds) retry (num)
+set rxoffs
+~~~~~~~~~~
+
+Set the offsets of segments relating to the data buffer beginning on receiving
+if split feature is engaged. Affects only the queues configured with split
+offloads (currently BUFFER_SPLIT is supported only).
+
+ testpmd> set rxoffs (x[,y]*)
+
+Where x[,y]* represents a CSV list of values, without white space. If the list
+of offsets is shorter than the list of segments the zero offsets will be used
+for the remaining segments.
+
set rxpkts
~~~~~~~~~~