On Fri, Nov 06, 2015 at 12:56:37PM +0200, Matias Elo wrote: > Implement nm_dispatch() functionality in ODP code to > optimize performance and enable future feature additions. > > Signed-off-by: Matias Elo <[email protected]>
Reviewed-and-Tested-by: Stuart Haslam <[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
