aboutsummaryrefslogtreecommitdiff
path: root/platform/linux-generic
diff options
context:
space:
mode:
authorMatias Elo <matias.elo@nokia.com>2017-05-23 15:38:54 +0300
committerMaxim Uvarov <maxim.uvarov@linaro.org>2017-05-23 23:14:36 +0300
commit60b9dd435bf1be55794e5be6ee24714d28a5b587 (patch)
treed172f31b75b5871560c464b2d27761404fad8964 /platform/linux-generic
parent599ac6802352c9c56eca33a6004824783becaa6e (diff)
linux-gen: sched: fix ordered enqueue to pktout queue
Make sure packet order is maintained if enqueueing packets from an ordered queue. Fixes https://bugs.linaro.org/show_bug.cgi?id=3002 Signed-off-by: Matias Elo <matias.elo@nokia.com> Reviewed-and-tested-by: Yi He <yi.he@linaro.org> Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
Diffstat (limited to 'platform/linux-generic')
-rw-r--r--platform/linux-generic/odp_packet_io.c8
-rw-r--r--platform/linux-generic/odp_queue.c1
-rw-r--r--platform/linux-generic/odp_schedule.c5
-rw-r--r--platform/linux-generic/odp_schedule_iquery.c5
4 files changed, 17 insertions, 2 deletions
diff --git a/platform/linux-generic/odp_packet_io.c b/platform/linux-generic/odp_packet_io.c
index 98460a566..50a000e5b 100644
--- a/platform/linux-generic/odp_packet_io.c
+++ b/platform/linux-generic/odp_packet_io.c
@@ -586,6 +586,10 @@ int pktout_enqueue(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr)
int len = 1;
int nbr;
+ if (sched_fn->ord_enq_multi(qentry->s.index, (void **)buf_hdr, len,
+ &nbr))
+ return (nbr == len ? 0 : -1);
+
nbr = odp_pktout_send(qentry->s.pktout, &pkt, len);
return (nbr == len ? 0 : -1);
}
@@ -603,6 +607,10 @@ int pktout_enq_multi(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr[],
int nbr;
int i;
+ if (sched_fn->ord_enq_multi(qentry->s.index, (void **)buf_hdr, num,
+ &nbr))
+ return nbr;
+
for (i = 0; i < num; ++i)
pkt_tbl[i] = _odp_packet_from_buffer(buf_hdr[i]->handle.handle);
diff --git a/platform/linux-generic/odp_queue.c b/platform/linux-generic/odp_queue.c
index fcf4bf5bb..a96f9225f 100644
--- a/platform/linux-generic/odp_queue.c
+++ b/platform/linux-generic/odp_queue.c
@@ -95,6 +95,7 @@ static int queue_init(queue_entry_t *queue, const char *name,
queue->s.dequeue_multi = queue_deq_multi;
queue->s.pktin = PKTIN_INVALID;
+ queue->s.pktout = PKTOUT_INVALID;
queue->s.head = NULL;
queue->s.tail = NULL;
diff --git a/platform/linux-generic/odp_schedule.c b/platform/linux-generic/odp_schedule.c
index f680ac47e..c4567d810 100644
--- a/platform/linux-generic/odp_schedule.c
+++ b/platform/linux-generic/odp_schedule.c
@@ -20,6 +20,7 @@
#include <odp_config_internal.h>
#include <odp_align_internal.h>
#include <odp/api/sync.h>
+#include <odp/api/packet_io.h>
#include <odp_ring_internal.h>
#include <odp_queue_internal.h>
@@ -729,7 +730,9 @@ static int schedule_ord_enq_multi(uint32_t queue_index, void *buf_hdr[],
return 0;
}
- if (odp_unlikely(stash_num >= MAX_ORDERED_STASH)) {
+ /* Pktout may drop packets, so the operation cannot be stashed. */
+ if (dst_queue->s.pktout.pktio != ODP_PKTIO_INVALID ||
+ odp_unlikely(stash_num >= MAX_ORDERED_STASH)) {
/* If the local stash is full, wait until it is our turn and
* then release the stash and do enqueue directly. */
wait_for_order(src_queue);
diff --git a/platform/linux-generic/odp_schedule_iquery.c b/platform/linux-generic/odp_schedule_iquery.c
index b8a400117..75470aff8 100644
--- a/platform/linux-generic/odp_schedule_iquery.c
+++ b/platform/linux-generic/odp_schedule_iquery.c
@@ -21,6 +21,7 @@
#include <odp/api/hints.h>
#include <odp/api/cpu.h>
#include <odp/api/thrmask.h>
+#include <odp/api/packet_io.h>
#include <odp_config_internal.h>
/* Number of priority levels */
@@ -1176,7 +1177,9 @@ static int schedule_ord_enq_multi(uint32_t queue_index, void *buf_hdr[],
return 0;
}
- if (odp_unlikely(stash_num >= MAX_ORDERED_STASH)) {
+ /* Pktout may drop packets, so the operation cannot be stashed. */
+ if (dst_queue->s.pktout.pktio != ODP_PKTIO_INVALID ||
+ odp_unlikely(stash_num >= MAX_ORDERED_STASH)) {
/* If the local stash is full, wait until it is our turn and
* then release the stash and do enqueue directly. */
wait_for_order(src_queue);