From: Gregory Etelson <[email protected]>

Add support for selective Rx using existing rxpkts and mbuf-size
command line parameters.

When a segment is specified with rxpkts and a matching 0 mbuf-size
on PMDs supporting selective Rx,
testpmd set the mempool of the segment to NULL,
meaning the segment won't be received.

Example usage to receive only Ethernet header and 64 bytes at offset 128:

  --rxpkts=14,114,64,0 --mbuf-size=256,0,256,0

This creates segments:
- [0-13]: 14 bytes with mempool (received)
- [14-127]: 114 bytes with NULL mempool (discarded)
- [128-191]: 64 bytes with mempool (received)
- [192-max]: remaining bytes with NULL mempool (discarded)

If the first segment has no mempool,
there will be no mempool created with the index 0.
That's why the lookup of the first mempool is now achieved
in the new function mbuf_pool_find_first(socket)
instead of mbuf_pool_find(socket, index 0)

Note: RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT is required for this feature
and is checked at ethdev API level.
This check is removed from testpmd to allow negative testing of the API.

Signed-off-by: Gregory Etelson <[email protected]>
Signed-off-by: Thomas Monjalon <[email protected]>
---
 app/test-pmd/cmdline.c                      |  2 +-
 app/test-pmd/parameters.c                   |  5 +--
 app/test-pmd/testpmd.c                      | 48 +++++++++++++--------
 app/test-pmd/testpmd.h                      | 16 +++++++
 doc/guides/testpmd_app_ug/run_app.rst       | 16 +++++++
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  3 +-
 6 files changed, 66 insertions(+), 24 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index cc9c462498..3c39e27aa8 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -3076,7 +3076,7 @@ cmd_setup_rxtx_queue_parsed(
                if (!numa_support || socket_id == NUMA_NO_CONFIG)
                        socket_id = port->socket_id;
 
-               mp = mbuf_pool_find(socket_id, 0);
+               mp = mbuf_pool_find_first(socket_id);
                if (mp == NULL) {
                        fprintf(stderr,
                                "Failed to setup RX queue: No mempool 
allocation on the socket %d\n",
diff --git a/app/test-pmd/parameters.c b/app/test-pmd/parameters.c
index ecbd618f00..337d8fc8ac 100644
--- a/app/test-pmd/parameters.c
+++ b/app/test-pmd/parameters.c
@@ -1170,10 +1170,9 @@ launch_args_parse(int argc, char** argv)
                                rte_exit(EXIT_FAILURE,
                                        "bad mbuf-size\n");
                        for (i = 0; i < nb_segs; i++) {
-                               if (mb_sz[i] <= 0 || mb_sz[i] > 0xFFFF)
+                               if (mb_sz[i] > 0xFFFF)
                                        rte_exit(EXIT_FAILURE,
-                                               "mbuf-size should be "
-                                               "> 0 and < 65536\n");
+                                               "mbuf-size should be < 
65536\n");
                                mbuf_data_size[i] = (uint16_t) mb_sz[i];
                        }
                        mbuf_data_size_n = nb_segs;
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index a9b35f530a..fcd8a90967 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -1806,19 +1806,25 @@ init_config(void)
                uint8_t i, j;
 
                for (i = 0; i < num_sockets; i++)
-                       for (j = 0; j < mbuf_data_size_n; j++)
+                       for (j = 0; j < mbuf_data_size_n; j++) {
+                               if (mbuf_data_size[j] == 0)
+                                       continue;
                                mempools[i * MAX_SEGS_BUFFER_SPLIT + j] =
                                        mbuf_pool_create(mbuf_data_size[j],
                                                          nb_mbuf_per_pool,
                                                          socket_ids[i], j);
+                       }
        } else {
                uint8_t i;
 
-               for (i = 0; i < mbuf_data_size_n; i++)
+               for (i = 0; i < mbuf_data_size_n; i++) {
+                       if (mbuf_data_size[i] == 0)
+                               continue;
                        mempools[i] = mbuf_pool_create
                                        (mbuf_data_size[i],
                                         nb_mbuf_per_pool,
                                         SOCKET_ID_ANY, i);
+               }
        }
 
        init_port_config();
@@ -1831,11 +1837,11 @@ init_config(void)
         * Records which Mbuf pool to use by each logical core, if needed.
         */
        for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
-               mbp = mbuf_pool_find(
-                       rte_lcore_to_socket_id(fwd_lcores_cpuids[lc_id]), 0);
+               mbp = mbuf_pool_find_first(
+                       rte_lcore_to_socket_id(fwd_lcores_cpuids[lc_id]));
 
                if (mbp == NULL)
-                       mbp = mbuf_pool_find(0, 0);
+                       mbp = mbuf_pool_find_first(0);
                fwd_lcores[lc_id]->mbp = mbp;
 #ifdef RTE_LIB_GSO
                /* initialize GSO context */
@@ -2744,31 +2750,35 @@ rx_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
        uint32_t prev_hdrs = 0;
        int ret;
 
-       if ((rx_pkt_nb_segs > 1) &&
-           (rx_conf->offloads & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT)) {
+       if (multi_rx_mempool == 0 &&
+           (rx_pkt_nb_segs > 1 || mbuf_data_size_n > 1)) {
+               unsigned int nb_segs = RTE_MAX(rx_pkt_nb_segs, 
(uint8_t)mbuf_data_size_n);
+
                /* multi-segment configuration */
-               for (i = 0; i < rx_pkt_nb_segs; i++) {
+               for (i = 0; i < nb_segs; i++) {
                        struct rte_eth_rxseg_split *rx_seg = &rx_useg[i].split;
                        /*
                         * Use last valid pool for the segments with number
                         * exceeding the pool index.
                         */
                        mp_n = (i >= mbuf_data_size_n) ? mbuf_data_size_n - 1 : 
i;
-                       mpx = mbuf_pool_find(socket_id, mp_n);
-                       /* Handle zero as mbuf data buffer size. */
                        rx_seg->offset = i < rx_pkt_nb_offs ?
                                           rx_pkt_seg_offsets[i] : 0;
-                       rx_seg->mp = mpx ? mpx : mp;
+                       if (mbuf_data_size[mp_n] == 0) {
+                               rx_seg->mp = NULL;
+                       } else {
+                               mpx = mbuf_pool_find(socket_id, mp_n);
+                               rx_seg->mp = mpx ? mpx : mp;
+                       }
                        if (rx_pkt_hdr_protos[i] != 0 && rx_pkt_seg_lengths[i] 
== 0) {
                                rx_seg->proto_hdr = rx_pkt_hdr_protos[i] & 
~prev_hdrs;
                                prev_hdrs |= rx_seg->proto_hdr;
                        } else {
-                               rx_seg->length = rx_pkt_seg_lengths[i] ?
-                                               rx_pkt_seg_lengths[i] :
-                                               mbuf_data_size[mp_n];
+                               rx_seg->length = i < rx_pkt_nb_segs ?
+                                               rx_pkt_seg_lengths[i] : 0;
                        }
                }
-               rx_conf->rx_nseg = rx_pkt_nb_segs;
+               rx_conf->rx_nseg = nb_segs;
                rx_conf->rx_seg = rx_useg;
                rx_conf->rx_mempools = NULL;
                rx_conf->rx_nmempool = 0;
@@ -3126,8 +3136,8 @@ start_port(portid_t pid)
                                if ((numa_support) &&
                                        (rxring_numa[pi] != NUMA_NO_CONFIG)) {
                                        struct rte_mempool * mp =
-                                               mbuf_pool_find
-                                                       (rxring_numa[pi], 0);
+                                               mbuf_pool_find_first
+                                                       (rxring_numa[pi]);
                                        if (mp == NULL) {
                                                fprintf(stderr,
                                                        "Failed to setup RX 
queue: No mempool allocation on the socket %d\n",
@@ -3142,9 +3152,9 @@ start_port(portid_t pid)
                                             mp);
                                } else {
                                        struct rte_mempool *mp =
-                                               mbuf_pool_find
+                                               mbuf_pool_find_first
                                                        ((numa_support ? 
port->socket_id :
-                                                       (unsigned 
int)SOCKET_ID_ANY), 0);
+                                                       (unsigned 
int)SOCKET_ID_ANY));
                                        if (mp == NULL) {
                                                fprintf(stderr,
                                                        "Failed to setup RX 
queue: No mempool allocation on the socket %d\n",
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 1a54535470..3d4b36d668 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -895,6 +895,22 @@ mbuf_pool_find(unsigned int sock_id, uint16_t idx)
        return rte_mempool_lookup((const char *)pool_name);
 }
 
+static inline struct rte_mempool *
+mbuf_pool_find_first(unsigned int sock_id)
+{
+       struct rte_mempool *mp;
+       uint16_t idx;
+
+       for (idx = 0; idx < mbuf_data_size_n; idx++) {
+               if (mbuf_data_size[idx] == 0) /* no mempool with this index */
+                       continue;
+               mp = mbuf_pool_find(sock_id, idx);
+               if (mp != NULL)
+                       return mp;
+       }
+       return NULL;
+}
+
 static inline uint16_t
 common_fwd_stream_receive(struct fwd_stream *fs, struct rte_mbuf **burst,
        unsigned int nb_pkts)
diff --git a/doc/guides/testpmd_app_ug/run_app.rst 
b/doc/guides/testpmd_app_ug/run_app.rst
index 1a4a4b6c12..d654484546 100644
--- a/doc/guides/testpmd_app_ug/run_app.rst
+++ b/doc/guides/testpmd_app_ug/run_app.rst
@@ -127,6 +127,7 @@ The command line options are:
     The default value is 2048. If multiple mbuf-size values are specified the
     extra memory pools will be created for allocating mbufs to receive packets
     with buffer splitting features.
+    A value of 0 indicates a discarded segment in buffer split.
 
 *   ``--total-num-mbufs=N``
 
@@ -372,6 +373,21 @@ The command line options are:
     Optionally the multiple memory pools can be specified with --mbuf-size
     command line parameter and the mbufs to receive will be allocated
     sequentially from these extra memory pools.
+    A length of 0 means maximum length: rest of the segment
+    or all remaining packet data in case of a discard segment.
+
+    To receive only the Ethernet header (14 bytes)
+    and a 64-byte segment starting at offset 128,
+    while discarding the rest::
+
+       --rxpkts=14,114,64,0 --mbuf-size=256,0,256,0
+
+    This configuration will:
+
+    * Receive 14 bytes (Ethernet header)
+    * Discard 114 bytes (NULL mempool segment)
+    * Receive 64 bytes
+    * Discard remaining bytes (NULL mempool segment, length=0)
 
 *   ``--txpkts=X[,Y]``
 
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst 
b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index d50921258a..f0f2b0758b 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -850,7 +850,8 @@ mbuf for remaining segments will be allocated from the last 
valid pool).
    testpmd> set rxpkts (x[,y]*)
 
 Where x[,y]* represents a CSV list of values, without white space. Zero value
-means to use the corresponding memory pool data buffer size.
+means to use the corresponding memory pool data buffer size,
+or to discard all remaining packet data for a discard segment (mbuf-size=0).
 
 set rxhdrs
 ~~~~~~~~~~
-- 
2.54.0

Reply via email to