@@ -306,7 +306,9 @@ static inline int packet_parse_not_complete(odp_packet_hdr_t *pkt_hdr)
/* Forward declarations */
int _odp_packet_copy_md_to_packet(odp_packet_t srcpkt, odp_packet_t dstpkt);
-odp_packet_t packet_alloc(odp_pool_t pool_hdl, uint32_t len, int parse);
+/* Packet alloc of pktios */
+int packet_alloc_multi(odp_pool_t pool_hdl, uint32_t len,
+ odp_packet_t pkt[], int max_num);
/* Fill in parser metadata for L2 */
void packet_parse_l2(packet_parser_t *prs, uint32_t frame_len);
@@ -45,6 +45,7 @@
typedef struct {
int sockfd; /**< socket descriptor */
odp_pool_t pool; /**< pool to alloc packets from */
+ uint32_t mtu; /**< maximum transmission unit */
unsigned char if_mac[ETH_ALEN]; /**< IF eth mac addr */
uint8_t *cache_ptr[ODP_PACKET_SOCKET_MAX_BURST_RX];
odp_shm_t shm;
@@ -76,35 +76,46 @@ static void packet_init(pool_entry_t *pool, odp_packet_hdr_t *pkt_hdr,
pkt_hdr->input = ODP_PKTIO_INVALID;
}
-odp_packet_t packet_alloc(odp_pool_t pool_hdl, uint32_t len, int parse)
+int packet_alloc_multi(odp_pool_t pool_hdl, uint32_t len,
+ odp_packet_t pkt[], int max_num)
{
+ odp_packet_hdr_t *pkt_hdr;
+ pool_entry_t *pool = odp_pool_to_entry(pool_hdl);
+ int num, i;
+
+ num = buffer_alloc_multi(pool_hdl, len, (odp_buffer_t *)pkt, max_num);
+
+ for (i = 0; i < num; i++) {
+ pkt_hdr = odp_packet_hdr(pkt[i]);
+ packet_init(pool, pkt_hdr, len, 1 /* do parse */);
+
+ if (pkt_hdr->tailroom >= pkt_hdr->buf_hdr.segsize)
+ pull_tail_seg(pkt_hdr);
+ }
+
+ return num;
+}
+
+odp_packet_t odp_packet_alloc(odp_pool_t pool_hdl, uint32_t len)
+{
+ pool_entry_t *pool = odp_pool_to_entry(pool_hdl);
+ size_t pkt_size = len ? len : pool->s.params.buf.size;
odp_packet_t pkt;
odp_packet_hdr_t *pkt_hdr;
- pool_entry_t *pool = odp_pool_to_entry(pool_hdl);
- if (pool->s.params.type != ODP_POOL_PACKET)
+ if (pool->s.params.type != ODP_POOL_PACKET) {
+ __odp_errno = EINVAL;
return ODP_PACKET_INVALID;
-
- /* Handle special case for zero-length packets */
- if (len == 0) {
- len = pool->s.params.buf.size;
-
- pkt = (odp_packet_t)buffer_alloc(pool_hdl, len);
-
- if (pkt == ODP_PACKET_INVALID)
- return ODP_PACKET_INVALID;
-
- pull_tail(odp_packet_hdr(pkt), len);
-
- } else {
- pkt = (odp_packet_t)buffer_alloc(pool_hdl, len);
-
- if (pkt == ODP_PACKET_INVALID)
- return ODP_PACKET_INVALID;
}
+ pkt = (odp_packet_t)buffer_alloc(pool_hdl, pkt_size);
+ if (pkt == ODP_PACKET_INVALID)
+ return ODP_PACKET_INVALID;
+
pkt_hdr = odp_packet_hdr(pkt);
- packet_init(pool, pkt_hdr, len, parse);
+ packet_init(pool, pkt_hdr, pkt_size, 0 /* do not parse */);
+ if (len == 0)
+ pull_tail(pkt_hdr, pkt_size);
if (pkt_hdr->tailroom >= pkt_hdr->buf_hdr.segsize)
pull_tail_seg(pkt_hdr);
@@ -112,11 +123,6 @@ odp_packet_t packet_alloc(odp_pool_t pool_hdl, uint32_t len, int parse)
return pkt;
}
-odp_packet_t odp_packet_alloc(odp_pool_t pool_hdl, uint32_t len)
-{
- return packet_alloc(pool_hdl, len, 0);
-}
-
int odp_packet_alloc_multi(odp_pool_t pool_hdl, uint32_t len,
odp_packet_t pkt[], int num)
{
@@ -135,9 +141,12 @@ int odp_packet_alloc_multi(odp_pool_t pool_hdl, uint32_t len,
for (i = 0; i < count; ++i) {
odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt[i]);
- packet_init(pool, pkt_hdr, pkt_size, 0);
+ packet_init(pool, pkt_hdr, pkt_size, 0 /* do not parse */);
if (len == 0)
pull_tail(pkt_hdr, pkt_size);
+
+ if (pkt_hdr->tailroom >= pkt_hdr->buf_hdr.segsize)
+ pull_tail_seg(pkt_hdr);
}
return count;
@@ -145,12 +154,16 @@ int odp_packet_alloc_multi(odp_pool_t pool_hdl, uint32_t len,
void odp_packet_free(odp_packet_t pkt)
{
- odp_buffer_free((odp_buffer_t)pkt);
+ uint32_t pool_id = pool_id_from_buf((odp_buffer_t)pkt);
+
+ buffer_free(pool_id, (odp_buffer_t)pkt);
}
void odp_packet_free_multi(const odp_packet_t pkt[], int num)
{
- odp_buffer_free_multi((const odp_buffer_t *)pkt, num);
+ uint32_t pool_id = pool_id_from_buf((odp_buffer_t)pkt[0]);
+
+ buffer_free_multi(pool_id, (const odp_buffer_t * const)pkt, num);
}
int odp_packet_reset(odp_packet_t pkt, uint32_t len)
@@ -706,7 +706,7 @@ static int dpdk_stop(pktio_entry_t *pktio_entry)
static inline int mbuf_to_pkt(pktio_entry_t *pktio_entry,
odp_packet_t pkt_table[],
struct rte_mbuf *mbuf_table[],
- uint16_t num, odp_time_t *ts)
+ uint16_t mbuf_num, odp_time_t *ts)
{
odp_packet_t pkt;
odp_packet_hdr_t *pkt_hdr;
@@ -715,9 +715,15 @@ static inline int mbuf_to_pkt(pktio_entry_t *pktio_entry,
void *buf;
int i, j;
int nb_pkts = 0;
+ int alloc_len, num;
+ odp_pool_t pool = pktio_entry->s.pkt_dpdk.pool;
+
+ /* Allocate maximum sized packets */
+ alloc_len = pktio_entry->s.pkt_dpdk.data_room;
+
+ num = packet_alloc_multi(pool, alloc_len, pkt_table, mbuf_num);
for (i = 0; i < num; i++) {
- odp_pool_t pool = pktio_entry->s.pkt_dpdk.pool;
odp_packet_hdr_t parsed_hdr;
mbuf = mbuf_table[i];
@@ -738,18 +744,16 @@ static inline int mbuf_to_pkt(pktio_entry_t *pktio_entry,
&parsed_hdr))
goto fail;
}
- pkt = packet_alloc(pool, pkt_len, 1);
- if (pkt == ODP_PACKET_INVALID)
- goto fail;
+ pkt = pkt_table[i];
pkt_hdr = odp_packet_hdr(pkt);
+ pull_tail(pkt_hdr, alloc_len - pkt_len);
/* For now copy the data in the mbuf,
worry about zero-copy later */
- if (odp_packet_copy_from_mem(pkt, 0, pkt_len, buf) != 0) {
- odp_packet_free(pkt);
+ if (odp_packet_copy_from_mem(pkt, 0, pkt_len, buf) != 0)
goto fail;
- }
+
pkt_hdr->input = pktio_entry->s.handle;
if (pktio_cls_enabled(pktio_entry))
@@ -770,7 +774,9 @@ static inline int mbuf_to_pkt(pktio_entry_t *pktio_entry,
return nb_pkts;
fail:
- for (j = i; j < num; j++)
+ odp_packet_free_multi(&pkt_table[i], mbuf_num - i);
+
+ for (j = i; j < mbuf_num; j++)
rte_pktmbuf_free(mbuf_table[j]);
return (i > 0 ? i : -1);
@@ -599,6 +599,7 @@ static inline int netmap_pkt_to_odp(pktio_entry_t *pktio_entry,
odp_pool_t pool = pktio_entry->s.pkt_nm.pool;
odp_packet_hdr_t *pkt_hdr;
odp_packet_hdr_t parsed_hdr;
+ int num;
if (odp_unlikely(len > pktio_entry->s.pkt_nm.max_frame_len)) {
ODP_ERR("RX: frame too big %" PRIu16 " %zu!\n", len,
@@ -616,8 +617,8 @@ static inline int netmap_pkt_to_odp(pktio_entry_t *pktio_entry,
len, &pool, &parsed_hdr))
return -1;
}
- pkt = packet_alloc(pool, len, 1);
- if (pkt == ODP_PACKET_INVALID)
+ num = packet_alloc_multi(pool, len, &pkt, 1);
+ if (num != 1)
return -1;
pkt_hdr = odp_packet_hdr(pkt);
@@ -224,19 +224,9 @@ static int pcapif_recv_pkt(pktio_entry_t *pktio_entry, int index ODP_UNUSED,
pktio_entry->s.config.pktin.bit.ts_ptp)
ts = &ts_val;
- pkt = ODP_PACKET_INVALID;
- pkt_len = 0;
-
for (i = 0; i < len; ) {
int ret;
- if (pkt == ODP_PACKET_INVALID) {
- pkt = packet_alloc(pcap->pool, 0 /*default len*/, 1);
- if (odp_unlikely(pkt == ODP_PACKET_INVALID))
- break;
- pkt_len = odp_packet_len(pkt);
- }
-
ret = pcap_next_ex(pcap->rx, &hdr, &data);
/* end of file, attempt to reopen if within loop limit */
@@ -246,17 +236,17 @@ static int pcapif_recv_pkt(pktio_entry_t *pktio_entry, int index ODP_UNUSED,
if (ret != 1)
break;
+ pkt_len = hdr->caplen;
+
+ ret = packet_alloc_multi(pcap->pool, pkt_len, &pkt, 1);
+ if (odp_unlikely(ret != 1))
+ break;
+
if (ts != NULL)
ts_val = odp_time_global();
pkt_hdr = odp_packet_hdr(pkt);
- if (!odp_packet_pull_tail(pkt, pkt_len - hdr->caplen)) {
- ODP_ERR("failed to pull tail: pkt_len: %d caplen: %d\n",
- pkt_len, hdr->caplen);
- break;
- }
-
if (odp_packet_copy_from_mem(pkt, 0, hdr->caplen, data) != 0) {
ODP_ERR("failed to copy packet data\n");
break;
@@ -269,7 +259,6 @@ static int pcapif_recv_pkt(pktio_entry_t *pktio_entry, int index ODP_UNUSED,
pkt_hdr->input = pktio_entry->s.handle;
pkts[i] = pkt;
- pkt = ODP_PACKET_INVALID;
i++;
}
@@ -277,9 +266,6 @@ static int pcapif_recv_pkt(pktio_entry_t *pktio_entry, int index ODP_UNUSED,
odp_ticketlock_unlock(&pktio_entry->s.rxl);
- if (pkt != ODP_PACKET_INVALID)
- odp_packet_free(pkt);
-
return i;
}
@@ -527,6 +527,10 @@ static int sock_setup_pkt(pktio_entry_t *pktio_entry, const char *netdev,
if (err != 0)
goto error;
+ pkt_sock->mtu = mtu_get_fd(sockfd, netdev);
+ if (!pkt_sock->mtu)
+ goto error;
+
/* bind socket to if */
memset(&sa_ll, 0, sizeof(sa_ll));
sa_ll.sll_family = AF_PACKET;
@@ -659,6 +663,7 @@ static int sock_mmsg_recv(pktio_entry_t *pktio_entry, int index ODP_UNUSED,
void *base = msgvec[i].msg_hdr.msg_iov->iov_base;
struct ethhdr *eth_hdr = base;
uint16_t pkt_len = msgvec[i].msg_len;
+ int num;
/* Don't receive packets sent by ourselves */
if (odp_unlikely(ethaddrs_equal(pkt_sock->if_mac,
@@ -668,8 +673,8 @@ static int sock_mmsg_recv(pktio_entry_t *pktio_entry, int index ODP_UNUSED,
if (cls_classify_packet(pktio_entry, base, pkt_len,
pkt_len, &pool, &parsed_hdr))
continue;
- pkt = packet_alloc(pool, pkt_len, 1);
- if (pkt == ODP_PACKET_INVALID)
+ num = packet_alloc_multi(pool, pkt_len, &pkt, 1);
+ if (num != 1)
continue;
pkt_hdr = odp_packet_hdr(pkt);
@@ -690,10 +695,14 @@ static int sock_mmsg_recv(pktio_entry_t *pktio_entry, int index ODP_UNUSED,
[ODP_BUFFER_MAX_SEG];
for (i = 0; i < (int)len; i++) {
- pkt_table[i] = packet_alloc(pkt_sock->pool,
- 0 /*default*/, 1);
- if (odp_unlikely(pkt_table[i] == ODP_PACKET_INVALID))
+ int num;
+
+ num = packet_alloc_multi(pkt_sock->pool, pkt_sock->mtu,
+ &pkt_table[i], 1);
+ if (odp_unlikely(num != 1)) {
+ pkt_table[i] = ODP_PACKET_INVALID;
break;
+ }
msgvec[i].msg_hdr.msg_iovlen =
_rx_pkt_to_iovec(pkt_table[i], iovecs[i]);
@@ -818,7 +827,7 @@ static int sock_mmsg_send(pktio_entry_t *pktio_entry, int index ODP_UNUSED,
*/
static uint32_t sock_mtu_get(pktio_entry_t *pktio_entry)
{
- return mtu_get_fd(pktio_entry->s.pkt_sock.sockfd, pktio_entry->s.name);
+ return pktio_entry->s.pkt_sock.mtu;
}
/*
@@ -171,6 +171,7 @@ static inline unsigned pkt_mmap_v2_rx(pktio_entry_t *pktio_entry,
odp_packet_hdr_t *hdr;
odp_packet_hdr_t parsed_hdr;
odp_pool_t pool = pkt_sock->pool;
+ int num;
if (!mmap_rx_kernel_ready(ring->rd[frame_num].iov_base))
break;
@@ -208,8 +209,10 @@ static inline unsigned pkt_mmap_v2_rx(pktio_entry_t *pktio_entry,
}
}
- pkt_table[nb_rx] = packet_alloc(pool, pkt_len, 1);
- if (odp_unlikely(pkt_table[nb_rx] == ODP_PACKET_INVALID)) {
+ num = packet_alloc_multi(pool, pkt_len, &pkt_table[nb_rx], 1);
+
+ if (odp_unlikely(num != 1)) {
+ pkt_table[nb_rx] = ODP_PACKET_INVALID;
mmap_rx_user_ready(ppd.raw); /* drop */
frame_num = next_frame_num;
continue;
@@ -185,11 +185,12 @@ static odp_packet_t pack_odp_pkt(pktio_entry_t *pktio_entry, const void *data,
{
odp_packet_t pkt;
odp_packet_hdr_t *pkt_hdr;
+ int num;
- pkt = packet_alloc(pktio_entry->s.pkt_tap.pool, len, 1);
+ num = packet_alloc_multi(pktio_entry->s.pkt_tap.pool, len, &pkt, 1);
- if (pkt == ODP_PACKET_INVALID)
- return pkt;
+ if (num != 1)
+ return ODP_PACKET_INVALID;
if (odp_packet_copy_from_mem(pkt, 0, len, data) < 0) {
ODP_ERR("failed to copy packet data\n");