Reviewed-and-tested-by: Yi He <yi...@linaro.org>
On 22 May 2017 at 17:39, Matias Elo <matias....@nokia.com> wrote: > 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....@nokia.com> > --- > platform/linux-generic/odp_packet_io.c | 8 ++++++++ > platform/linux-generic/odp_queue.c | 1 + > platform/linux-generic/odp_schedule.c | 5 ++++- > 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 98460a5..7e45c63 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; > + > 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 fcf4bf5..a96f922 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 f680ac4..c4567d8 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 b8a4001..75470af 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); > -- > 2.7.4 > >