Using separate file descriptors enables using rx and tx
functions simultaneously from different threads.

Previously netmap tx queues were flushed only after no free
slots were left which caused long delays on slow packet
rates. Now queues are flushed after each packet
burst.

Signed-off-by: Matias Elo <[email protected]>
---
 platform/linux-generic/include/odp_packet_netmap.h |  3 ++-
 platform/linux-generic/pktio/netmap.c              | 29 ++++++++++++++--------
 2 files changed, 21 insertions(+), 11 deletions(-)

diff --git a/platform/linux-generic/include/odp_packet_netmap.h 
b/platform/linux-generic/include/odp_packet_netmap.h
index 23aea5b..0577dfe 100644
--- a/platform/linux-generic/include/odp_packet_netmap.h
+++ b/platform/linux-generic/include/odp_packet_netmap.h
@@ -15,7 +15,8 @@
 typedef struct {
        odp_pool_t pool;                /**< pool to alloc packets from */
        size_t max_frame_len;           /**< buf_size - sizeof(pkt_hdr) */
-       struct nm_desc *desc;           /**< netmap meta-data for the device */
+       struct nm_desc *rx_desc;        /**< netmap meta-data for the device */
+       struct nm_desc *tx_desc;        /**< netmap meta-data for the device */
        uint32_t if_flags;              /**< interface flags */
        int sockfd;                     /**< control socket */
        unsigned char if_mac[ETH_ALEN]; /**< eth mac address */
diff --git a/platform/linux-generic/pktio/netmap.c 
b/platform/linux-generic/pktio/netmap.c
index b93dbfd..092fa30 100644
--- a/platform/linux-generic/pktio/netmap.c
+++ b/platform/linux-generic/pktio/netmap.c
@@ -89,10 +89,13 @@ static int netmap_close(pktio_entry_t *pktio_entry)
 {
        pkt_netmap_t *pkt_nm = &pktio_entry->s.pkt_nm;
 
-       if (pkt_nm->desc != NULL) {
-               nm_close(pkt_nm->desc);
+       if (pkt_nm->rx_desc != NULL) {
+               nm_close(pkt_nm->rx_desc);
                mmap_desc.mem = NULL;
        }
+       if (pkt_nm->tx_desc != NULL)
+               nm_close(pkt_nm->tx_desc);
+
        if (pkt_nm->sockfd != -1 && close(pkt_nm->sockfd) != 0) {
                __odp_errno = errno;
                ODP_ERR("close(sockfd): %s\n", strerror(errno));
@@ -131,18 +134,21 @@ static int netmap_open(odp_pktio_t id ODP_UNUSED, 
pktio_entry_t *pktio_entry,
        snprintf(ifname, sizeof(ifname), "netmap:%s", netdev);
 
        if (mmap_desc.mem == NULL)
-               pkt_nm->desc = nm_open(ifname, NULL, NETMAP_NO_TX_POLL, NULL);
+               pkt_nm->rx_desc = nm_open(ifname, NULL, NETMAP_NO_TX_POLL,
+                                         NULL);
        else
-               pkt_nm->desc = nm_open(ifname, NULL, NETMAP_NO_TX_POLL |
-                                      NM_OPEN_NO_MMAP, &mmap_desc);
-       if (pkt_nm->desc == NULL) {
+               pkt_nm->rx_desc = nm_open(ifname, NULL, NETMAP_NO_TX_POLL |
+                                         NM_OPEN_NO_MMAP, &mmap_desc);
+       pkt_nm->tx_desc = nm_open(ifname, NULL, NM_OPEN_NO_MMAP, &mmap_desc);
+
+       if (pkt_nm->rx_desc == NULL || pkt_nm->tx_desc == NULL) {
                ODP_ERR("nm_open(%s) failed\n", ifname);
                goto error;
        }
 
        if (mmap_desc.mem == NULL) {
-               mmap_desc.mem = pkt_nm->desc->mem;
-               mmap_desc.memsize = pkt_nm->desc->memsize;
+               mmap_desc.mem = pkt_nm->rx_desc->mem;
+               mmap_desc.memsize = pkt_nm->rx_desc->memsize;
        }
 
        sockfd = socket(AF_INET, SOCK_DGRAM, 0);
@@ -220,7 +226,7 @@ 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.desc;
+       struct nm_desc *nm_desc = pktio_entry->s.pkt_nm.rx_desc;
        struct pollfd polld;
 
        polld.fd = nm_desc->fd;
@@ -241,8 +247,8 @@ static int netmap_recv(pktio_entry_t *pktio_entry, 
odp_packet_t pkt_table[],
 static int netmap_send(pktio_entry_t *pktio_entry, odp_packet_t pkt_table[],
                       unsigned num)
 {
-       struct nm_desc *nm_desc = pktio_entry->s.pkt_nm.desc;
        struct pollfd polld;
+       struct nm_desc *nm_desc = pktio_entry->s.pkt_nm.tx_desc;
        unsigned i, nb_tx;
        uint8_t *frame;
        uint32_t frame_len;
@@ -264,6 +270,9 @@ static int netmap_send(pktio_entry_t *pktio_entry, 
odp_packet_t pkt_table[],
                        break;
                }
        }
+       /* Send pending packets */
+       poll(&polld, 1, 0);
+
        for (i = 0; i < nb_tx; i++)
                odp_packet_free(pkt_table[i]);
 
-- 
1.9.1

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

Reply via email to