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

Reply via email to