diff options
author | Matias Elo <matias.elo@nokia.com> | 2017-05-23 15:38:54 +0300 |
---|---|---|
committer | Maxim Uvarov <maxim.uvarov@linaro.org> | 2017-05-23 23:14:36 +0300 |
commit | 60b9dd435bf1be55794e5be6ee24714d28a5b587 (patch) | |
tree | d172f31b75b5871560c464b2d27761404fad8964 /platform/linux-generic | |
parent | 599ac6802352c9c56eca33a6004824783becaa6e (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.c | 8 | ||||
-rw-r--r-- | platform/linux-generic/odp_queue.c | 1 | ||||
-rw-r--r-- | platform/linux-generic/odp_schedule.c | 5 | ||||
-rw-r--r-- | platform/linux-generic/odp_schedule_iquery.c | 5 |
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); |