This patch changes odp_pktio_open() to ensure a one-to-one relationship
between a pktio device an a pktio handle. Attempts to open a device
which is already open will fail, setting errno to -EEXIST to indicate
the reason for the failure. A new API odp_pktio_lookup() is added which
can be used to obtain a handle to an already open device.

Signed-off-by: Stuart Haslam <[email protected]>
---
 platform/linux-generic/include/api/odp_packet_io.h |  18 ++-
 .../linux-generic/include/odp_packet_io_internal.h |   1 +
 platform/linux-generic/odp_packet_io.c             | 122 ++++++++++++++-------
 3 files changed, 102 insertions(+), 39 deletions(-)

diff --git a/platform/linux-generic/include/api/odp_packet_io.h 
b/platform/linux-generic/include/api/odp_packet_io.h
index e4577c3..0c34f29 100644
--- a/platform/linux-generic/include/api/odp_packet_io.h
+++ b/platform/linux-generic/include/api/odp_packet_io.h
@@ -32,8 +32,13 @@ extern "C" {
 /**
  * Open an ODP packet IO instance
  *
- * @param dev    Packet IO device
- * @param pool   Pool to use for packet IO
+ * Packet IO handles are single instance per device, attempts to open an 
already
+ * open device will fail, returning ODP_PKTIO_INVALID with errno set to 
-EEXIST.
+ * odp_pktio_lookup() may be used to obtain a handle to an already open device.
+ *
+ * @param dev    Packet IO device name
+ * @param pool   Pool from which to allocate buffers for storing packets
+ *               received over this packet IO
  *
  * @return ODP packet IO handle or ODP_PKTIO_INVALID on error
  *
@@ -53,6 +58,15 @@ odp_pktio_t odp_pktio_open(const char *dev, 
odp_buffer_pool_t pool);
 int odp_pktio_close(odp_pktio_t id);
 
 /**
+ * Return a packet IO handle for an already open device
+ *
+ * @param dev Packet IO device name
+ *
+ * @return ODP packet IO handle or ODP_PKTIO_INVALID
+ */
+odp_pktio_t odp_pktio_lookup(const char *dev);
+
+/**
  * Receive packets
  *
  * @param id          ODP packet IO handle
diff --git a/platform/linux-generic/include/odp_packet_io_internal.h 
b/platform/linux-generic/include/odp_packet_io_internal.h
index 465127b..7d9fc3d 100644
--- a/platform/linux-generic/include/odp_packet_io_internal.h
+++ b/platform/linux-generic/include/odp_packet_io_internal.h
@@ -55,6 +55,7 @@ typedef union {
 } pktio_entry_t;
 
 typedef struct {
+       odp_spinlock_t lock;
        pktio_entry_t entries[ODP_CONFIG_PKTIO_ENTRIES];
 } pktio_table_t;
 
diff --git a/platform/linux-generic/odp_packet_io.c 
b/platform/linux-generic/odp_packet_io.c
index 59590d2..cd109d2 100644
--- a/platform/linux-generic/odp_packet_io.c
+++ b/platform/linux-generic/odp_packet_io.c
@@ -23,6 +23,7 @@
 #include <sys/ioctl.h>
 #include <linux/if_arp.h>
 #include <ifaddrs.h>
+#include <errno.h>
 
 static pktio_table_t *pktio_tbl;
 
@@ -48,6 +49,8 @@ int odp_pktio_init_global(void)
 
        memset(pktio_tbl, 0, sizeof(pktio_table_t));
 
+       odp_spinlock_init(&pktio_tbl->lock);
+
        for (id = 1; id <= ODP_CONFIG_PKTIO_ENTRIES; ++id) {
                pktio_entry = &pktio_tbl->entries[id - 1];
 
@@ -160,12 +163,39 @@ static int free_pktio_entry(odp_pktio_t id)
        return 0;
 }
 
-odp_pktio_t odp_pktio_open(const char *dev, odp_buffer_pool_t pool)
+static int init_socket(pktio_entry_t *entry, const char *dev,
+                      odp_buffer_pool_t pool)
+{
+       int fd = -1;
+
+       if (getenv("ODP_PKTIO_DISABLE_SOCKET_MMAP") == NULL) {
+               entry->s.type = ODP_PKTIO_TYPE_SOCKET_MMAP;
+               fd = setup_pkt_sock_mmap(&entry->s.pkt_sock_mmap, dev, pool, 1);
+               if (fd == -1)
+                       close_pkt_sock_mmap(&entry->s.pkt_sock_mmap);
+       }
+
+       if (fd == -1 && getenv("ODP_PKTIO_DISABLE_SOCKET_MMSG") == NULL) {
+               entry->s.type = ODP_PKTIO_TYPE_SOCKET_MMSG;
+               fd = setup_pkt_sock(&entry->s.pkt_sock, dev, pool);
+               if (fd == -1)
+                       close_pkt_sock(&entry->s.pkt_sock);
+       }
+
+       if (fd == -1 && getenv("ODP_PKTIO_DISABLE_SOCKET_BASIC") == NULL) {
+               entry->s.type = ODP_PKTIO_TYPE_SOCKET_BASIC;
+               fd = setup_pkt_sock(&entry->s.pkt_sock, dev, pool);
+               if (fd == -1)
+                       close_pkt_sock(&entry->s.pkt_sock);
+       }
+
+       return fd;
+}
+
+static odp_pktio_t setup_pktio_entry(const char *dev, odp_buffer_pool_t pool)
 {
        odp_pktio_t id;
        pktio_entry_t *pktio_entry;
-       int res;
-       int fanout = 1;
        char loop[IFNAMSIZ] = {0};
        char *loop_hint;
 
@@ -209,46 +239,34 @@ odp_pktio_t odp_pktio_open(const char *dev, 
odp_buffer_pool_t pool)
        if (!pktio_entry)
                return ODP_PKTIO_INVALID;
 
-       ODP_DBG("ODP_PKTIO_USE_FANOUT: %d\n", fanout);
-       if (getenv("ODP_PKTIO_DISABLE_SOCKET_MMAP") == NULL) {
-               pktio_entry->s.type = ODP_PKTIO_TYPE_SOCKET_MMAP;
-               res = setup_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap, dev,
-                               pool, fanout);
-               if (res != -1) {
-                       ODP_DBG("IO type: ODP_PKTIO_TYPE_SOCKET_MMAP\n");
-                       goto done;
-               }
-               close_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap);
+       if (init_socket(pktio_entry, dev, pool) == -1) {
+               unlock_entry_classifier(pktio_entry);
+               free_pktio_entry(id);
+               id = ODP_PKTIO_INVALID;
+               ODP_ERR("Unable to init any I/O type.\n");
+       } else {
+               strncpy(pktio_entry->s.name, dev, IFNAMSIZ);
+               unlock_entry_classifier(pktio_entry);
        }
 
-       if (getenv("ODP_PKTIO_DISABLE_SOCKET_MMSG") == NULL) {
-               pktio_entry->s.type = ODP_PKTIO_TYPE_SOCKET_MMSG;
-               res = setup_pkt_sock(&pktio_entry->s.pkt_sock, dev, pool);
-               if (res != -1) {
-                       ODP_DBG("IO type: ODP_PKTIO_TYPE_SOCKET_MMSG\n");
-                       goto done;
-               }
-               close_pkt_sock(&pktio_entry->s.pkt_sock);
-       }
+       return id;
+}
 
-       if (getenv("ODP_PKTIO_DISABLE_SOCKET_BASIC") == NULL) {
-               pktio_entry->s.type = ODP_PKTIO_TYPE_SOCKET_BASIC;
-               res = setup_pkt_sock(&pktio_entry->s.pkt_sock, dev, pool);
-               if (res != -1) {
-                       ODP_DBG("IO type: ODP_PKTIO_TYPE_SOCKET_BASIC\n");
-                       goto done;
-               }
-               close_pkt_sock(&pktio_entry->s.pkt_sock);
+odp_pktio_t odp_pktio_open(const char *dev, odp_buffer_pool_t pool)
+{
+       odp_pktio_t id;
+
+       id = odp_pktio_lookup(dev);
+       if (id != ODP_PKTIO_INVALID) {
+               /* interface is already open */
+               errno = -EEXIST;
+               return ODP_PKTIO_INVALID;
        }
 
-       unlock_entry_classifier(pktio_entry);
-       free_pktio_entry(id);
-       ODP_ERR("Unable to init any I/O type.\n");
-       return ODP_PKTIO_INVALID;
+       odp_spinlock_lock(&pktio_tbl->lock);
+       id = setup_pktio_entry(dev, pool);
+       odp_spinlock_unlock(&pktio_tbl->lock);
 
-done:
-       snprintf(pktio_entry->s.name, IFNAMSIZ, "%s", dev);
-       unlock_entry_classifier(pktio_entry);
        return id;
 }
 
@@ -284,6 +302,36 @@ int odp_pktio_close(odp_pktio_t id)
        return 0;
 }
 
+odp_pktio_t odp_pktio_lookup(const char *dev)
+{
+       odp_pktio_t id = ODP_PKTIO_INVALID;
+       pktio_entry_t *entry;
+       int i;
+
+       odp_spinlock_lock(&pktio_tbl->lock);
+
+       for (i = 1; i <= ODP_CONFIG_PKTIO_ENTRIES; ++i) {
+               entry = get_pktio_entry(i);
+               if (is_free(entry))
+                       continue;
+
+               lock_entry(entry);
+
+               if (!is_free(entry) &&
+                   strncmp(entry->s.name, dev, IFNAMSIZ) == 0)
+                       id = i;
+
+               unlock_entry(entry);
+
+               if (id != ODP_PKTIO_INVALID)
+                       break;
+       }
+
+       odp_spinlock_unlock(&pktio_tbl->lock);
+
+       return id;
+}
+
 int odp_pktio_recv(odp_pktio_t id, odp_packet_t pkt_table[], unsigned len)
 {
        pktio_entry_t *pktio_entry = get_pktio_entry(id);
-- 
2.1.1



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

Reply via email to