Signed-off-by: Ciprian Barbu <[email protected]>
---
 platform/linux-netmap/include/odp_packet_netmap.h |  18 +-
 platform/linux-netmap/odp_packet_netmap.c         | 280 ++++++++--------------
 2 files changed, 106 insertions(+), 192 deletions(-)

diff --git a/platform/linux-netmap/include/odp_packet_netmap.h 
b/platform/linux-netmap/include/odp_packet_netmap.h
index 576385d..2ac10d2 100644
--- a/platform/linux-netmap/include/odp_packet_netmap.h
+++ b/platform/linux-netmap/include/odp_packet_netmap.h
@@ -26,17 +26,15 @@
 /** Packet socket using netmap mmaped rings for both Rx and Tx */
 typedef struct {
        odp_buffer_pool_t pool;
-       size_t max_frame_len; /**< max frame len = buf_size - sizeof(pkt_hdr) */
-       size_t frame_offset; /**< frame start offset from start of pkt buf */
-       size_t buf_size; /**< size of buffer payload in 'pool' */
-       struct nm_desc *nm_desc;
-       uint32_t begin;
-       uint32_t end;
-       struct netmap_ring *rxring;
-       struct netmap_ring *txring;
-       odp_queue_t tx_access; /* Used for exclusive access to send packets */
+       size_t max_frame_len;           /**< buf_size - sizeof(pkt_hdr) */
+       size_t frame_offset;            /**< Frame start offset from start of 
pkt buf */
+       size_t buf_size;                /**< Size of buffer payload in 'pool' */
+       struct nm_desc *desc;           /**< Netmap meta-data for the device */
+       odp_queue_t tx_access;          /**< Exclusive access to send packets */
        uint32_t if_flags;
-       char ifname[32];
+       odp_packet_t *pkt_table;        /**< Used by recv_pkt_netmap */
+       int nb_rx;                      /**< Used by recv_pkt_netmap */
+       char ifname[IFNAMSIZ];
 } pkt_netmap_t;
 
 /**
diff --git a/platform/linux-netmap/odp_packet_netmap.c 
b/platform/linux-netmap/odp_packet_netmap.c
index 936c9b7..37e574b 100644
--- a/platform/linux-netmap/odp_packet_netmap.c
+++ b/platform/linux-netmap/odp_packet_netmap.c
@@ -103,7 +103,9 @@ static int nm_do_ioctl(pkt_netmap_t * const pkt_nm, 
unsigned long cmd,
        case SIOCGIFFLAGS:
                pkt_nm->if_flags = (ifr.ifr_flags << 16) |
                        (0xffff & ifr.ifr_flags);
-               ODP_DBG("flags are 0x%x\n", pkt_nm->if_flags);
+               ODP_DBG("[%04d] flags are 0x%x\n",
+                       odp_thread_id(),
+                       pkt_nm->if_flags);
                break;
        default:
                break;
@@ -119,7 +121,7 @@ done:
 int setup_pkt_netmap(pkt_netmap_t * const pkt_nm, const char *netdev,
                     odp_buffer_pool_t pool)
 {
-       char ifname[32];
+       char ifname[IFNAMSIZ];
        odp_packet_t pkt;
        uint8_t *pkt_buf;
        uint8_t *l2_hdr;
@@ -144,7 +146,7 @@ int setup_pkt_netmap(pkt_netmap_t * const pkt_nm, const 
char *netdev,
 
        odph_packet_free(pkt);
 
-       strncpy(pkt_nm->ifname, netdev, sizeof(pkt_nm->ifname));
+       snprintf(pkt_nm->ifname, sizeof(pkt_nm->ifname), "%s", netdev);
        snprintf(ifname, sizeof(ifname), "netmap:%s", netdev);
 
        odp_spinlock_lock(&mmap_desc_lock);
@@ -153,37 +155,34 @@ int setup_pkt_netmap(pkt_netmap_t * const pkt_nm, const 
char *netdev,
                mmap_desc.mem);
 
        if (mmap_desc.mem == NULL)
-               pkt_nm->nm_desc = nm_open(ifname, NULL, 0, NULL);
+               pkt_nm->desc = nm_open(ifname, NULL, 0, NULL);
        else
-               pkt_nm->nm_desc = nm_open(ifname, NULL, NM_OPEN_NO_MMAP,
+               pkt_nm->desc = nm_open(ifname, NULL, NM_OPEN_NO_MMAP,
                                          &mmap_desc);
 
-       if (pkt_nm->nm_desc == NULL) {
+       if (pkt_nm->desc == NULL) {
                ODP_ERR("Error opening nm interface: %s\n", strerror(errno));
                odp_spinlock_unlock(&mmap_desc_lock);
                return -1;
        }
 
        if (mmap_desc.mem == NULL) {
-               mmap_desc.mem = pkt_nm->nm_desc->mem;
-               mmap_desc.memsize = pkt_nm->nm_desc->memsize;
+               mmap_desc.mem = pkt_nm->desc->mem;
+               mmap_desc.memsize = pkt_nm->desc->memsize;
        }
        odp_spinlock_unlock(&mmap_desc_lock);
 
-       ODP_DBG("thread %d mmap addr %p\n",
+       ODP_DBG("[%04d] mmap addr %p\n",
                odp_thread_id(),
-               pkt_nm->nm_desc->mem);
-
-       pkt_nm->begin  = 0;
-       pkt_nm->end    = pkt_nm->nm_desc->req.nr_rx_rings;
-       pkt_nm->rxring = NETMAP_RXRING(pkt_nm->nm_desc->nifp, 0);
-       pkt_nm->txring = NETMAP_TXRING(pkt_nm->nm_desc->nifp, 0);
+               pkt_nm->desc->mem);
 
        ret = nm_do_ioctl(pkt_nm, SIOCGIFFLAGS, 0);
        if (ret)
                return ret;
        if ((pkt_nm->if_flags & IFF_UP) == 0) {
-               ODP_DBG("%s is down, bringing up...\n", pkt_nm->ifname);
+               ODP_DBG("[%04d] %s is down, bringing up...\n",
+                       odp_thread_id(),
+                       pkt_nm->ifname);
                pkt_nm->if_flags |= IFF_UP;
        }
        if (ETH_PROMISC) {
@@ -192,11 +191,13 @@ int setup_pkt_netmap(pkt_netmap_t * const pkt_nm, const 
char *netdev,
        }
        ret = nm_do_ioctl(pkt_nm, SIOCETHTOOL, ETHTOOL_SGSO);
        if (ret)
-               ODP_DBG("ETHTOOL_SGSO not supported\n");
+               ODP_DBG("[%04d] ETHTOOL_SGSO not supported\n",
+                       odp_thread_id());
 
        ret = nm_do_ioctl(pkt_nm, SIOCETHTOOL, ETHTOOL_STSO);
        if (ret)
-               ODP_DBG("ETHTOOL_STSO not supported\n");
+               ODP_DBG("[%04d] ETHTOOL_STSO not supported\n",
+                       odp_thread_id());
        /* TODO: This seems to cause the app to not receive frames
         * first time it is launched after netmap driver is inserted.
         * Should be investigated further.
@@ -206,217 +207,132 @@ int setup_pkt_netmap(pkt_netmap_t * const pkt_nm, const 
char *netdev,
         */
        ret = nm_do_ioctl(pkt_nm, SIOCETHTOOL, ETHTOOL_STXCSUM);
        if (ret)
-               ODP_DBG("ETHTOOL_STXCSUM not supported\n");
+               ODP_DBG("[%04d] ETHTOOL_STXCSUM not supported\n",
+                       odp_thread_id());
 
-       ODP_DBG("Wait for link to come up\n");
+       ODP_DBG("[%04d] Wait for link to come up\n",
+               odp_thread_id());
        sleep(WAITLINK_TMO);
-       ODP_DBG("Done\n");
+       ODP_DBG("[%04d] Done\n",
+               odp_thread_id());
 
        return 0;
 }
 
 int close_pkt_netmap(pkt_netmap_t * const pkt_nm)
 {
-       if (pkt_nm->nm_desc != NULL) {
-               nm_close(pkt_nm->nm_desc);
-               pkt_nm->nm_desc = NULL;
+       if (pkt_nm->desc != NULL) {
+               nm_close(pkt_nm->desc);
+               pkt_nm->desc = NULL;
        }
 
        return 0;
 }
 
+static void nm_recv_cb(uint8_t *arg, const struct nm_pkthdr *hdr,
+                      const uint8_t *buf)
+{
+       pkt_netmap_t *pkt_nm = (pkt_netmap_t *)arg;
+       odp_packet_t pkt;
+       uint8_t *pkt_buf, *l2_hdr;
+       size_t frame_len;
+
+       frame_len = (size_t)hdr->len;
+
+       if (frame_len > pkt_nm->max_frame_len) {
+               ODP_ERR("[%04d] RX: frame too big %u %lu!\n",
+                       odp_thread_id(),
+                       (unsigned)frame_len, pkt_nm->max_frame_len);
+               return;
+       }
+
+       if (odp_unlikely(frame_len < ODPH_ETH_LEN_MIN)) {
+               ODP_ERR("[%04d] RX: Frame truncated: %u\n",
+                       odp_thread_id(),
+                       (unsigned)frame_len);
+               return;
+       }
+
+       pkt = odph_packet_alloc(pkt_nm->pool);
+
+       if (odp_unlikely(pkt == ODP_PACKET_INVALID)) {
+               ODP_DBG("[%04d] Could not allocate packet\n", odp_thread_id());
+               return;
+       }
+       pkt_buf = odp_packet_addr(pkt);
+       l2_hdr = pkt_buf + pkt_nm->frame_offset;
+       /* For now copy the data in the mbuf,
+          worry about zero-copy later */
+       memcpy(l2_hdr, buf, frame_len);
+
+       /* Initialize, parse and set packet header data */
+       odp_packet_init(pkt);
+       odp_packet_parse(pkt, frame_len, pkt_nm->frame_offset);
+
+       pkt_nm->pkt_table[pkt_nm->nb_rx++] = pkt;
+}
+
 int recv_pkt_netmap(pkt_netmap_t * const pkt_nm, odp_packet_t pkt_table[],
                    unsigned len)
 {
-       struct netmap_ring *rxring = pkt_nm->rxring;
-       int fd;
-       unsigned nb_rx = 0;
-       uint32_t limit, rx;
-       uint32_t ringid = pkt_nm->begin;
-       odp_packet_t pkt = ODP_PACKET_INVALID;
+       int fd = pkt_nm->desc->fd;
+
 #ifdef NETMAP_BLOCKING_IO
        struct pollfd fds[1];
        int ret;
-#endif
 
-       fd = pkt_nm->nm_desc->fd;
-#ifdef NETMAP_BLOCKING_IO
        fds[0].fd = fd;
        fds[0].events = POLLIN;
-#endif
 
-       while (nb_rx < len) {
-#ifdef NETMAP_BLOCKING_IO
-               ret = poll(&fds[0], 1, POLL_TMO);
-               if (ret <= 0 || (fds[0].revents & POLLERR))
-                       break;
+       ret = poll(&fds[0], 1, POLL_TMO);
+       if (ret <= 0 || (fds[0].revents & POLLERR))
+               return 0;
 #else
-               ioctl(fd, NIOCRXSYNC, NULL);
+       ioctl(fd, NIOCRXSYNC, NULL);
 #endif
 
-               /* Find first ring not empty */
-               while (nm_ring_empty(rxring)) {
-                       ringid++;
-
-                       /* Return to scheduler if no more data to meet the
-                          requested amount (len) */
-                       if (ringid == pkt_nm->end) {
-                               ODP_DBG("No more data on the wire\n");
-                               break;
-                       }
-
-                       rxring = NETMAP_RXRING(pkt_nm->nm_desc->nifp, ringid);
-               }
-
-               limit = len - nb_rx;
-               if (nm_ring_space(rxring) < limit)
-                       limit = nm_ring_space(rxring);
-
-               ODP_DBG("receiving %d frames out of %u\n", limit, len);
-
-               for (rx = 0; rx < limit; rx++) {
-                       struct netmap_slot *rslot;
-                       char *p;
-                       uint16_t frame_len;
-                       uint8_t *pkt_buf;
-                       uint8_t *l2_hdr;
-                       uint32_t cur;
-
-                       if (odp_likely(pkt == ODP_PACKET_INVALID)) {
-                               pkt = odph_packet_alloc(pkt_nm->pool);
-                               if (odp_unlikely(pkt == ODP_PACKET_INVALID))
-                                       break;
-                       }
-
-                       cur = rxring->cur;
-                       rslot = &rxring->slot[cur];
-                       p = NETMAP_BUF(rxring, rslot->buf_idx);
-                       frame_len = rslot->len;
-
-                       rxring->head = nm_ring_next(rxring, cur);
-                       rxring->cur = rxring->head;
-
-                       pkt_buf = odp_packet_addr(pkt);
-                       l2_hdr = pkt_buf + pkt_nm->frame_offset;
-
-                       if (frame_len > pkt_nm->max_frame_len) {
-                               ODP_ERR("RX: frame too big %u %lu!\n",
-                                       frame_len, pkt_nm->max_frame_len);
-                               /* drop the frame, reuse pkt next interation */
-                               continue;
-                       }
-                       if (odp_unlikely(frame_len < ODPH_ETH_LEN_MIN)) {
-                               ODP_ERR("RX: Frame truncated: %u\n",
-                                       (unsigned)frame_len);
-                               continue;
-                       }
-
-                       /* For now copy the data in the mbuf,
-                          worry about zero-copy later */
-                       memcpy(l2_hdr, p, frame_len);
-
-                       /* Initialize, parse and set packet header data */
-                       odp_packet_init(pkt);
-                       odp_packet_parse(pkt, frame_len, pkt_nm->frame_offset);
-
-                       pkt_table[nb_rx] = pkt;
-                       pkt = ODP_PACKET_INVALID;
-                       nb_rx++;
-               }
-
-               if (odp_unlikely(pkt == ODP_PACKET_INVALID))
-                       break;
-       }
+       pkt_nm->pkt_table = pkt_table;
+       pkt_nm->nb_rx = 0;
+       nm_dispatch(pkt_nm->desc, len, nm_recv_cb, (uint8_t *)pkt_nm);
 
-       if (odp_unlikely(pkt != ODP_PACKET_INVALID))
-               odp_buffer_free((odp_buffer_t) pkt);
+       if (pkt_nm->nb_rx)
+               ODP_DBG("[%04d] <=== rcvd %03u frames from netmap adapter\n",
+                       odp_thread_id(), pkt_nm->nb_rx);
 
-       if (nb_rx)
-               ODP_DBG("<=== rcvd %03u frames from netmap adapter\n", nb_rx);
-
-       return nb_rx;
+       return pkt_nm->nb_rx;
 }
 
 int send_pkt_netmap(pkt_netmap_t * const pkt_nm, odp_packet_t pkt_table[],
                    unsigned len)
 {
-       struct netmap_ring *txring = pkt_nm->txring;
-       int                 fd;
-       unsigned            nb_tx = 0;
-       uint32_t            limit, tx;
-       uint32_t            ringid = pkt_nm->begin;
-       odp_packet_t        pkt;
+       int fd = pkt_nm->desc->fd;
+       unsigned tx, nb_tx;
 
 #ifdef NETMAP_BLOCKING_IO
        struct pollfd fds[2];
        int ret;
-#endif
 
-       fd = pkt_nm->nm_desc->fd;
-#ifdef NETMAP_BLOCKING_IO
        fds[0].fd = fd;
        fds[0].events = POLLOUT;
-#endif
 
-       while (nb_tx < len) {
-#ifdef NETMAP_BLOCKING_IO
-               ret = poll(&fds[0], 1, POLL_TMO);
-               if (ret <= 0 || (fds[0].revents & POLLERR))
-                       break;
+       ret = poll(&fds[0], 1, POLL_TMO);
+       if (ret <= 0 || (fds[0].revents & POLLERR))
+               return 0;
 #else
-               ioctl(fd, NIOCTXSYNC, NULL);
+       ioctl(fd, NIOCTXSYNC, NULL);
 #endif
 
-               /* Find first ring not empty */
-               while (nm_ring_empty(txring)) {
-                       ringid++;
-
-                       /* Return to scheduler if no more space to meet the
-                          requested amount (len) */
-                       if (ringid == pkt_nm->end) {
-                               ODP_DBG("No more space in TX rings\n");
-                               break;
-                       }
-
-                       txring = NETMAP_TXRING(pkt_nm->nm_desc->nifp, ringid);
-               }
-
-               limit = len - nb_tx;
-               if (nm_ring_space(txring) < limit)
-                       limit = nm_ring_space(txring);
-
-               ODP_DBG("Sending %d packets out of %d to netmap %p %u\n",
-                       limit, len, txring, txring->cur);
-
-               for (tx = 0; tx < limit; tx++) {
-                       struct netmap_slot *tslot;
-                       size_t frame_len;
-                       uint32_t cur;
-                       uint8_t *frame;
-                       void *txbuf;
-
-                       cur = txring->cur;
-                       tslot = &txring->slot[cur];
-                       txbuf = NETMAP_BUF(txring, tslot->buf_idx);
-
-                       pkt = pkt_table[nb_tx];
-                       frame = odp_packet_l2(pkt);
-                       frame_len = odp_packet_get_len(pkt);
-
-                       memcpy(txbuf, frame, frame_len);
-                       tslot->len = frame_len;
-                       txring->head = nm_ring_next(txring, cur);
-                       txring->cur = txring->head;
-                       nb_tx++;
-               }
+       for (nb_tx = 0; nb_tx < len; nb_tx++) {
+               odp_packet_t pkt = pkt_table[nb_tx];
+               uint8_t *frame = odp_packet_l2(pkt);
+               size_t frame_len = odp_packet_get_len(pkt);
+               if (nm_inject(pkt_nm->desc, frame, frame_len))
+                       break;
        }
 
-#ifndef NETMAP_BLOCKING_IO
-       ioctl(fd, NIOCTXSYNC, NULL);
-#endif
-
        if (nb_tx)
-               ODP_DBG("===> sent %03u frames to netmap adapter\n", nb_tx);
+               ODP_DBG("[%04d] ===> sent %03u frames to netmap adapter\n",
+                       odp_thread_id(), nb_tx);
 
        for (tx = 0; tx < len; tx++)
                odph_packet_free(pkt_table[tx]);
-- 
1.8.3.2


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

Reply via email to