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

diff --git a/platform/linux-netmap/include/odp_packet_netmap.h 
b/platform/linux-netmap/include/odp_packet_netmap.h
index 2ac10d2..0e4fb09 100644
--- a/platform/linux-netmap/include/odp_packet_netmap.h
+++ b/platform/linux-netmap/include/odp_packet_netmap.h
@@ -23,6 +23,16 @@
 
 #define NETMAP_BLOCKING_IO
 
+/* Since we allow more than one thread to open the same device
+ * this struct uinquely identifies a device so that proper locking
+ * can be implemented
+ */
+typedef struct {
+       char ifname[IFNAMSIZ];
+       odp_spinlock_t rx_lock;
+       odp_spinlock_t tx_lock;
+} netmap_dev_t;
+
 /** Packet socket using netmap mmaped rings for both Rx and Tx */
 typedef struct {
        odp_buffer_pool_t pool;
@@ -34,7 +44,7 @@ typedef struct {
        uint32_t if_flags;
        odp_packet_t *pkt_table;        /**< Used by recv_pkt_netmap */
        int nb_rx;                      /**< Used by recv_pkt_netmap */
-       char ifname[IFNAMSIZ];
+       netmap_dev_t *nm_dev;
 } pkt_netmap_t;
 
 /**
diff --git a/platform/linux-netmap/odp_packet_netmap.c 
b/platform/linux-netmap/odp_packet_netmap.c
index 37e574b..8c56a66 100644
--- a/platform/linux-netmap/odp_packet_netmap.c
+++ b/platform/linux-netmap/odp_packet_netmap.c
@@ -58,11 +58,17 @@
 static struct nm_desc mmap_desc;       /** Used to store the mmap address;
                                          filled in first time, used for
                                          subsequent calls to nm_open */
-static odp_spinlock_t mmap_desc_lock;
+static odp_spinlock_t nm_global_lock;  /** Global lock for mmap addr and
+                                         dev lookup */
+
+#define MAX_DEVS       32
+static netmap_dev_t netmap_devs[MAX_DEVS];
+static int nm_dev_cnt;
 
 int odp_netmap_init_global(void)
 {
-       odp_spinlock_init(&mmap_desc_lock);
+       odp_spinlock_init(&nm_global_lock);
+       memset(netmap_devs, 0, sizeof(netmap_devs));
        return 0;
 }
 
@@ -81,7 +87,7 @@ static int nm_do_ioctl(pkt_netmap_t * const pkt_nm, unsigned 
long cmd,
        }
 
        memset(&ifr, 0, sizeof(ifr));
-       strncpy(ifr.ifr_name, pkt_nm->ifname, sizeof(ifr.ifr_name));
+       strncpy(ifr.ifr_name, pkt_nm->nm_dev->ifname, sizeof(ifr.ifr_name));
 
        switch (cmd) {
        case SIOCSIFFLAGS:
@@ -125,7 +131,12 @@ int setup_pkt_netmap(pkt_netmap_t * const pkt_nm, const 
char *netdev,
        odp_packet_t pkt;
        uint8_t *pkt_buf;
        uint8_t *l2_hdr;
-       int ret;
+       int i, ret;
+
+       if (nm_dev_cnt == MAX_DEVS) {
+               ODP_ERR("Maximum number of devices reached: %d\n", nm_dev_cnt);
+               return -1;
+       }
 
        if (pool == ODP_BUFFER_POOL_INVALID)
                return -1;
@@ -146,10 +157,9 @@ int setup_pkt_netmap(pkt_netmap_t * const pkt_nm, const 
char *netdev,
 
        odph_packet_free(pkt);
 
-       snprintf(pkt_nm->ifname, sizeof(pkt_nm->ifname), "%s", netdev);
        snprintf(ifname, sizeof(ifname), "netmap:%s", netdev);
 
-       odp_spinlock_lock(&mmap_desc_lock);
+       odp_spinlock_lock(&nm_global_lock);
        ODP_DBG("[%04d] Initial mmap addr: %p\n",
                odp_thread_id(),
                mmap_desc.mem);
@@ -162,7 +172,7 @@ int setup_pkt_netmap(pkt_netmap_t * const pkt_nm, const 
char *netdev,
 
        if (pkt_nm->desc == NULL) {
                ODP_ERR("Error opening nm interface: %s\n", strerror(errno));
-               odp_spinlock_unlock(&mmap_desc_lock);
+               odp_spinlock_unlock(&nm_global_lock);
                return -1;
        }
 
@@ -170,7 +180,23 @@ int setup_pkt_netmap(pkt_netmap_t * const pkt_nm, const 
char *netdev,
                mmap_desc.mem = pkt_nm->desc->mem;
                mmap_desc.memsize = pkt_nm->desc->memsize;
        }
-       odp_spinlock_unlock(&mmap_desc_lock);
+
+       /* Lookup dev */
+       for (i = 0; i < nm_dev_cnt; i++) {
+               if (!strcmp(netmap_devs[i].ifname, netdev)) {
+                       pkt_nm->nm_dev = &netmap_devs[i];
+                       break;
+               }
+       }
+       if (i == nm_dev_cnt) {
+               nm_dev_cnt++;
+               snprintf(netmap_devs[i].ifname, sizeof(netmap_devs[i].ifname),
+                        "%s", netdev);
+               odp_spinlock_init(&netmap_devs[i].rx_lock);
+               odp_spinlock_init(&netmap_devs[i].tx_lock);
+               pkt_nm->nm_dev = &netmap_devs[i];
+       }
+       odp_spinlock_unlock(&nm_global_lock);
 
        ODP_DBG("[%04d] mmap addr %p\n",
                odp_thread_id(),
@@ -182,7 +208,7 @@ int setup_pkt_netmap(pkt_netmap_t * const pkt_nm, const 
char *netdev,
        if ((pkt_nm->if_flags & IFF_UP) == 0) {
                ODP_DBG("[%04d] %s is down, bringing up...\n",
                        odp_thread_id(),
-                       pkt_nm->ifname);
+                       pkt_nm->nm_dev->ifname);
                pkt_nm->if_flags |= IFF_UP;
        }
        if (ETH_PROMISC) {
@@ -293,7 +319,10 @@ int recv_pkt_netmap(pkt_netmap_t * const pkt_nm, 
odp_packet_t pkt_table[],
 
        pkt_nm->pkt_table = pkt_table;
        pkt_nm->nb_rx = 0;
+
+       odp_spinlock_lock(&pkt_nm->nm_dev->rx_lock);
        nm_dispatch(pkt_nm->desc, len, nm_recv_cb, (uint8_t *)pkt_nm);
+       odp_spinlock_unlock(&pkt_nm->nm_dev->rx_lock);
 
        if (pkt_nm->nb_rx)
                ODP_DBG("[%04d] <=== rcvd %03u frames from netmap adapter\n",
@@ -322,6 +351,7 @@ int send_pkt_netmap(pkt_netmap_t * const pkt_nm, 
odp_packet_t pkt_table[],
        ioctl(fd, NIOCTXSYNC, NULL);
 #endif
 
+       odp_spinlock_lock(&pkt_nm->nm_dev->tx_lock);
        for (nb_tx = 0; nb_tx < len; nb_tx++) {
                odp_packet_t pkt = pkt_table[nb_tx];
                uint8_t *frame = odp_packet_l2(pkt);
@@ -329,6 +359,7 @@ int send_pkt_netmap(pkt_netmap_t * const pkt_nm, 
odp_packet_t pkt_table[],
                if (nm_inject(pkt_nm->desc, frame, frame_len))
                        break;
        }
+       odp_spinlock_unlock(&pkt_nm->nm_dev->tx_lock);
 
        if (nb_tx)
                ODP_DBG("[%04d] ===> sent %03u frames to netmap adapter\n",
-- 
1.8.3.2


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

Reply via email to