Implement nm_dispatch() functionality in ODP code to optimize performance and enable future feature additions.
Signed-off-by: Matias Elo <[email protected]> --- platform/linux-generic/pktio/netmap.c | 94 +++++++++++++++++++++++------------ 1 file changed, 61 insertions(+), 33 deletions(-) diff --git a/platform/linux-generic/pktio/netmap.c b/platform/linux-generic/pktio/netmap.c index 794c82e..d064323 100644 --- a/platform/linux-generic/pktio/netmap.c +++ b/platform/linux-generic/pktio/netmap.c @@ -31,12 +31,6 @@ static struct nm_desc mmap_desc; /** Used to store the mmap address; #define NM_OPEN_RETRIES 5 #define NM_INJECT_RETRIES 10 -struct dispatch_args { - odp_packet_t *pkt_table; - unsigned nb_rx; - pktio_entry_t *pktio_entry; -}; - static int netmap_do_ioctl(pktio_entry_t *pktio_entry, unsigned long cmd, int subcmd) { @@ -187,64 +181,98 @@ error: return -1; } -static void netmap_recv_cb(u_char *arg, const struct nm_pkthdr *hdr, - const u_char *buf) +/** + * Create ODP packet from netmap packet + * + * @param pktio_entry Packet IO handle + * @param pkt_out Storage for new ODP packet handle + * @param buf Netmap buffer address + * @param len Netmap buffer length + * + * @retval 0 on success + * @retval <0 on failure + */ +static inline int netmap_pkt_to_odp(pktio_entry_t *pktio_entry, + odp_packet_t *pkt_out, const char *buf, + uint16_t len) { - struct dispatch_args *args = (struct dispatch_args *)(void *)arg; - pkt_netmap_t *pkt_nm = &args->pktio_entry->s.pkt_nm; odp_packet_t pkt; odp_packet_hdr_t *pkt_hdr; - size_t frame_len = (size_t)hdr->len; - if (odp_unlikely(frame_len > pkt_nm->max_frame_len)) { - ODP_ERR("RX: frame too big %u %lu!\n", (unsigned)frame_len, - pkt_nm->max_frame_len); - return; + if (odp_unlikely(len > pktio_entry->s.pkt_nm.max_frame_len)) { + ODP_ERR("RX: frame too big %" PRIu16 " %zu!\n", len, + pktio_entry->s.pkt_nm.max_frame_len); + return -1; } - if (odp_unlikely(frame_len < ODPH_ETH_LEN_MIN)) { - ODP_ERR("RX: Frame truncated: %u\n", (unsigned)frame_len); - return; + if (odp_unlikely(len < ODPH_ETH_LEN_MIN)) { + ODP_ERR("RX: Frame truncated: %" PRIu16 "\n", len); + return -1; } - pkt = packet_alloc(pkt_nm->pool, frame_len, 1); + pkt = packet_alloc(pktio_entry->s.pkt_nm.pool, len, 1); if (pkt == ODP_PACKET_INVALID) - return; + return -1; pkt_hdr = odp_packet_hdr(pkt); /* For now copy the data in the mbuf, worry about zero-copy later */ - if (odp_packet_copydata_in(pkt, 0, frame_len, buf) != 0) { + if (odp_packet_copydata_in(pkt, 0, len, buf) != 0) { odp_packet_free(pkt); - return; + return -1; } - packet_parse_l2(pkt_hdr); - args->pkt_table[args->nb_rx++] = pkt; + *pkt_out = pkt; + return 0; } static int netmap_recv(pktio_entry_t *pktio_entry, odp_packet_t pkt_table[], unsigned num) { - struct dispatch_args args; - struct nm_desc *nm_desc = pktio_entry->s.pkt_nm.rx_desc; + struct netmap_ring *ring; + struct nm_desc *desc = pktio_entry->s.pkt_nm.rx_desc; struct pollfd polld; + char *buf; + int i; + int num_rings = desc->last_rx_ring - desc->first_rx_ring + 1; + int ring_id = desc->cur_rx_ring; + unsigned num_rx = 0; + uint32_t slot_id; - polld.fd = nm_desc->fd; + polld.fd = desc->fd; polld.events = POLLIN; - args.pkt_table = pkt_table; - args.nb_rx = 0; - args.pktio_entry = pktio_entry; + for (i = 0; i < num_rings && num_rx != num; i++) { + ring_id = desc->cur_rx_ring + i; - nm_dispatch(nm_desc, num, netmap_recv_cb, (u_char *)&args); - if (args.nb_rx == 0) { + if (ring_id > desc->last_rx_ring) + ring_id = desc->first_rx_ring; + + ring = NETMAP_RXRING(desc->nifp, ring_id); + + while (!nm_ring_empty(ring) && num_rx != num) { + slot_id = ring->cur; + buf = NETMAP_BUF(ring, ring->slot[slot_id].buf_idx); + + odp_prefetch(buf); + + if (!netmap_pkt_to_odp(pktio_entry, &pkt_table[num_rx], + buf, ring->slot[slot_id].len)) + num_rx++; + + ring->cur = nm_ring_next(ring, slot_id); + ring->head = ring->cur; + } + } + desc->cur_rx_ring = ring_id; + + if (num_rx == 0) { if (odp_unlikely(poll(&polld, 1, 0) < 0)) ODP_ERR("RX: poll error\n"); } - return args.nb_rx; + return num_rx; } static int netmap_send(pktio_entry_t *pktio_entry, odp_packet_t pkt_table[], -- 1.9.1 _______________________________________________ lng-odp mailing list [email protected] https://lists.linaro.org/mailman/listinfo/lng-odp
