took that patch to next branch, will be in master just after 1.4.1

Maxim.

On 11/11/2015 14:34, Stuart Haslam wrote:
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

_______________________________________________
lng-odp mailing list
[email protected]
https://lists.linaro.org/mailman/listinfo/lng-odp

Reply via email to