diff mbox

[2/2] linux-generic: packet_io: separate locks for RX/TX

Message ID 1453307831-15459-3-git-send-email-zoltan.kiss@linaro.org
State Accepted
Commit 09601c62d322952e705d9e8d6b60d38b8ca13d15
Headers show

Commit Message

Zoltan Kiss Jan. 20, 2016, 4:37 p.m. UTC
It's possible that two threads want to use the same packet IO in the same
time, but one wants RX while the other wants TX. In this case they would
block each other unnecessary on the same lock. This could be seen e.g.
with odp_l2fwd.
Replace that lock with two new ones for each direction. Most callers need
both, but send and receive can work with only one.

Signed-off-by: Zoltan Kiss <zoltan.kiss@linaro.org>
---
 .../linux-generic/include/odp_packet_io_internal.h |  4 +++-
 platform/linux-generic/odp_packet_io.c             | 27 +++++++++++++---------
 2 files changed, 19 insertions(+), 12 deletions(-)
diff mbox

Patch

diff --git a/platform/linux-generic/include/odp_packet_io_internal.h b/platform/linux-generic/include/odp_packet_io_internal.h
index 4d73952..84bee1e 100644
--- a/platform/linux-generic/include/odp_packet_io_internal.h
+++ b/platform/linux-generic/include/odp_packet_io_internal.h
@@ -64,7 +64,9 @@  typedef struct {
 
 struct pktio_entry {
 	const struct pktio_if_ops *ops; /**< Implementation specific methods */
-	odp_ticketlock_t lock;		/**< entry ticketlock */
+	/* These two locks together lock the whole pktio device */
+	odp_ticketlock_t rxl;		/**< RX ticketlock */
+	odp_ticketlock_t txl;		/**< TX ticketlock */
 	int taken;			/**< is entry taken(1) or free(0) */
 	int cls_enabled;		/**< is classifier enabled */
 	odp_pktio_t handle;		/**< pktio handle */
diff --git a/platform/linux-generic/odp_packet_io.c b/platform/linux-generic/odp_packet_io.c
index 267aa01..908f9a4 100644
--- a/platform/linux-generic/odp_packet_io.c
+++ b/platform/linux-generic/odp_packet_io.c
@@ -55,7 +55,8 @@  int odp_pktio_init_global(void)
 	for (id = 1; id <= ODP_CONFIG_PKTIO_ENTRIES; ++id) {
 		pktio_entry = &pktio_tbl->entries[id - 1];
 
-		odp_ticketlock_init(&pktio_entry->s.lock);
+		odp_ticketlock_init(&pktio_entry->s.rxl);
+		odp_ticketlock_init(&pktio_entry->s.txl);
 		odp_spinlock_init(&pktio_entry->s.cls.lock);
 		odp_spinlock_init(&pktio_entry->s.cls.l2_cos_table.lock);
 		odp_spinlock_init(&pktio_entry->s.cls.l3_cos_table.lock);
@@ -106,24 +107,28 @@  static void set_taken(pktio_entry_t *entry)
 
 static void lock_entry(pktio_entry_t *entry)
 {
-	odp_ticketlock_lock(&entry->s.lock);
+	odp_ticketlock_lock(&entry->s.rxl);
+	odp_ticketlock_lock(&entry->s.txl);
 }
 
 static void unlock_entry(pktio_entry_t *entry)
 {
-	odp_ticketlock_unlock(&entry->s.lock);
+	odp_ticketlock_unlock(&entry->s.txl);
+	odp_ticketlock_unlock(&entry->s.rxl);
 }
 
 static void lock_entry_classifier(pktio_entry_t *entry)
 {
-	odp_ticketlock_lock(&entry->s.lock);
+	odp_ticketlock_lock(&entry->s.rxl);
+	odp_ticketlock_lock(&entry->s.txl);
 	odp_spinlock_lock(&entry->s.cls.lock);
 }
 
 static void unlock_entry_classifier(pktio_entry_t *entry)
 {
 	odp_spinlock_unlock(&entry->s.cls.lock);
-	odp_ticketlock_unlock(&entry->s.lock);
+	odp_ticketlock_unlock(&entry->s.txl);
+	odp_ticketlock_unlock(&entry->s.rxl);
 }
 
 static void init_pktio_entry(pktio_entry_t *entry)
@@ -385,15 +390,15 @@  int odp_pktio_recv(odp_pktio_t id, odp_packet_t pkt_table[], int len)
 	if (pktio_entry == NULL)
 		return -1;
 
-	lock_entry(pktio_entry);
+	odp_ticketlock_lock(&pktio_entry->s.rxl);
 	if (pktio_entry->s.state == STATE_STOP ||
 	    pktio_entry->s.param.in_mode == ODP_PKTIN_MODE_DISABLED) {
-		unlock_entry(pktio_entry);
+		odp_ticketlock_unlock(&pktio_entry->s.rxl);
 		__odp_errno = EPERM;
 		return -1;
 	}
 	pkts = pktio_entry->s.ops->recv(pktio_entry, pkt_table, len);
-	unlock_entry(pktio_entry);
+	odp_ticketlock_unlock(&pktio_entry->s.rxl);
 
 	if (pkts < 0)
 		return pkts;
@@ -412,15 +417,15 @@  int odp_pktio_send(odp_pktio_t id, odp_packet_t pkt_table[], int len)
 	if (pktio_entry == NULL)
 		return -1;
 
-	lock_entry(pktio_entry);
+	odp_ticketlock_lock(&pktio_entry->s.txl);
 	if (pktio_entry->s.state == STATE_STOP ||
 	    pktio_entry->s.param.out_mode == ODP_PKTOUT_MODE_DISABLED) {
-		unlock_entry(pktio_entry);
+			odp_ticketlock_unlock(&pktio_entry->s.txl);
 		__odp_errno = EPERM;
 		return -1;
 	}
 	pkts = pktio_entry->s.ops->send(pktio_entry, pkt_table, len);
-	unlock_entry(pktio_entry);
+	odp_ticketlock_unlock(&pktio_entry->s.txl);
 
 	return pkts;
 }