Signed-off-by: huanggaoyang <[email protected]>
---
 include/odp/api/packet_io.h                        | 15 +++++
 .../linux-generic/include/odp_packet_io_internal.h |  1 +
 platform/linux-generic/include/odp_packet_tap.h    |  5 +-
 platform/linux-generic/odp_packet_io.c             | 16 +++++
 platform/linux-generic/pktio/tap.c                 | 70 ++++++++++++++++++++--
 test/validation/pktio/pktio.c                      | 63 ++++++++++++++++++-
 test/validation/pktio/pktio.h                      |  1 +
 7 files changed, 163 insertions(+), 8 deletions(-)

diff --git a/include/odp/api/packet_io.h b/include/odp/api/packet_io.h
index 42796da..cc7d9d4 100644
--- a/include/odp/api/packet_io.h
+++ b/include/odp/api/packet_io.h
@@ -577,6 +577,21 @@ int odp_pktio_promisc_mode_set(odp_pktio_t pktio, 
odp_bool_t enable);
 int odp_pktio_promisc_mode(odp_pktio_t pktio);
 
 /**
+ * Add an extra packet pool to a packet IO interface.
+ *
+ * When receive packets directly from an interface,
+ * choose the most suitable pool via the packet len.
+ *
+ * @param[in] pktio Packet IO handle.
+ * @param[in] pool  packet pool to be added.
+ *
+ * @retval  0 if operation success.
+ * @retval <0 on failure
+*/
+
+int odp_pktio_add_pool(odp_pktio_t pktio, odp_pool_t pool);
+
+/**
  * Get the default MAC address of a packet IO interface.
  *
  * @param      pktio     Packet IO handle
diff --git a/platform/linux-generic/include/odp_packet_io_internal.h 
b/platform/linux-generic/include/odp_packet_io_internal.h
index f871f0a..1169db5 100644
--- a/platform/linux-generic/include/odp_packet_io_internal.h
+++ b/platform/linux-generic/include/odp_packet_io_internal.h
@@ -165,6 +165,7 @@ typedef struct pktio_if_ops {
                          odp_packet_t packets[], int num);
        int (*send_queue)(pktio_entry_t *entry, int index,
                          odp_packet_t packets[], int num);
+       int (*add_pool)(pktio_entry_t *pktio_entry, odp_pool_t pool);
 } pktio_if_ops_t;
 
 int _odp_packet_cls_enq(pktio_entry_t *pktio_entry, const uint8_t *base,
diff --git a/platform/linux-generic/include/odp_packet_tap.h 
b/platform/linux-generic/include/odp_packet_tap.h
index 7877586..464d3b0 100644
--- a/platform/linux-generic/include/odp_packet_tap.h
+++ b/platform/linux-generic/include/odp_packet_tap.h
@@ -9,13 +9,16 @@
 
 #include <odp/pool.h>
 
+#define ODP_PACK_POOL_MAX      4
+
 typedef struct {
        int fd;                         /**< file descriptor for tap interface*/
        int skfd;                       /**< socket descriptor */
        uint32_t mtu;                   /**< cached mtu */
        unsigned char if_mac[ETH_ALEN]; /**< MAC address of pktio side (not a
                                             MAC address of kernel interface)*/
-       odp_pool_t pool;                /**< pool to alloc packets from */
+       uint32_t pool_num;
+       odp_pool_t pool[ODP_PACK_POOL_MAX]; /**< pool to alloc packets from */
 } pkt_tap_t;
 
 #endif
diff --git a/platform/linux-generic/odp_packet_io.c 
b/platform/linux-generic/odp_packet_io.c
index 27b6553..600f1b4 100644
--- a/platform/linux-generic/odp_packet_io.c
+++ b/platform/linux-generic/odp_packet_io.c
@@ -1296,6 +1296,22 @@ int odp_pktio_send_queue(odp_pktout_queue_t queue, 
odp_packet_t packets[],
        return single_send_queue(entry, queue.index, packets, num);
 }
 
+int odp_pktio_add_pool(odp_pktio_t pktio, odp_pool_t pool)
+{
+       pktio_entry_t *pktio_entry = get_pktio_entry(pktio);
+       int ret = 0;
+
+       if (pktio_entry == NULL)
+               return -1;
+
+       odp_ticketlock_lock(&pktio_entry->s.rxl);
+       if (pktio_entry->s.ops->add_pool)
+               ret = pktio_entry->s.ops->add_pool(pktio_entry, pool);
+       odp_ticketlock_unlock(&pktio_entry->s.rxl);
+
+       return ret;
+}
+
 int single_capability(odp_pktio_capability_t *capa)
 {
        memset(capa, 0, sizeof(odp_pktio_capability_t));
diff --git a/platform/linux-generic/pktio/tap.c 
b/platform/linux-generic/pktio/tap.c
index 1eb4f56..245ab96 100644
--- a/platform/linux-generic/pktio/tap.c
+++ b/platform/linux-generic/pktio/tap.c
@@ -148,7 +148,8 @@ static int tap_pktio_open(odp_pktio_t id ODP_UNUSED,
        tap->fd = fd;
        tap->skfd = skfd;
        tap->mtu = mtu;
-       tap->pool = pool;
+       tap->pool[0] = pool;
+       tap->pool_num = 1;
        return 0;
 sock_err:
        close(skfd);
@@ -178,13 +179,36 @@ static int tap_pktio_close(pktio_entry_t *pktio_entry)
        return ret;
 }
 
-static odp_packet_t pack_odp_pkt(odp_pool_t pool,
+static inline uint32_t get_pool_bufsize(odp_pool_t pool)
+{
+       pool_entry_t *pool_entry = odp_pool_to_entry(pool);
+
+       return pool_entry->s.params.buf.size;
+}
+
+static odp_packet_t packet_alloc_proper(pkt_tap_t *tap, uint32_t len)
+{
+       uint32_t idx;
+       odp_packet_t pkt;
+
+       for (idx = 0; idx < tap->pool_num; idx++) {
+               if (tap->pool[idx] != NULL &&
+                   len <= get_pool_bufsize(tap->pool[idx])) {
+                       pkt = packet_alloc(tap->pool[idx], len, 1);
+                       if (pkt != ODP_PACKET_INVALID)
+                               return pkt;
+               }
+       }
+       return ODP_PACKET_INVALID;
+}
+
+static odp_packet_t pack_odp_pkt(pkt_tap_t *tap,
                                 const void *data,
                                 unsigned int len)
 {
        odp_packet_t pkt;
 
-       pkt = packet_alloc(pool, len, 1);
+       pkt = packet_alloc_proper(tap, len);
 
        if (pkt == ODP_PACKET_INVALID)
                return pkt;
@@ -218,7 +242,7 @@ static int tap_pktio_recv(pktio_entry_t *pktio_entry, 
odp_packet_t pkts[],
                        break;
                }
 
-               pkts[i] = pack_odp_pkt(tap->pool, buf, retval);
+               pkts[i] = pack_odp_pkt(tap, buf, retval);
                if (pkts[i] == ODP_PACKET_INVALID)
                        break;
        }
@@ -309,6 +333,33 @@ static int tap_mac_addr_get(pktio_entry_t *pktio_entry, 
void *mac_addr)
        return ETH_ALEN;
 }
 
+static int tap_add_pool(pktio_entry_t *pktio_entry, odp_pool_t pool)
+{
+       uint32_t idx;
+       uint32_t pool_num = pktio_entry->s.pkt_tap.pool_num;
+       uint32_t bufsize;
+       odp_pool_t tmp;
+       pkt_tap_t *pktap = &pktio_entry->s.pkt_tap;
+
+       if (pool == NULL || pool_num >= ODP_PACK_POOL_MAX)
+               return -1;
+
+       bufsize = get_pool_bufsize(pool);
+
+       pktap->pool[pool_num] = pool;
+       for (idx = pool_num - 1; ; idx--) {
+               if (get_pool_bufsize(pktap->pool[idx]) <= bufsize)
+                       break;
+               tmp = pktap->pool[idx];
+               pktap->pool[idx] = pktap->pool[idx + 1];
+               pktap->pool[idx + 1] = tmp;
+               if (idx == 0)
+                       break;
+       }
+       pktio_entry->s.pkt_tap.pool_num++;
+
+       return 0;
+}
 const pktio_if_ops_t tap_pktio_ops = {
        .init = NULL,
        .term = NULL,
@@ -321,5 +372,14 @@ const pktio_if_ops_t tap_pktio_ops = {
        .mtu_get = tap_mtu_get,
        .promisc_mode_set = tap_promisc_mode_set,
        .promisc_mode_get = tap_promisc_mode_get,
-       .mac_get = tap_mac_addr_get
+       .mac_get = tap_mac_addr_get,
+       .capability = NULL,
+       .input_queues_config = NULL,
+       .output_queues_config = NULL,
+       .in_queues = NULL,
+       .pktin_queues = NULL,
+       .pktout_queues = NULL,
+       .recv_queue = NULL,
+       .send_queue = NULL,
+       .add_pool = tap_add_pool
 };
diff --git a/test/validation/pktio/pktio.c b/test/validation/pktio/pktio.c
index a5f25da..d633701 100644
--- a/test/validation/pktio/pktio.c
+++ b/test/validation/pktio/pktio.c
@@ -65,7 +65,8 @@ typedef enum {
 
 typedef enum {
        TXRX_MODE_SINGLE,
-       TXRX_MODE_MULTI
+       TXRX_MODE_MULTI,
+       TXRX_MODE_DIFF_POOL,
 } txrx_mode_e;
 
 /** size of transmitted packets */
@@ -81,6 +82,7 @@ odp_atomic_u32_t ip_seq;
 pkt_segmented_e pool_segmentation = PKT_POOL_UNSEGMENTED;
 
 odp_pool_t pool[MAX_NUM_IFACES] = {ODP_POOL_INVALID, ODP_POOL_INVALID};
+odp_pool_t pool_plus[MAX_NUM_IFACES] = {ODP_POOL_INVALID, ODP_POOL_INVALID};
 
 static inline void _pktio_wait_linkup(odp_pktio_t pktio)
 {
@@ -477,7 +479,7 @@ static void pktio_txrx_multi(pktio_info_t *pktio_a, 
pktio_info_t *pktio_b,
        }
 
        /* send packet(s) out */
-       if (mode == TXRX_MODE_SINGLE) {
+       if (mode == TXRX_MODE_SINGLE || mode == TXRX_MODE_DIFF_POOL) {
                for (i = 0; i < num_pkts; ++i) {
                        ret = odp_queue_enq(pktio_a->outq, tx_ev[i]);
                        if (ret != 0) {
@@ -503,6 +505,12 @@ static void pktio_txrx_multi(pktio_info_t *pktio_a, 
pktio_info_t *pktio_b,
        CU_ASSERT(num_rx == num_pkts);
 
        for (i = 0; i < num_rx; ++i) {
+               if (mode == TXRX_MODE_DIFF_POOL) {
+                       odp_pool_t pi = odp_packet_pool(rx_pkt[i]);
+
+                       CU_ASSERT(pi == pool_plus[0] || pi == pool_plus[1]);
+               }
+
                CU_ASSERT_FATAL(rx_pkt[i] != ODP_PACKET_INVALID);
                CU_ASSERT(odp_packet_input(rx_pkt[i]) == pktio_b->id);
                CU_ASSERT(odp_packet_has_error(rx_pkt[i]) == 0);
@@ -530,6 +538,10 @@ static void test_txrx(odp_pktin_mode_t in_mode, int 
num_pkts,
                io->outq = odp_pktio_outq_getdef(io->id);
                io->in_mode = in_mode;
 
+               if (mode == TXRX_MODE_DIFF_POOL) {
+                       ret = odp_pktio_add_pool(io->id, pool_plus[i]);
+                       CU_ASSERT(ret == 0);
+               }
                if (in_mode == ODP_PKTIN_MODE_QUEUE) {
                        create_inq(io->id, ODP_QUEUE_TYPE_PLAIN);
                        io->inq = odp_pktio_inq_getdef(io->id);
@@ -588,6 +600,11 @@ void pktio_test_recv(void)
        test_txrx(ODP_PKTIN_MODE_DIRECT, 1, TXRX_MODE_SINGLE);
 }
 
+void pktio_test_recv_diff_pool(void)
+{
+       test_txrx(ODP_PKTIN_MODE_DIRECT, 1, TXRX_MODE_DIFF_POOL);
+}
+
 void pktio_test_recv_multi(void)
 {
        test_txrx(ODP_PKTIN_MODE_DIRECT, TX_BATCH_LEN, TXRX_MODE_MULTI);
@@ -1622,6 +1639,30 @@ static int create_pool(const char *iface, int num)
        return 0;
 }
 
+static int create_pool_plus(const char *iface, int num)
+{
+       char pool_name[ODP_POOL_NAME_LEN];
+       odp_pool_param_t params;
+
+       memset(&params, 0, sizeof(params));
+       params.pkt.seg_len = 0x100;
+       params.pkt.len = 0x100;
+       params.pkt.num     = PKT_BUF_NUM;
+       params.type        = ODP_POOL_PACKET;
+
+       snprintf(pool_name, sizeof(pool_name),
+                "pkt_pool_%s_plus", iface);
+
+       pool_plus[num] = odp_pool_create(pool_name, &params);
+       if (ODP_POOL_INVALID == pool[num]) {
+               fprintf(stderr, "%s: failed to create pool: %d",
+                       __func__, odp_errno());
+               return -1;
+       }
+
+       return 0;
+}
+
 static int pktio_suite_init(void)
 {
        int i;
@@ -1651,6 +1692,11 @@ static int pktio_suite_init(void)
                        return -1;
        }
 
+       for (i = 0; i < num_ifaces; i++) {
+               if (create_pool_plus(iface_name[i], i) != 0)
+                       return -1;
+       }
+
        if (default_pool_create() != 0) {
                fprintf(stderr, "error: failed to create default pool\n");
                return -1;
@@ -1690,6 +1736,17 @@ int pktio_suite_term(void)
                                pool_name);
                        ret = -1;
                }
+               snprintf(pool_name, sizeof(pool_name),
+                        "pkt_pool_%s_plus", iface_name[i]);
+               pool = odp_pool_lookup(pool_name);
+               if (pool == ODP_POOL_INVALID)
+                       continue;
+
+               if (odp_pool_destroy(pool) != 0) {
+                       fprintf(stderr, "error: failed to destroy pool %s\n",
+                               pool_name);
+                       ret = -1;
+               }
        }
 
        if (odp_pool_destroy(default_pkt_pool) != 0) {
@@ -1715,6 +1772,7 @@ odp_testinfo_t pktio_suite_unsegmented[] = {
        ODP_TEST_INFO(pktio_test_sched_queue),
        ODP_TEST_INFO(pktio_test_sched_multi),
        ODP_TEST_INFO(pktio_test_recv),
+       ODP_TEST_INFO(pktio_test_recv_diff_pool),
        ODP_TEST_INFO(pktio_test_recv_multi),
        ODP_TEST_INFO(pktio_test_recv_queue),
        ODP_TEST_INFO(pktio_test_jumbo),
@@ -1738,6 +1796,7 @@ odp_testinfo_t pktio_suite_segmented[] = {
        ODP_TEST_INFO(pktio_test_sched_queue),
        ODP_TEST_INFO(pktio_test_sched_multi),
        ODP_TEST_INFO(pktio_test_recv),
+       ODP_TEST_INFO(pktio_test_recv_diff_pool),
        ODP_TEST_INFO(pktio_test_recv_multi),
        ODP_TEST_INFO(pktio_test_jumbo),
        ODP_TEST_INFO_CONDITIONAL(pktio_test_send_failure,
diff --git a/test/validation/pktio/pktio.h b/test/validation/pktio/pktio.h
index 22fd814..8bdb6a4 100644
--- a/test/validation/pktio/pktio.h
+++ b/test/validation/pktio/pktio.h
@@ -15,6 +15,7 @@ void pktio_test_plain_multi(void);
 void pktio_test_sched_queue(void);
 void pktio_test_sched_multi(void);
 void pktio_test_recv(void);
+void pktio_test_recv_diff_pool(void);
 void pktio_test_recv_multi(void);
 void pktio_test_recv_queue(void);
 void pktio_test_jumbo(void);
-- 
1.9.1


_______________________________________________
lng-odp mailing list
[email protected]
https://lists.linaro.org/mailman/listinfo/lng-odp

Reply via email to