@@ -18,6 +18,7 @@
#include <odp_buffer_pool.h>
#include <odp_packet.h>
#include <odp_spinlock.h>
+#include <odp_ticketlock.h>
#define ODP_NETMAP_RING_HW 0
#define ODP_NETMAP_RING_SW 1
@@ -29,6 +30,8 @@
*/
typedef struct {
char ifname[IFNAMSIZ];
+ odp_ticketlock_t rx_lock;
+ odp_ticketlock_t tx_lock;
} netmap_dev_t;
/** Packet socket using netmap mmaped rings for both Rx and Tx */
@@ -196,6 +196,8 @@ int setup_pkt_netmap(pkt_netmap_t * const pkt_nm, const char *netdev,
nm_dev_cnt++;
snprintf(netmap_devs[i].ifname, sizeof(netmap_devs[i].ifname),
"%s", netdev);
+ odp_ticketlock_init(&netmap_devs[i].rx_lock);
+ odp_ticketlock_init(&netmap_devs[i].tx_lock);
pkt_nm->nm_dev = &netmap_devs[i];
}
odp_spinlock_unlock(&nm_global_lock);
@@ -311,14 +313,19 @@ int recv_pkt_netmap(pkt_netmap_t * const pkt_nm, odp_packet_t pkt_table[],
fds[0].fd = fd;
fds[0].events = POLLIN;
- ret = poll(fds, 1, POLL_TMO);
- if (ret <= 0 || (fds[0].revents & POLLERR))
- return 0;
-
args.pkt_table = pkt_table;
args.nb_rx = 0;
args.pkt_nm = pkt_nm;
+
+ odp_ticketlock_lock(&pkt_nm->nm_dev->rx_lock);
+ ret = poll(fds, 1, POLL_TMO);
+ if (ret <= 0 || (fds[0].revents & POLLERR)) {
+ odp_ticketlock_unlock(&pkt_nm->nm_dev->rx_lock);
+ return 0;
+ }
+
nm_dispatch(pkt_nm->desc, len, nm_recv_cb, (uint8_t *)&args);
+ odp_ticketlock_unlock(&pkt_nm->nm_dev->rx_lock);
return args.nb_rx;
}
@@ -334,9 +341,12 @@ int send_pkt_netmap(pkt_netmap_t * const pkt_nm, odp_packet_t pkt_table[],
fds[0].fd = fd;
fds[0].events = POLLOUT;
+ odp_ticketlock_lock(&pkt_nm->nm_dev->tx_lock);
ret = poll(fds, 1, POLL_TMO);
- if (ret <= 0 || (fds[0].revents & POLLERR))
+ if (ret <= 0 || (fds[0].revents & POLLERR)) {
+ odp_ticketlock_unlock(&pkt_nm->nm_dev->tx_lock);
goto out;
+ }
for (nb_tx = 0; nb_tx < len; nb_tx++) {
odp_packet_t pkt = pkt_table[nb_tx];
@@ -345,6 +355,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) == 0)
break;
}
+ odp_ticketlock_unlock(&pkt_nm->nm_dev->tx_lock);
out:
for (tx = 0; tx < len; tx++)
These locks ensure exclusive access to netmap rings when at least two different pktios are opened for the same interface. Exclusive access to pktio instance is already guaranteed via lock_entry and unlock_entry. Signed-off-by: Ciprian Barbu <ciprian.barbu@linaro.org> --- platform/linux-netmap/include/odp_packet_netmap.h | 3 +++ platform/linux-netmap/odp_packet_netmap.c | 21 ++++++++++++++++----- 2 files changed, 19 insertions(+), 5 deletions(-)