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 <[email protected]>
---
 .../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 --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;
 }
-- 
1.9.1

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

Reply via email to