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(¶ms, 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, ¶ms);
+ 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