]> git.droids-corp.org - dpdk.git/commitdiff
app/testpmd: add mempool with external data buffers
authorViacheslav Ovsiienko <viacheslavo@mellanox.com>
Mon, 20 Jan 2020 19:16:25 +0000 (19:16 +0000)
committerThomas Monjalon <thomas@monjalon.net>
Mon, 20 Jan 2020 22:37:49 +0000 (23:37 +0100)
The new mbuf pool type is added to testpmd. To engage the
mbuf pool with externally attached data buffers the parameter
"--mp-alloc=xbuf" should be specified in testpmd command line.

The objective of this patch is just to test whether mbuf pool
with externally attached data buffers works OK. The memory for
data buffers is allocated from DPDK memory, so this is not
"true" external memory from some physical device (this is
supposed the most common use case for such kind of mbuf pool).

The user should be aware that not all drivers support the mbuf
with EXT_ATTACHED_BUF flags set in newly allocated mbuf (many
PMDs just overwrite ol_flags field and flag value is getting
lost).

Signed-off-by: Viacheslav Ovsiienko <viacheslavo@mellanox.com>
Acked-by: Olivier Matz <olivier.matz@6wind.com>
app/test-pmd/config.c
app/test-pmd/flowgen.c
app/test-pmd/parameters.c
app/test-pmd/testpmd.c
app/test-pmd/testpmd.h
app/test-pmd/txonly.c

index 52f1d9d928afbe2764054b841f125eb151176d1a..9669cbd4cb8f7634792944fb957e20f645fcc359 100644 (file)
@@ -2422,6 +2422,8 @@ mp_alloc_to_str(uint8_t mode)
                return "xmem";
        case MP_ALLOC_XMEM_HUGE:
                return "xmemhuge";
+       case MP_ALLOC_XBUF:
+               return "xbuf";
        default:
                return "invalid";
        }
index 03b72aaa56e21c3c5180f30269ff92b5599489c8..ae50cdc9de933484a40e5dcdfbdaab12c485fcb6 100644 (file)
@@ -199,7 +199,8 @@ pkt_burst_flow_gen(struct fwd_stream *fs)
                                                           sizeof(*ip_hdr));
                pkt->nb_segs            = 1;
                pkt->pkt_len            = pkt_size;
-               pkt->ol_flags           = ol_flags;
+               pkt->ol_flags           &= EXT_ATTACHED_MBUF;
+               pkt->ol_flags           |= ol_flags;
                pkt->vlan_tci           = vlan_tci;
                pkt->vlan_tci_outer     = vlan_tci_outer;
                pkt->l2_len             = sizeof(struct rte_ether_hdr);
index 2e7a504415f32758b0eca5895a403d2cdede0d6b..6340104d33d32b006d7d5db385946ec9da5b9125 100644 (file)
@@ -841,6 +841,8 @@ launch_args_parse(int argc, char** argv)
                                        mp_alloc_type = MP_ALLOC_XMEM;
                                else if (!strcmp(optarg, "xmemhuge"))
                                        mp_alloc_type = MP_ALLOC_XMEM_HUGE;
+                               else if (!strcmp(optarg, "xbuf"))
+                                       mp_alloc_type = MP_ALLOC_XBUF;
                                else
                                        rte_exit(EXIT_FAILURE,
                                                "mp-alloc %s invalid - must be: "
index 38dbb12a8f64a4fec3e9f15673ef7ff8cb959d66..f9f4cd1d3d6b33bcbbcbd2b0934e2b0d45c2d385 100644 (file)
@@ -78,6 +78,7 @@
 #endif
 
 #define EXTMEM_HEAP_NAME "extmem"
+#define EXTBUF_ZONE_SIZE RTE_PGSIZE_2M
 
 uint16_t verbose_level = 0; /**< Silent by default. */
 int testpmd_logtype; /**< Log type for testpmd logs */
@@ -868,6 +869,66 @@ dma_map_cb(struct rte_mempool *mp __rte_unused, void *opaque __rte_unused,
        }
 }
 
+static unsigned int
+setup_extbuf(uint32_t nb_mbufs, uint16_t mbuf_sz, unsigned int socket_id,
+           char *pool_name, struct rte_pktmbuf_extmem **ext_mem)
+{
+       struct rte_pktmbuf_extmem *xmem;
+       unsigned int ext_num, zone_num, elt_num;
+       uint16_t elt_size;
+
+       elt_size = RTE_ALIGN_CEIL(mbuf_sz, RTE_CACHE_LINE_SIZE);
+       elt_num = EXTBUF_ZONE_SIZE / elt_size;
+       zone_num = (nb_mbufs + elt_num - 1) / elt_num;
+
+       xmem = malloc(sizeof(struct rte_pktmbuf_extmem) * zone_num);
+       if (xmem == NULL) {
+               TESTPMD_LOG(ERR, "Cannot allocate memory for "
+                                "external buffer descriptors\n");
+               *ext_mem = NULL;
+               return 0;
+       }
+       for (ext_num = 0; ext_num < zone_num; ext_num++) {
+               struct rte_pktmbuf_extmem *xseg = xmem + ext_num;
+               const struct rte_memzone *mz;
+               char mz_name[RTE_MEMZONE_NAMESIZE];
+               int ret;
+
+               ret = snprintf(mz_name, sizeof(mz_name),
+                       RTE_MEMPOOL_MZ_FORMAT "_xb_%u", pool_name, ext_num);
+               if (ret < 0 || ret >= (int)sizeof(mz_name)) {
+                       errno = ENAMETOOLONG;
+                       ext_num = 0;
+                       break;
+               }
+               mz = rte_memzone_reserve_aligned(mz_name, EXTBUF_ZONE_SIZE,
+                                                socket_id,
+                                                RTE_MEMZONE_IOVA_CONTIG |
+                                                RTE_MEMZONE_1GB |
+                                                RTE_MEMZONE_SIZE_HINT_ONLY,
+                                                EXTBUF_ZONE_SIZE);
+               if (mz == NULL) {
+                       /*
+                        * The caller exits on external buffer creation
+                        * error, so there is no need to free memzones.
+                        */
+                       errno = ENOMEM;
+                       ext_num = 0;
+                       break;
+               }
+               xseg->buf_ptr = mz->addr;
+               xseg->buf_iova = mz->iova;
+               xseg->buf_len = EXTBUF_ZONE_SIZE;
+               xseg->elt_size = elt_size;
+       }
+       if (ext_num == 0 && xmem != NULL) {
+               free(xmem);
+               xmem = NULL;
+       }
+       *ext_mem = xmem;
+       return ext_num;
+}
+
 /*
  * Configuration initialisation done once at init time.
  */
@@ -936,6 +997,26 @@ mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
                                        heap_socket);
                        break;
                }
+       case MP_ALLOC_XBUF:
+               {
+                       struct rte_pktmbuf_extmem *ext_mem;
+                       unsigned int ext_num;
+
+                       ext_num = setup_extbuf(nb_mbuf, mbuf_seg_size,
+                                              socket_id, pool_name, &ext_mem);
+                       if (ext_num == 0)
+                               rte_exit(EXIT_FAILURE,
+                                        "Can't create pinned data buffers\n");
+
+                       TESTPMD_LOG(INFO, "preferred mempool ops selected: %s\n",
+                                       rte_mbuf_best_mempool_ops());
+                       rte_mp = rte_pktmbuf_pool_create_extbuf
+                                       (pool_name, nb_mbuf, mb_mempool_cache,
+                                        0, mbuf_seg_size, socket_id,
+                                        ext_mem, ext_num);
+                       free(ext_mem);
+                       break;
+               }
        default:
                {
                        rte_exit(EXIT_FAILURE, "Invalid mempool creation mode\n");
index 7cf48d005b5f58800dd6d9776b0c8ae20c01ab22..3dd5fc750bd58f777d0fe63f2c0927954deed3fe 100644 (file)
@@ -76,8 +76,10 @@ enum {
        /**< allocate mempool natively, but populate using anonymous memory */
        MP_ALLOC_XMEM,
        /**< allocate and populate mempool using anonymous memory */
-       MP_ALLOC_XMEM_HUGE
+       MP_ALLOC_XMEM_HUGE,
        /**< allocate and populate mempool using anonymous hugepage memory */
+       MP_ALLOC_XBUF
+       /**< allocate mempool natively, use rte_pktmbuf_pool_create_extbuf */
 };
 
 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
index 3caf281cb813e899db706d4101db054546071fad..871cf6c1547f51e4d443959715960393860007bd 100644 (file)
@@ -170,7 +170,8 @@ pkt_burst_prepare(struct rte_mbuf *pkt, struct rte_mempool *mbp,
 
        rte_pktmbuf_reset_headroom(pkt);
        pkt->data_len = tx_pkt_seg_lengths[0];
-       pkt->ol_flags = ol_flags;
+       pkt->ol_flags &= EXT_ATTACHED_MBUF;
+       pkt->ol_flags |= ol_flags;
        pkt->vlan_tci = vlan_tci;
        pkt->vlan_tci_outer = vlan_tci_outer;
        pkt->l2_len = sizeof(struct rte_ether_hdr);