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
>
>

Reply via email to