diff mbox

[RFC] Remove queue types ODP_QUEUE_TYPE_PKTIN and PKTOUT

Message ID 1412965700261.42362@caviumnetworks.com
State New
Headers show

Commit Message

Rosenboim, Leonid Oct. 10, 2014, 6:28 p.m. UTC
Stuart,

The declaration of a queue as PKTIN, PKTOUT during creation time is NOT an implementation detail, and was in my opinion deliberate and changing this will have serious consequences for our ability to support this API on Octeon SoCs.

Octeon has queues implemented in hardware, and there are two distinct types of queues supported in the hardware of these chips: One type of queue is for scheduling incoming packets, timer events and generic events initiated by an application or packets in transit (SSO). The other type of queues are only used for packet output (PKO). For mapping an ODP queue to one of these, the implementation needs to know the queue's intended use to select and reserve a resource from the correct resource type.

It seems your comprehension of the API is entirely focused on a software based implementation, without considering advanced network processors, and the ability of the ODP API to abstract these hardware mechanisms. The objective of enabling the mapping of network processor packet processing hardware to ODP APIs is an objective clearly set forth in ODP charter, and should not be neglected.

Here are some documents in the public domain containing further information.
http://university.caviumnetworks.com/downloads/Mini_version_of_Prog_Guide_EDU_July_2010.pdf.
hactive.googlecode.com/files/CN50XX-HRM-V0.99E.pdf

Detailed documentation on the latest SoC models and complete and updated programmers guide is available under NDA.

- Leo

Comments

Bill Fischofer Oct. 10, 2014, 7:39 p.m. UTC | #1
We had discussed moving PKTIN/PKTOUT from the odp_queue_type to a new
odp_queue_class, with the rationale being that these really were orthogonal
concepts, not eliminating it.  I agree with Leo that we need to be mindful
of HW-based implementations in the design of all ODP APIs.  It's the main
reason why we do these designs in the open so that the various
implementation stake holders can provide feedback on API feasibility and
opportunities for acceleration, along with recommendations concerning the
appropriate level of abstraction needed to accomplish these goals.

I will be revising the queue design doc to reflect this.  I will be
traveling on business next Tuesday but Mike will be hosting the ODP team
call where this should be discussed in more detail.

Bill

On Fri, Oct 10, 2014 at 1:28 PM, Rosenboim, Leonid <
Leonid.Rosenboim@caviumnetworks.com> wrote:

> Stuart,
>
> The declaration of a queue as PKTIN, PKTOUT during creation time is NOT an
> implementation detail, and was in my opinion deliberate and changing this
> will have serious consequences for our ability to support this API on
> Octeon SoCs.
>
> Octeon has queues implemented in hardware, and there are two distinct
> types of queues supported in the hardware of these chips: One type of queue
> is for scheduling incoming packets, timer events and generic events
> initiated by an application or packets in transit (SSO). The other type of
> queues are only used for packet output (PKO). For mapping an ODP queue to
> one of these, the implementation needs to know the queue's intended use to
> select and reserve a resource from the correct resource type.
>
> It seems your comprehension of the API is entirely focused on a software
> based implementation, without considering advanced network processors, and
> the ability of the ODP API to abstract these hardware mechanisms. The
> objective of enabling the mapping of network processor packet processing
> hardware to ODP APIs is an objective clearly set forth in ODP charter, and
> should not be neglected.
>
> Here are some documents in the public domain containing further
> information.
>
> http://university.caviumnetworks.com/downloads/Mini_version_of_Prog_Guide_EDU_July_2010.pdf
> .
> hactive.googlecode.com/files/CN50XX-HRM-V0.99E.pdf
>
> Detailed documentation on the latest SoC models and complete and updated
> programmers guide is available under NDA.
>
> - Leo
> ________________________________________
> From: lng-odp-bounces@lists.linaro.org <lng-odp-bounces@lists.linaro.org>
> on behalf of Stuart Haslam <stuart.haslam@arm.com>
> Sent: Thursday, October 09, 2014 1:33 PM
> To: lng-odp@lists.linaro.org
> Subject: [lng-odp] [RFC PATCH] Remove queue types ODP_QUEUE_TYPE_PKTIN
> and      PKTOUT
>
> The PKTIN and PKTOUT queue types are currently used to identify queues
> as being attached to a pktio interface, but this is an implementation
> detail that has leaked into the API.
>
> Instead of using the queue type to modify the behaviour of a queue
> endpoint to send/recv packets over a pktio interface, add hooks to
> change this behaviour when a queue is set as a pktio input or output
> queue.
>
> Signed-off-by: Stuart Haslam <stuart.haslam@arm.com>
> ---
> Sending as an RFC for now as I've only done limited testing so far.
> Also, I'm not sure if other platforms depend on these queue types, I
> expect they don't but please shout if this is not the case.
>
> Tested only with SCHED queues with odp_pktio on linux-generic.
>
>  example/generator/odp_generator.c                  |  2 +-
>  example/ipsec/odp_ipsec.c                          |  4 +-
>  example/l2fwd/odp_l2fwd.c                          |  2 +-
>  example/packet/odp_pktio.c                         |  2 +-
>  platform/linux-generic/include/api/odp_queue.h     |  2 -
>  .../linux-generic/include/odp_queue_internal.h     |  3 ++
>  platform/linux-generic/odp_packet_io.c             | 10 ++--
>  platform/linux-generic/odp_queue.c                 | 61
> ++++++++++++----------
>  platform/linux-generic/odp_schedule.c              |  4 +-
>  9 files changed, 45 insertions(+), 45 deletions(-)
>
> diff --git a/example/generator/odp_generator.c
> b/example/generator/odp_generator.c
> index 6055324..d566a19 100644
> --- a/example/generator/odp_generator.c
> +++ b/example/generator/odp_generator.c
> @@ -473,7 +473,7 @@ static void *gen_recv_thread(void *arg)
>         qparam.sched.group = ODP_SCHED_GROUP_DEFAULT;
>         snprintf(inq_name, sizeof(inq_name), "%i-pktio_inq_def",
> (int)pktio);
>         inq_name[ODP_QUEUE_NAME_LEN - 1] = '\0';
> -       inq_def = odp_queue_create(inq_name, ODP_QUEUE_TYPE_PKTIN,
> &qparam);
> +       inq_def = odp_queue_create(inq_name, ODP_QUEUE_TYPE_SCHED,
> &qparam);
>         if (inq_def == ODP_QUEUE_INVALID) {
>                 ODP_ERR("  [%02i] Error: pktio queue creation failed\n",
> thr);
>                 return NULL;
> diff --git a/example/ipsec/odp_ipsec.c b/example/ipsec/odp_ipsec.c
> index ec6c87a..ba90242 100644
> --- a/example/ipsec/odp_ipsec.c
> +++ b/example/ipsec/odp_ipsec.c
> @@ -291,7 +291,7 @@ odp_queue_t polled_odp_queue_create(const char *name,
>
>         my_queue = odp_queue_create(name, my_type, param);
>
> -       if ((ODP_QUEUE_TYPE_SCHED == type) || (ODP_QUEUE_TYPE_PKTIN ==
> type)) {
> +       if (ODP_QUEUE_TYPE_SCHED == type) {
>                 poll_queues[num_polled_queues++] = my_queue;
>                 printf("%s: adding %d\n", __func__, my_queue);
>         }
> @@ -572,7 +572,7 @@ void initialize_intf(char *intf)
>         snprintf(inq_name, sizeof(inq_name), "%i-pktio_inq_def",
> (int)pktio);
>         inq_name[ODP_QUEUE_NAME_LEN - 1] = '\0';
>
> -       inq_def = QUEUE_CREATE(inq_name, ODP_QUEUE_TYPE_PKTIN, &qparam);
> +       inq_def = QUEUE_CREATE(inq_name, ODP_QUEUE_TYPE_SCHED, &qparam);
>         if (ODP_QUEUE_INVALID == inq_def) {
>                 ODP_ERR("Error: pktio queue creation failed for %s\n",
> intf);
>                 exit(EXIT_FAILURE);
> diff --git a/example/l2fwd/odp_l2fwd.c b/example/l2fwd/odp_l2fwd.c
> index 8aa0ba0..4f08dd2 100644
> --- a/example/l2fwd/odp_l2fwd.c
> +++ b/example/l2fwd/odp_l2fwd.c
> @@ -165,7 +165,7 @@ static odp_pktio_t queue_mode_init_params(void *arg,
> odp_buffer_pool_t pool)
>         snprintf(inq_name, sizeof(inq_name), "%i-pktio_inq_def",
> (int)pktio);
>         inq_name[ODP_QUEUE_NAME_LEN - 1] = '\0';
>
> -       inq_def = odp_queue_create(inq_name, ODP_QUEUE_TYPE_PKTIN,
> &qparam);
> +       inq_def = odp_queue_create(inq_name, ODP_QUEUE_TYPE_SCHED,
> &qparam);
>         if (inq_def == ODP_QUEUE_INVALID) {
>                 ODP_ERR("  Error: pktio queue creation failed");
>                 return ODP_PKTIO_INVALID;
> diff --git a/example/packet/odp_pktio.c b/example/packet/odp_pktio.c
> index 145ae47..afb2cd2 100644
> --- a/example/packet/odp_pktio.c
> +++ b/example/packet/odp_pktio.c
> @@ -151,7 +151,7 @@ static void *pktio_queue_thread(void *arg)
>         snprintf(inq_name, sizeof(inq_name), "%i-pktio_inq_def",
> (int)pktio);
>         inq_name[ODP_QUEUE_NAME_LEN - 1] = '\0';
>
> -       inq_def = odp_queue_create(inq_name, ODP_QUEUE_TYPE_PKTIN,
> &qparam);
> +       inq_def = odp_queue_create(inq_name, ODP_QUEUE_TYPE_SCHED,
> &qparam);
>         if (inq_def == ODP_QUEUE_INVALID) {
>                 ODP_ERR("  [%02i] Error: pktio queue creation failed\n",
> thr);
>                 return NULL;
> diff --git a/platform/linux-generic/include/api/odp_queue.h
> b/platform/linux-generic/include/api/odp_queue.h
> index 5e083f1..38ff272 100644
> --- a/platform/linux-generic/include/api/odp_queue.h
> +++ b/platform/linux-generic/include/api/odp_queue.h
> @@ -42,8 +42,6 @@ typedef int odp_queue_type_t;
>
>  #define ODP_QUEUE_TYPE_SCHED  0  /**< Scheduled queue */
>  #define ODP_QUEUE_TYPE_POLL   1  /**< Not scheduled queue */
> -#define ODP_QUEUE_TYPE_PKTIN  2  /**< Packet input queue */
> -#define ODP_QUEUE_TYPE_PKTOUT 3  /**< Packet output queue */
>
>  /**
>   * ODP schedule priority
> diff --git a/platform/linux-generic/include/odp_queue_internal.h
> b/platform/linux-generic/include/odp_queue_internal.h
> index 8b6c517..5329d4f 100644
> --- a/platform/linux-generic/include/odp_queue_internal.h
> +++ b/platform/linux-generic/include/odp_queue_internal.h
> @@ -95,6 +95,9 @@ void queue_unlock(queue_entry_t *queue);
>  odp_buffer_t queue_sched_buf(odp_queue_t queue);
>  int queue_sched_atomic(odp_queue_t handle);
>
> +void queue_set_pktin(queue_entry_t *queue, odp_pktio_t id);
> +void queue_set_pktout(queue_entry_t *queue, odp_pktio_t id);
> +
>  static inline uint32_t queue_to_id(odp_queue_t handle)
>  {
>         return handle - 1;
> diff --git a/platform/linux-generic/odp_packet_io.c
> b/platform/linux-generic/odp_packet_io.c
> index 0c30f0f..fbf23ff 100644
> --- a/platform/linux-generic/odp_packet_io.c
> +++ b/platform/linux-generic/odp_packet_io.c
> @@ -65,13 +65,13 @@ int odp_pktio_init_global(void)
>                 snprintf(name, sizeof(name), "%i-pktio_outq_default",
> (int)id);
>                 name[ODP_QUEUE_NAME_LEN-1] = '\0';
>
> -               qid = odp_queue_create(name, ODP_QUEUE_TYPE_PKTOUT, NULL);
> +               qid = odp_queue_create(name, ODP_QUEUE_TYPE_SCHED, NULL);
>                 if (qid == ODP_QUEUE_INVALID)
>                         return -1;
>                 pktio_entry->s.outq_default = qid;
>
>                 queue_entry = queue_to_qentry(qid);
> -               queue_entry->s.pktout = id;
> +               queue_set_pktout(queue_entry, id);
>         }
>
>         return 0;
> @@ -325,16 +325,12 @@ int odp_pktio_inq_setdef(odp_pktio_t id, odp_queue_t
> queue)
>         if (pktio_entry == NULL || qentry == NULL)
>                 return -1;
>
> -       if (qentry->s.type != ODP_QUEUE_TYPE_PKTIN)
> -               return -1;
> -
>         lock_entry(pktio_entry);
>         pktio_entry->s.inq_default = queue;
>         unlock_entry(pktio_entry);
>
>         queue_lock(qentry);
> -       qentry->s.pktin = id;
> -       qentry->s.status = QUEUE_STATUS_SCHED;
> +       queue_set_pktin(qentry, id);
>         queue_unlock(qentry);
>
>         odp_schedule_queue(queue, qentry->s.param.sched.prio);
> diff --git a/platform/linux-generic/odp_queue.c
> b/platform/linux-generic/odp_queue.c
> index 1318bcd..1f0e33a 100644
> --- a/platform/linux-generic/odp_queue.c
> +++ b/platform/linux-generic/odp_queue.c
> @@ -53,6 +53,8 @@ static void queue_init(queue_entry_t *queue, const char
> *name,
>  {
>         strncpy(queue->s.name, name, ODP_QUEUE_NAME_LEN - 1);
>         queue->s.type = type;
> +       queue->s.pktin  = ODP_PKTIO_INVALID;
> +       queue->s.pktout = ODP_PKTIO_INVALID;
>
>         if (param) {
>                 memcpy(&queue->s.param, param, sizeof(odp_queue_param_t));
> @@ -64,27 +66,10 @@ static void queue_init(queue_entry_t *queue, const
> char *name,
>                 queue->s.param.sched.group = ODP_SCHED_GROUP_DEFAULT;
>         }
>
> -       switch (type) {
> -       case ODP_QUEUE_TYPE_PKTIN:
> -               queue->s.enqueue = pktin_enqueue;
> -               queue->s.dequeue = pktin_dequeue;
> -               queue->s.enqueue_multi = pktin_enq_multi;
> -               queue->s.dequeue_multi = pktin_deq_multi;
> -               break;
> -       case ODP_QUEUE_TYPE_PKTOUT:
> -               queue->s.enqueue = pktout_enqueue;
> -               queue->s.dequeue = pktout_dequeue;
> -               queue->s.enqueue_multi = pktout_enq_multi;
> -               queue->s.dequeue_multi = pktout_deq_multi;
> -               break;
> -       default:
> -               queue->s.enqueue = queue_enq;
> -               queue->s.dequeue = queue_deq;
> -               queue->s.enqueue_multi = queue_enq_multi;
> -               queue->s.dequeue_multi = queue_deq_multi;
> -               break;
> -       }
> -
> +       queue->s.enqueue = queue_enq;
> +       queue->s.dequeue = queue_deq;
> +       queue->s.enqueue_multi = queue_enq_multi;
> +       queue->s.dequeue_multi = queue_deq_multi;
>         queue->s.head = NULL;
>         queue->s.tail = NULL;
>         queue->s.sched_buf = ODP_BUFFER_INVALID;
> @@ -162,8 +147,7 @@ odp_queue_t odp_queue_create(const char *name,
> odp_queue_type_t type,
>                 if (queue->s.status == QUEUE_STATUS_FREE) {
>                         queue_init(queue, name, type, param);
>
> -                       if (type == ODP_QUEUE_TYPE_SCHED ||
> -                           type == ODP_QUEUE_TYPE_PKTIN)
> +                       if (type == ODP_QUEUE_TYPE_SCHED)
>                                 queue->s.status = QUEUE_STATUS_NOTSCHED;
>                         else
>                                 queue->s.status = QUEUE_STATUS_READY;
> @@ -175,8 +159,7 @@ odp_queue_t odp_queue_create(const char *name,
> odp_queue_type_t type,
>                 UNLOCK(&queue->s.lock);
>         }
>
> -       if (handle != ODP_QUEUE_INVALID &&
> -           (type == ODP_QUEUE_TYPE_SCHED || type ==
> ODP_QUEUE_TYPE_PKTIN)) {
> +       if (handle != ODP_QUEUE_INVALID && type == ODP_QUEUE_TYPE_SCHED) {
>                 odp_buffer_t buf;
>
>                 buf = odp_schedule_buffer_alloc(handle);
> @@ -353,8 +337,7 @@ odp_buffer_hdr_t *queue_deq(queue_entry_t *queue)
>
>         if (queue->s.head == NULL) {
>                 /* Already empty queue */
> -               if (queue->s.status == QUEUE_STATUS_SCHED &&
> -                   queue->s.type != ODP_QUEUE_TYPE_PKTIN)
> +               if (queue->s.status == QUEUE_STATUS_SCHED)
>                         queue->s.status = QUEUE_STATUS_NOTSCHED;
>         } else {
>                 buf_hdr       = queue->s.head;
> @@ -381,8 +364,7 @@ int queue_deq_multi(queue_entry_t *queue,
> odp_buffer_hdr_t *buf_hdr[], int num)
>
>         if (queue->s.head == NULL) {
>                 /* Already empty queue */
> -               if (queue->s.status == QUEUE_STATUS_SCHED &&
> -                   queue->s.type != ODP_QUEUE_TYPE_PKTIN)
> +               if (queue->s.status == QUEUE_STATUS_SCHED)
>                         queue->s.status = QUEUE_STATUS_NOTSCHED;
>         } else {
>                 odp_buffer_hdr_t *hdr = queue->s.head;
> @@ -453,3 +435,24 @@ void queue_unlock(queue_entry_t *queue)
>  {
>         UNLOCK(&queue->s.lock);
>  }
> +
> +void queue_set_pktin(queue_entry_t *queue, odp_pktio_t pktio_id)
> +{
> +       queue->s.pktin = pktio_id;
> +       queue->s.enqueue = pktin_enqueue;
> +       queue->s.dequeue = pktin_dequeue;
> +       queue->s.enqueue_multi = pktin_enq_multi;
> +       queue->s.dequeue_multi = pktin_deq_multi;
> +       if (queue->s.type == ODP_QUEUE_TYPE_SCHED)
> +               queue->s.status = QUEUE_STATUS_SCHED;
> +}
> +
> +void queue_set_pktout(queue_entry_t *queue, odp_pktio_t pktio_id)
> +{
> +       queue->s.pktout = pktio_id;
> +       queue->s.enqueue = pktout_enqueue;
> +       queue->s.dequeue = pktout_dequeue;
> +       queue->s.enqueue_multi = pktout_enq_multi;
> +       queue->s.dequeue_multi = pktout_deq_multi;
> +}
> +
> diff --git a/platform/linux-generic/odp_schedule.c
> b/platform/linux-generic/odp_schedule.c
> index 1bf819b..5742196 100644
> --- a/platform/linux-generic/odp_schedule.c
> +++ b/platform/linux-generic/odp_schedule.c
> @@ -301,8 +301,8 @@ static int schedule(odp_queue_t *out_queue,
> odp_buffer_t out_buf[],
>                                         /* Remove empty queue from
> scheduling,
>                                          * except packet input queues
>                                          */
> -                                       if (odp_queue_type(queue) ==
> -                                           ODP_QUEUE_TYPE_PKTIN)
> +                                       queue_entry_t *qentry =
> queue_to_qentry(queue);
> +                                       if (qentry->s.pktin !=
> ODP_PKTIO_INVALID)
>                                                 odp_queue_enq(pri_q,
> desc_buf);
>
>                                         continue;
> --
> 1.9.1
>
>
>
> _______________________________________________
> lng-odp mailing list
> lng-odp@lists.linaro.org
> http://lists.linaro.org/mailman/listinfo/lng-odp
>
Savolainen, Petri (NSN - FI/Espoo) Oct. 13, 2014, 7:14 a.m. UTC | #2
Hi Leo,

As Stuart pointed out, PKTIO/PKTOUT slipped into the API during early packet IO integration. The queue type (as currently defined) should only identify how application is going to dequeue from a  queue (either through scheduler or by polling).

Creation of those queues that application is only enqueuing to (and ODP dequeueing from) could be hidden from the application. For example, application could ask ODP (through a packet output API call) for a queue that sends packet out through a given interface with given (output scheduling/shaping) properties. 

I think, it's more flexible that way than application creating queues (with a list of queue parameters) and then give that queue to the packet out API.


-Petri



> -----Original Message-----
> From: lng-odp-bounces@lists.linaro.org [mailto:lng-odp-
> bounces@lists.linaro.org] On Behalf Of ext Rosenboim, Leonid
> Sent: Friday, October 10, 2014 9:28 PM
> To: Stuart Haslam; lng-odp@lists.linaro.org
> Cc: Kapoor, Prasun; Manoharan, Balasubramanian
> Subject: Re: [lng-odp] [RFC PATCH] Remove queue types ODP_QUEUE_TYPE_PKTIN
> and PKTOUT
> Importance: High
> 
> Stuart,
> 
> The declaration of a queue as PKTIN, PKTOUT during creation time is NOT an
> implementation detail, and was in my opinion deliberate and changing this
> will have serious consequences for our ability to support this API on
> Octeon SoCs.
> 
> Octeon has queues implemented in hardware, and there are two distinct
> types of queues supported in the hardware of these chips: One type of
> queue is for scheduling incoming packets, timer events and generic events
> initiated by an application or packets in transit (SSO). The other type of
> queues are only used for packet output (PKO). For mapping an ODP queue to
> one of these, the implementation needs to know the queue's intended use to
> select and reserve a resource from the correct resource type.
> 
> It seems your comprehension of the API is entirely focused on a software
> based implementation, without considering advanced network processors, and
> the ability of the ODP API to abstract these hardware mechanisms. The
> objective of enabling the mapping of network processor packet processing
> hardware to ODP APIs is an objective clearly set forth in ODP charter, and
> should not be neglected.
> 
> Here are some documents in the public domain containing further
> information.
> http://university.caviumnetworks.com/downloads/Mini_version_of_Prog_Guide_
> EDU_July_2010.pdf.
> hactive.googlecode.com/files/CN50XX-HRM-V0.99E.pdf
> 
> Detailed documentation on the latest SoC models and complete and updated
> programmers guide is available under NDA.
> 
> - Leo
> ________________________________________
> From: lng-odp-bounces@lists.linaro.org <lng-odp-bounces@lists.linaro.org>
> on behalf of Stuart Haslam <stuart.haslam@arm.com>
> Sent: Thursday, October 09, 2014 1:33 PM
> To: lng-odp@lists.linaro.org
> Subject: [lng-odp] [RFC PATCH] Remove queue types ODP_QUEUE_TYPE_PKTIN and
> PKTOUT
> 
> The PKTIN and PKTOUT queue types are currently used to identify queues
> as being attached to a pktio interface, but this is an implementation
> detail that has leaked into the API.
> 
> Instead of using the queue type to modify the behaviour of a queue
> endpoint to send/recv packets over a pktio interface, add hooks to
> change this behaviour when a queue is set as a pktio input or output
> queue.
> 
> Signed-off-by: Stuart Haslam <stuart.haslam@arm.com>
> ---
> Sending as an RFC for now as I've only done limited testing so far.
> Also, I'm not sure if other platforms depend on these queue types, I
> expect they don't but please shout if this is not the case.
> 
> Tested only with SCHED queues with odp_pktio on linux-generic.
> 
>  example/generator/odp_generator.c                  |  2 +-
>  example/ipsec/odp_ipsec.c                          |  4 +-
>  example/l2fwd/odp_l2fwd.c                          |  2 +-
>  example/packet/odp_pktio.c                         |  2 +-
>  platform/linux-generic/include/api/odp_queue.h     |  2 -
>  .../linux-generic/include/odp_queue_internal.h     |  3 ++
>  platform/linux-generic/odp_packet_io.c             | 10 ++--
>  platform/linux-generic/odp_queue.c                 | 61 ++++++++++++-----
> -----
>  platform/linux-generic/odp_schedule.c              |  4 +-
>  9 files changed, 45 insertions(+), 45 deletions(-)
> 
> diff --git a/example/generator/odp_generator.c
> b/example/generator/odp_generator.c
> index 6055324..d566a19 100644
> --- a/example/generator/odp_generator.c
> +++ b/example/generator/odp_generator.c
> @@ -473,7 +473,7 @@ static void *gen_recv_thread(void *arg)
>         qparam.sched.group = ODP_SCHED_GROUP_DEFAULT;
>         snprintf(inq_name, sizeof(inq_name), "%i-pktio_inq_def",
> (int)pktio);
>         inq_name[ODP_QUEUE_NAME_LEN - 1] = '\0';
> -       inq_def = odp_queue_create(inq_name, ODP_QUEUE_TYPE_PKTIN,
> &qparam);
> +       inq_def = odp_queue_create(inq_name, ODP_QUEUE_TYPE_SCHED,
> &qparam);
>         if (inq_def == ODP_QUEUE_INVALID) {
>                 ODP_ERR("  [%02i] Error: pktio queue creation failed\n",
> thr);
>                 return NULL;
> diff --git a/example/ipsec/odp_ipsec.c b/example/ipsec/odp_ipsec.c
> index ec6c87a..ba90242 100644
> --- a/example/ipsec/odp_ipsec.c
> +++ b/example/ipsec/odp_ipsec.c
> @@ -291,7 +291,7 @@ odp_queue_t polled_odp_queue_create(const char *name,
> 
>         my_queue = odp_queue_create(name, my_type, param);
> 
> -       if ((ODP_QUEUE_TYPE_SCHED == type) || (ODP_QUEUE_TYPE_PKTIN ==
> type)) {
> +       if (ODP_QUEUE_TYPE_SCHED == type) {
>                 poll_queues[num_polled_queues++] = my_queue;
>                 printf("%s: adding %d\n", __func__, my_queue);
>         }
> @@ -572,7 +572,7 @@ void initialize_intf(char *intf)
>         snprintf(inq_name, sizeof(inq_name), "%i-pktio_inq_def",
> (int)pktio);
>         inq_name[ODP_QUEUE_NAME_LEN - 1] = '\0';
> 
> -       inq_def = QUEUE_CREATE(inq_name, ODP_QUEUE_TYPE_PKTIN, &qparam);
> +       inq_def = QUEUE_CREATE(inq_name, ODP_QUEUE_TYPE_SCHED, &qparam);
>         if (ODP_QUEUE_INVALID == inq_def) {
>                 ODP_ERR("Error: pktio queue creation failed for %s\n",
> intf);
>                 exit(EXIT_FAILURE);
> diff --git a/example/l2fwd/odp_l2fwd.c b/example/l2fwd/odp_l2fwd.c
> index 8aa0ba0..4f08dd2 100644
> --- a/example/l2fwd/odp_l2fwd.c
> +++ b/example/l2fwd/odp_l2fwd.c
> @@ -165,7 +165,7 @@ static odp_pktio_t queue_mode_init_params(void *arg,
> odp_buffer_pool_t pool)
>         snprintf(inq_name, sizeof(inq_name), "%i-pktio_inq_def",
> (int)pktio);
>         inq_name[ODP_QUEUE_NAME_LEN - 1] = '\0';
> 
> -       inq_def = odp_queue_create(inq_name, ODP_QUEUE_TYPE_PKTIN,
> &qparam);
> +       inq_def = odp_queue_create(inq_name, ODP_QUEUE_TYPE_SCHED,
> &qparam);
>         if (inq_def == ODP_QUEUE_INVALID) {
>                 ODP_ERR("  Error: pktio queue creation failed");
>                 return ODP_PKTIO_INVALID;
> diff --git a/example/packet/odp_pktio.c b/example/packet/odp_pktio.c
> index 145ae47..afb2cd2 100644
> --- a/example/packet/odp_pktio.c
> +++ b/example/packet/odp_pktio.c
> @@ -151,7 +151,7 @@ static void *pktio_queue_thread(void *arg)
>         snprintf(inq_name, sizeof(inq_name), "%i-pktio_inq_def",
> (int)pktio);
>         inq_name[ODP_QUEUE_NAME_LEN - 1] = '\0';
> 
> -       inq_def = odp_queue_create(inq_name, ODP_QUEUE_TYPE_PKTIN,
> &qparam);
> +       inq_def = odp_queue_create(inq_name, ODP_QUEUE_TYPE_SCHED,
> &qparam);
>         if (inq_def == ODP_QUEUE_INVALID) {
>                 ODP_ERR("  [%02i] Error: pktio queue creation failed\n",
> thr);
>                 return NULL;
> diff --git a/platform/linux-generic/include/api/odp_queue.h
> b/platform/linux-generic/include/api/odp_queue.h
> index 5e083f1..38ff272 100644
> --- a/platform/linux-generic/include/api/odp_queue.h
> +++ b/platform/linux-generic/include/api/odp_queue.h
> @@ -42,8 +42,6 @@ typedef int odp_queue_type_t;
> 
>  #define ODP_QUEUE_TYPE_SCHED  0  /**< Scheduled queue */
>  #define ODP_QUEUE_TYPE_POLL   1  /**< Not scheduled queue */
> -#define ODP_QUEUE_TYPE_PKTIN  2  /**< Packet input queue */
> -#define ODP_QUEUE_TYPE_PKTOUT 3  /**< Packet output queue */
> 
>  /**
>   * ODP schedule priority
> diff --git a/platform/linux-generic/include/odp_queue_internal.h
> b/platform/linux-generic/include/odp_queue_internal.h
> index 8b6c517..5329d4f 100644
> --- a/platform/linux-generic/include/odp_queue_internal.h
> +++ b/platform/linux-generic/include/odp_queue_internal.h
> @@ -95,6 +95,9 @@ void queue_unlock(queue_entry_t *queue);
>  odp_buffer_t queue_sched_buf(odp_queue_t queue);
>  int queue_sched_atomic(odp_queue_t handle);
> 
> +void queue_set_pktin(queue_entry_t *queue, odp_pktio_t id);
> +void queue_set_pktout(queue_entry_t *queue, odp_pktio_t id);
> +
>  static inline uint32_t queue_to_id(odp_queue_t handle)
>  {
>         return handle - 1;
> diff --git a/platform/linux-generic/odp_packet_io.c b/platform/linux-
> generic/odp_packet_io.c
> index 0c30f0f..fbf23ff 100644
> --- a/platform/linux-generic/odp_packet_io.c
> +++ b/platform/linux-generic/odp_packet_io.c
> @@ -65,13 +65,13 @@ int odp_pktio_init_global(void)
>                 snprintf(name, sizeof(name), "%i-pktio_outq_default",
> (int)id);
>                 name[ODP_QUEUE_NAME_LEN-1] = '\0';
> 
> -               qid = odp_queue_create(name, ODP_QUEUE_TYPE_PKTOUT, NULL);
> +               qid = odp_queue_create(name, ODP_QUEUE_TYPE_SCHED, NULL);
>                 if (qid == ODP_QUEUE_INVALID)
>                         return -1;
>                 pktio_entry->s.outq_default = qid;
> 
>                 queue_entry = queue_to_qentry(qid);
> -               queue_entry->s.pktout = id;
> +               queue_set_pktout(queue_entry, id);
>         }
> 
>         return 0;
> @@ -325,16 +325,12 @@ int odp_pktio_inq_setdef(odp_pktio_t id, odp_queue_t
> queue)
>         if (pktio_entry == NULL || qentry == NULL)
>                 return -1;
> 
> -       if (qentry->s.type != ODP_QUEUE_TYPE_PKTIN)
> -               return -1;
> -
>         lock_entry(pktio_entry);
>         pktio_entry->s.inq_default = queue;
>         unlock_entry(pktio_entry);
> 
>         queue_lock(qentry);
> -       qentry->s.pktin = id;
> -       qentry->s.status = QUEUE_STATUS_SCHED;
> +       queue_set_pktin(qentry, id);
>         queue_unlock(qentry);
> 
>         odp_schedule_queue(queue, qentry->s.param.sched.prio);
> diff --git a/platform/linux-generic/odp_queue.c b/platform/linux-
> generic/odp_queue.c
> index 1318bcd..1f0e33a 100644
> --- a/platform/linux-generic/odp_queue.c
> +++ b/platform/linux-generic/odp_queue.c
> @@ -53,6 +53,8 @@ static void queue_init(queue_entry_t *queue, const char
> *name,
>  {
>         strncpy(queue->s.name, name, ODP_QUEUE_NAME_LEN - 1);
>         queue->s.type = type;
> +       queue->s.pktin  = ODP_PKTIO_INVALID;
> +       queue->s.pktout = ODP_PKTIO_INVALID;
> 
>         if (param) {
>                 memcpy(&queue->s.param, param, sizeof(odp_queue_param_t));
> @@ -64,27 +66,10 @@ static void queue_init(queue_entry_t *queue, const
> char *name,
>                 queue->s.param.sched.group = ODP_SCHED_GROUP_DEFAULT;
>         }
> 
> -       switch (type) {
> -       case ODP_QUEUE_TYPE_PKTIN:
> -               queue->s.enqueue = pktin_enqueue;
> -               queue->s.dequeue = pktin_dequeue;
> -               queue->s.enqueue_multi = pktin_enq_multi;
> -               queue->s.dequeue_multi = pktin_deq_multi;
> -               break;
> -       case ODP_QUEUE_TYPE_PKTOUT:
> -               queue->s.enqueue = pktout_enqueue;
> -               queue->s.dequeue = pktout_dequeue;
> -               queue->s.enqueue_multi = pktout_enq_multi;
> -               queue->s.dequeue_multi = pktout_deq_multi;
> -               break;
> -       default:
> -               queue->s.enqueue = queue_enq;
> -               queue->s.dequeue = queue_deq;
> -               queue->s.enqueue_multi = queue_enq_multi;
> -               queue->s.dequeue_multi = queue_deq_multi;
> -               break;
> -       }
> -
> +       queue->s.enqueue = queue_enq;
> +       queue->s.dequeue = queue_deq;
> +       queue->s.enqueue_multi = queue_enq_multi;
> +       queue->s.dequeue_multi = queue_deq_multi;
>         queue->s.head = NULL;
>         queue->s.tail = NULL;
>         queue->s.sched_buf = ODP_BUFFER_INVALID;
> @@ -162,8 +147,7 @@ odp_queue_t odp_queue_create(const char *name,
> odp_queue_type_t type,
>                 if (queue->s.status == QUEUE_STATUS_FREE) {
>                         queue_init(queue, name, type, param);
> 
> -                       if (type == ODP_QUEUE_TYPE_SCHED ||
> -                           type == ODP_QUEUE_TYPE_PKTIN)
> +                       if (type == ODP_QUEUE_TYPE_SCHED)
>                                 queue->s.status = QUEUE_STATUS_NOTSCHED;
>                         else
>                                 queue->s.status = QUEUE_STATUS_READY;
> @@ -175,8 +159,7 @@ odp_queue_t odp_queue_create(const char *name,
> odp_queue_type_t type,
>                 UNLOCK(&queue->s.lock);
>         }
> 
> -       if (handle != ODP_QUEUE_INVALID &&
> -           (type == ODP_QUEUE_TYPE_SCHED || type ==
> ODP_QUEUE_TYPE_PKTIN)) {
> +       if (handle != ODP_QUEUE_INVALID && type == ODP_QUEUE_TYPE_SCHED) {
>                 odp_buffer_t buf;
> 
>                 buf = odp_schedule_buffer_alloc(handle);
> @@ -353,8 +337,7 @@ odp_buffer_hdr_t *queue_deq(queue_entry_t *queue)
> 
>         if (queue->s.head == NULL) {
>                 /* Already empty queue */
> -               if (queue->s.status == QUEUE_STATUS_SCHED &&
> -                   queue->s.type != ODP_QUEUE_TYPE_PKTIN)
> +               if (queue->s.status == QUEUE_STATUS_SCHED)
>                         queue->s.status = QUEUE_STATUS_NOTSCHED;
>         } else {
>                 buf_hdr       = queue->s.head;
> @@ -381,8 +364,7 @@ int queue_deq_multi(queue_entry_t *queue,
> odp_buffer_hdr_t *buf_hdr[], int num)
> 
>         if (queue->s.head == NULL) {
>                 /* Already empty queue */
> -               if (queue->s.status == QUEUE_STATUS_SCHED &&
> -                   queue->s.type != ODP_QUEUE_TYPE_PKTIN)
> +               if (queue->s.status == QUEUE_STATUS_SCHED)
>                         queue->s.status = QUEUE_STATUS_NOTSCHED;
>         } else {
>                 odp_buffer_hdr_t *hdr = queue->s.head;
> @@ -453,3 +435,24 @@ void queue_unlock(queue_entry_t *queue)
>  {
>         UNLOCK(&queue->s.lock);
>  }
> +
> +void queue_set_pktin(queue_entry_t *queue, odp_pktio_t pktio_id)
> +{
> +       queue->s.pktin = pktio_id;
> +       queue->s.enqueue = pktin_enqueue;
> +       queue->s.dequeue = pktin_dequeue;
> +       queue->s.enqueue_multi = pktin_enq_multi;
> +       queue->s.dequeue_multi = pktin_deq_multi;
> +       if (queue->s.type == ODP_QUEUE_TYPE_SCHED)
> +               queue->s.status = QUEUE_STATUS_SCHED;
> +}
> +
> +void queue_set_pktout(queue_entry_t *queue, odp_pktio_t pktio_id)
> +{
> +       queue->s.pktout = pktio_id;
> +       queue->s.enqueue = pktout_enqueue;
> +       queue->s.dequeue = pktout_dequeue;
> +       queue->s.enqueue_multi = pktout_enq_multi;
> +       queue->s.dequeue_multi = pktout_deq_multi;
> +}
> +
> diff --git a/platform/linux-generic/odp_schedule.c b/platform/linux-
> generic/odp_schedule.c
> index 1bf819b..5742196 100644
> --- a/platform/linux-generic/odp_schedule.c
> +++ b/platform/linux-generic/odp_schedule.c
> @@ -301,8 +301,8 @@ static int schedule(odp_queue_t *out_queue,
> odp_buffer_t out_buf[],
>                                         /* Remove empty queue from
> scheduling,
>                                          * except packet input queues
>                                          */
> -                                       if (odp_queue_type(queue) ==
> -                                           ODP_QUEUE_TYPE_PKTIN)
> +                                       queue_entry_t *qentry =
> queue_to_qentry(queue);
> +                                       if (qentry->s.pktin !=
> ODP_PKTIO_INVALID)
>                                                 odp_queue_enq(pri_q,
> desc_buf);
> 
>                                         continue;
> --
> 1.9.1
> 
> 
> 
> _______________________________________________
> lng-odp mailing list
> lng-odp@lists.linaro.org
> http://lists.linaro.org/mailman/listinfo/lng-odp
> 
> _______________________________________________
> lng-odp mailing list
> lng-odp@lists.linaro.org
> http://lists.linaro.org/mailman/listinfo/lng-odp
Taras Kondratiuk Oct. 13, 2014, 7:56 a.m. UTC | #3
On 10/10/2014 09:28 PM, Rosenboim, Leonid wrote:
> Stuart,
>
> The declaration of a queue as PKTIN, PKTOUT during creation time is NOT an implementation detail, and was in my opinion deliberate and changing this will have serious consequences for our ability to support this API on Octeon SoCs.
>
> Octeon has queues implemented in hardware, and there are two distinct types of queues supported in the hardware of these chips: One type of queue is for scheduling incoming packets, timer events and generic events initiated by an application or packets in transit (SSO). The other type of queues are only used for packet output (PKO). For mapping an ODP queue to one of these, the implementation needs to know the queue's intended use to select and reserve a resource from the correct resource type.
>
> It seems your comprehension of the API is entirely focused on a software based implementation, without considering advanced network processors, and the ability of the ODP API to abstract these hardware mechanisms. The objective of enabling the mapping of network processor packet processing hardware to ODP APIs is an objective clearly set forth in ODP charter, and should not be neglected.

Hi Leo,

This change does not limit use of HW features. At implementation level
you will have all information needed to correctly choose HW queue. The
only difference is that information is passed in two stages now:
  - queue creation
  - queue attach to pktin, pktout, crypto, etc interfaces.

So during queue creation a generic app<->app queue can be created, and
then queue can be modified depending where it is attached to.
While this approach does make implementation a bit more complex, it
removes that complexity and redundancy from application. I like it much
more than adding a bunch of flags/types/actors/etc on a queue creation.

As Petri mentioned in this thread these two steps can be combined in
some API. For example instead of creating and attaching PKTIO queue to
pktio interface explicitly a function odp_pktio_get_out_queue() can
implicitly create a proper queue, attach it to PKTIO and return an
opaque odp_queue_t handle.
Rosenboim, Leonid Oct. 13, 2014, 5:29 p.m. UTC | #4
Taras,

I am not worried too much about implementation at this stage, as I am sure we can figure it out,
but I am more concerned about semantics.

If the request to attach a queue to a certain packet output port is a separate request from queue creation, then the meaning of queue creation becomes empty, and makes the creation function obsolete.

Perhaps we should just elimiate the create function all together, except perhaps for app-to-app queues, and move all queues that are attached to packet I/O ports into the pktio API section. Otherwise, the queue create function, and any SoC implementation thereof becomes an unattractive kludge.

- Leo
Ankit Jindal Oct. 14, 2014, 5:24 a.m. UTC | #5
On 13 October 2014 22:59, Rosenboim, Leonid
<Leonid.Rosenboim@caviumnetworks.com> wrote:
> Taras,
>
> I am not worried too much about implementation at this stage, as I am sure we can figure it out,
> but I am more concerned about semantics.
>
> If the request to attach a queue to a certain packet output port is a separate request from queue creation, > then the meaning of queue creation becomes empty, and makes the creation function obsolete.
No I don't think. queue can be created independent of whether it is
attached or not. One of the use case, during power management,
application need not to delete the queue, rather it just need to
detach the queue from the subsystem, and later on resuming just attach
the same queue to the subsystem to start processing.
Having separate attach/detach and create/delete routine gives
flexibility to the application.

>
> Perhaps we should just elimiate the create function all together, except perhaps for app-to-app queues, and move all queues that are attached to packet I/O ports into the pktio API section. Otherwise, the queue create function, and any SoC implementation thereof becomes an unattractive kludge.
>
> - Leo

Thanks,
Ankit
> ________________________________________
> From: Taras Kondratiuk <taras.kondratiuk@linaro.org>
> Sent: Monday, October 13, 2014 12:56 AM
> To: Rosenboim, Leonid
> Cc: Stuart Haslam; lng-odp@lists.linaro.org; Kapoor, Prasun; Manoharan, Balasubramanian
> Subject: Re: [lng-odp] [RFC PATCH] Remove queue types ODP_QUEUE_TYPE_PKTIN and PKTOUT
>
> On 10/10/2014 09:28 PM, Rosenboim, Leonid wrote:
>> Stuart,
>>
>> The declaration of a queue as PKTIN, PKTOUT during creation time is NOT an implementation detail, and was in my opinion deliberate and changing this will have serious consequences for our ability to support this API on Octeon SoCs.
>>
>> Octeon has queues implemented in hardware, and there are two distinct types of queues supported in the hardware of these chips: One type of queue is for scheduling incoming packets, timer events and generic events initiated by an application or packets in transit (SSO). The other type of queues are only used for packet output (PKO). For mapping an ODP queue to one of these, the implementation needs to know the queue's intended use to select and reserve a resource from the correct resource type.
>>
>> It seems your comprehension of the API is entirely focused on a software based implementation, without considering advanced network processors, and the ability of the ODP API to abstract these hardware mechanisms. The objective of enabling the mapping of network processor packet processing hardware to ODP APIs is an objective clearly set forth in ODP charter, and should not be neglected.
>
> Hi Leo,
>
> This change does not limit use of HW features. At implementation level
> you will have all information needed to correctly choose HW queue. The
> only difference is that information is passed in two stages now:
>   - queue creation
>   - queue attach to pktin, pktout, crypto, etc interfaces.
>
> So during queue creation a generic app<->app queue can be created, and
> then queue can be modified depending where it is attached to.
> While this approach does make implementation a bit more complex, it
> removes that complexity and redundancy from application. I like it much
> more than adding a bunch of flags/types/actors/etc on a queue creation.
>
> As Petri mentioned in this thread these two steps can be combined in
> some API. For example instead of creating and attaching PKTIO queue to
> pktio interface explicitly a function odp_pktio_get_out_queue() can
> implicitly create a proper queue, attach it to PKTIO and return an
> opaque odp_queue_t handle.
>
> _______________________________________________
> lng-odp mailing list
> lng-odp@lists.linaro.org
> http://lists.linaro.org/mailman/listinfo/lng-odp
Taras Kondratiuk Oct. 14, 2014, 8:14 a.m. UTC | #6
On 10/13/2014 08:29 PM, Rosenboim, Leonid wrote:
> Taras,
>
> I am not worried too much about implementation at this stage, as I am sure we can figure it out,
> but I am more concerned about semantics.
>
> If the request to attach a queue to a certain packet output port is a separate request from queue creation, then the meaning of queue creation becomes empty, and makes the creation function obsolete.
>
> Perhaps we should just elimiate the create function all together, except perhaps for app-to-app queues, and move all queues that are attached to packet I/O ports into the pktio API section. Otherwise, the queue create function, and any SoC implementation thereof becomes an unattractive kludge.

That's also possible, but for now create/attach semantics looks quite
straightforward. Otherwise we have to duplicate API for app-to-app,
pktio, crypto, IPC... queues.
Gilad Ben-Yossef Oct. 14, 2014, 11:02 a.m. UTC | #7
I don't get it.
Leo's says Octeon does allocation of input/output queues differently - SSO vs. PKO
NPS does allocation input/output queues differently - PMU queues vs. TM queues.
Tilera does input/output queues differently - mpipe iqueue/eqeueue
DPDK does input/output queues differently - both are only created when an rte_eth device is setup.
From a peek in the ODP Keystone2 platform, it does allocation of input/output queues differently - input queue allocated when created and single output queue allocated on pktio open
Every HW based ODP platform has an issue doing this and the only upside I see is saving the application programmer from passing a flag at queue creation - how is this a win?
Also, scheduling input queues and scheduling output queues is two completely separate and even unrelated things.
Gilad


Gilad Ben-Yossef
Software Architect
EZchip Technologies Ltd.
37 Israel Pollak Ave, Kiryat Gat 82025 ,Israel
Tel: +972-4-959-6666 ext. 576, Fax: +972-8-681-1483 
Mobile: +972-52-826-0388, US Mobile: +1-973-826-0388
Email: giladb@ezchip.com, Web: http://www.ezchip.com

"Ethernet always wins."
        — Andy Bechtolsheim


> -----Original Message-----

> From: lng-odp-bounces@lists.linaro.org [mailto:lng-odp-

> bounces@lists.linaro.org] On Behalf Of Taras Kondratiuk

> Sent: Tuesday, October 14, 2014 11:14 AM

> To: Rosenboim, Leonid

> Cc: Kapoor, Prasun; Manoharan, Balasubramanian; lng-odp@lists.linaro.org

> Subject: Re: [lng-odp] [RFC PATCH] Remove queue types

> ODP_QUEUE_TYPE_PKTIN and PKTOUT

> 

> On 10/13/2014 08:29 PM, Rosenboim, Leonid wrote:

> > Taras,

> >

> > I am not worried too much about implementation at this stage, as I am

> sure we can figure it out,

> > but I am more concerned about semantics.

> >

> > If the request to attach a queue to a certain packet output port is a

> separate request from queue creation, then the meaning of queue creation

> becomes empty, and makes the creation function obsolete.

> >

> > Perhaps we should just elimiate the create function all together,

> except perhaps for app-to-app queues, and move all queues that are

> attached to packet I/O ports into the pktio API section. Otherwise, the

> queue create function, and any SoC implementation thereof becomes an

> unattractive kludge.

> 

> That's also possible, but for now create/attach semantics looks quite

> straightforward. Otherwise we have to duplicate API for app-to-app,

> pktio, crypto, IPC... queues.

> 

> _______________________________________________

> lng-odp mailing list

> lng-odp@lists.linaro.org

> http://lists.linaro.org/mailman/listinfo/lng-odp
diff mbox

Patch

diff --git a/example/generator/odp_generator.c b/example/generator/odp_generator.c
index 6055324..d566a19 100644
--- a/example/generator/odp_generator.c
+++ b/example/generator/odp_generator.c
@@ -473,7 +473,7 @@  static void *gen_recv_thread(void *arg)
        qparam.sched.group = ODP_SCHED_GROUP_DEFAULT;
        snprintf(inq_name, sizeof(inq_name), "%i-pktio_inq_def", (int)pktio);
        inq_name[ODP_QUEUE_NAME_LEN - 1] = '\0';
-       inq_def = odp_queue_create(inq_name, ODP_QUEUE_TYPE_PKTIN, &qparam);
+       inq_def = odp_queue_create(inq_name, ODP_QUEUE_TYPE_SCHED, &qparam);
        if (inq_def == ODP_QUEUE_INVALID) {
                ODP_ERR("  [%02i] Error: pktio queue creation failed\n", thr);
                return NULL;
diff --git a/example/ipsec/odp_ipsec.c b/example/ipsec/odp_ipsec.c
index ec6c87a..ba90242 100644
--- a/example/ipsec/odp_ipsec.c
+++ b/example/ipsec/odp_ipsec.c
@@ -291,7 +291,7 @@  odp_queue_t polled_odp_queue_create(const char *name,

        my_queue = odp_queue_create(name, my_type, param);

-       if ((ODP_QUEUE_TYPE_SCHED == type) || (ODP_QUEUE_TYPE_PKTIN == type)) {
+       if (ODP_QUEUE_TYPE_SCHED == type) {
                poll_queues[num_polled_queues++] = my_queue;
                printf("%s: adding %d\n", __func__, my_queue);
        }
@@ -572,7 +572,7 @@  void initialize_intf(char *intf)
        snprintf(inq_name, sizeof(inq_name), "%i-pktio_inq_def", (int)pktio);
        inq_name[ODP_QUEUE_NAME_LEN - 1] = '\0';

-       inq_def = QUEUE_CREATE(inq_name, ODP_QUEUE_TYPE_PKTIN, &qparam);
+       inq_def = QUEUE_CREATE(inq_name, ODP_QUEUE_TYPE_SCHED, &qparam);
        if (ODP_QUEUE_INVALID == inq_def) {
                ODP_ERR("Error: pktio queue creation failed for %s\n", intf);
                exit(EXIT_FAILURE);
diff --git a/example/l2fwd/odp_l2fwd.c b/example/l2fwd/odp_l2fwd.c
index 8aa0ba0..4f08dd2 100644
--- a/example/l2fwd/odp_l2fwd.c
+++ b/example/l2fwd/odp_l2fwd.c
@@ -165,7 +165,7 @@  static odp_pktio_t queue_mode_init_params(void *arg, odp_buffer_pool_t pool)
        snprintf(inq_name, sizeof(inq_name), "%i-pktio_inq_def", (int)pktio);
        inq_name[ODP_QUEUE_NAME_LEN - 1] = '\0';

-       inq_def = odp_queue_create(inq_name, ODP_QUEUE_TYPE_PKTIN, &qparam);
+       inq_def = odp_queue_create(inq_name, ODP_QUEUE_TYPE_SCHED, &qparam);
        if (inq_def == ODP_QUEUE_INVALID) {
                ODP_ERR("  Error: pktio queue creation failed");
                return ODP_PKTIO_INVALID;
diff --git a/example/packet/odp_pktio.c b/example/packet/odp_pktio.c
index 145ae47..afb2cd2 100644
--- a/example/packet/odp_pktio.c
+++ b/example/packet/odp_pktio.c
@@ -151,7 +151,7 @@  static void *pktio_queue_thread(void *arg)
        snprintf(inq_name, sizeof(inq_name), "%i-pktio_inq_def", (int)pktio);
        inq_name[ODP_QUEUE_NAME_LEN - 1] = '\0';

-       inq_def = odp_queue_create(inq_name, ODP_QUEUE_TYPE_PKTIN, &qparam);
+       inq_def = odp_queue_create(inq_name, ODP_QUEUE_TYPE_SCHED, &qparam);
        if (inq_def == ODP_QUEUE_INVALID) {
                ODP_ERR("  [%02i] Error: pktio queue creation failed\n", thr);
                return NULL;
diff --git a/platform/linux-generic/include/api/odp_queue.h b/platform/linux-generic/include/api/odp_queue.h
index 5e083f1..38ff272 100644
--- a/platform/linux-generic/include/api/odp_queue.h
+++ b/platform/linux-generic/include/api/odp_queue.h
@@ -42,8 +42,6 @@  typedef int odp_queue_type_t;

 #define ODP_QUEUE_TYPE_SCHED  0  /**< Scheduled queue */
 #define ODP_QUEUE_TYPE_POLL   1  /**< Not scheduled queue */
-#define ODP_QUEUE_TYPE_PKTIN  2  /**< Packet input queue */
-#define ODP_QUEUE_TYPE_PKTOUT 3  /**< Packet output queue */

 /**
  * ODP schedule priority
diff --git a/platform/linux-generic/include/odp_queue_internal.h b/platform/linux-generic/include/odp_queue_internal.h
index 8b6c517..5329d4f 100644
--- a/platform/linux-generic/include/odp_queue_internal.h
+++ b/platform/linux-generic/include/odp_queue_internal.h
@@ -95,6 +95,9 @@  void queue_unlock(queue_entry_t *queue);
 odp_buffer_t queue_sched_buf(odp_queue_t queue);
 int queue_sched_atomic(odp_queue_t handle);

+void queue_set_pktin(queue_entry_t *queue, odp_pktio_t id);
+void queue_set_pktout(queue_entry_t *queue, odp_pktio_t id);
+
 static inline uint32_t queue_to_id(odp_queue_t handle)
 {
        return handle - 1;
diff --git a/platform/linux-generic/odp_packet_io.c b/platform/linux-generic/odp_packet_io.c
index 0c30f0f..fbf23ff 100644
--- a/platform/linux-generic/odp_packet_io.c
+++ b/platform/linux-generic/odp_packet_io.c
@@ -65,13 +65,13 @@  int odp_pktio_init_global(void)
                snprintf(name, sizeof(name), "%i-pktio_outq_default", (int)id);
                name[ODP_QUEUE_NAME_LEN-1] = '\0';

-               qid = odp_queue_create(name, ODP_QUEUE_TYPE_PKTOUT, NULL);
+               qid = odp_queue_create(name, ODP_QUEUE_TYPE_SCHED, NULL);
                if (qid == ODP_QUEUE_INVALID)
                        return -1;
                pktio_entry->s.outq_default = qid;

                queue_entry = queue_to_qentry(qid);
-               queue_entry->s.pktout = id;
+               queue_set_pktout(queue_entry, id);
        }

        return 0;
@@ -325,16 +325,12 @@  int odp_pktio_inq_setdef(odp_pktio_t id, odp_queue_t queue)
        if (pktio_entry == NULL || qentry == NULL)
                return -1;

-       if (qentry->s.type != ODP_QUEUE_TYPE_PKTIN)
-               return -1;
-
        lock_entry(pktio_entry);
        pktio_entry->s.inq_default = queue;
        unlock_entry(pktio_entry);

        queue_lock(qentry);
-       qentry->s.pktin = id;
-       qentry->s.status = QUEUE_STATUS_SCHED;
+       queue_set_pktin(qentry, id);
        queue_unlock(qentry);

        odp_schedule_queue(queue, qentry->s.param.sched.prio);
diff --git a/platform/linux-generic/odp_queue.c b/platform/linux-generic/odp_queue.c
index 1318bcd..1f0e33a 100644
--- a/platform/linux-generic/odp_queue.c
+++ b/platform/linux-generic/odp_queue.c
@@ -53,6 +53,8 @@  static void queue_init(queue_entry_t *queue, const char *name,
 {
        strncpy(queue->s.name, name, ODP_QUEUE_NAME_LEN - 1);
        queue->s.type = type;
+       queue->s.pktin  = ODP_PKTIO_INVALID;
+       queue->s.pktout = ODP_PKTIO_INVALID;

        if (param) {
                memcpy(&queue->s.param, param, sizeof(odp_queue_param_t));
@@ -64,27 +66,10 @@  static void queue_init(queue_entry_t *queue, const char *name,
                queue->s.param.sched.group = ODP_SCHED_GROUP_DEFAULT;
        }

-       switch (type) {
-       case ODP_QUEUE_TYPE_PKTIN:
-               queue->s.enqueue = pktin_enqueue;
-               queue->s.dequeue = pktin_dequeue;
-               queue->s.enqueue_multi = pktin_enq_multi;
-               queue->s.dequeue_multi = pktin_deq_multi;
-               break;
-       case ODP_QUEUE_TYPE_PKTOUT:
-               queue->s.enqueue = pktout_enqueue;
-               queue->s.dequeue = pktout_dequeue;
-               queue->s.enqueue_multi = pktout_enq_multi;
-               queue->s.dequeue_multi = pktout_deq_multi;
-               break;
-       default:
-               queue->s.enqueue = queue_enq;
-               queue->s.dequeue = queue_deq;
-               queue->s.enqueue_multi = queue_enq_multi;
-               queue->s.dequeue_multi = queue_deq_multi;
-               break;
-       }
-
+       queue->s.enqueue = queue_enq;
+       queue->s.dequeue = queue_deq;
+       queue->s.enqueue_multi = queue_enq_multi;
+       queue->s.dequeue_multi = queue_deq_multi;
        queue->s.head = NULL;
        queue->s.tail = NULL;
        queue->s.sched_buf = ODP_BUFFER_INVALID;
@@ -162,8 +147,7 @@  odp_queue_t odp_queue_create(const char *name, odp_queue_type_t type,
                if (queue->s.status == QUEUE_STATUS_FREE) {
                        queue_init(queue, name, type, param);

-                       if (type == ODP_QUEUE_TYPE_SCHED ||
-                           type == ODP_QUEUE_TYPE_PKTIN)
+                       if (type == ODP_QUEUE_TYPE_SCHED)
                                queue->s.status = QUEUE_STATUS_NOTSCHED;
                        else
                                queue->s.status = QUEUE_STATUS_READY;
@@ -175,8 +159,7 @@  odp_queue_t odp_queue_create(const char *name, odp_queue_type_t type,
                UNLOCK(&queue->s.lock);
        }

-       if (handle != ODP_QUEUE_INVALID &&
-           (type == ODP_QUEUE_TYPE_SCHED || type == ODP_QUEUE_TYPE_PKTIN)) {
+       if (handle != ODP_QUEUE_INVALID && type == ODP_QUEUE_TYPE_SCHED) {
                odp_buffer_t buf;

                buf = odp_schedule_buffer_alloc(handle);
@@ -353,8 +337,7 @@  odp_buffer_hdr_t *queue_deq(queue_entry_t *queue)

        if (queue->s.head == NULL) {
                /* Already empty queue */
-               if (queue->s.status == QUEUE_STATUS_SCHED &&
-                   queue->s.type != ODP_QUEUE_TYPE_PKTIN)
+               if (queue->s.status == QUEUE_STATUS_SCHED)
                        queue->s.status = QUEUE_STATUS_NOTSCHED;
        } else {
                buf_hdr       = queue->s.head;
@@ -381,8 +364,7 @@  int queue_deq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[], int num)

        if (queue->s.head == NULL) {
                /* Already empty queue */
-               if (queue->s.status == QUEUE_STATUS_SCHED &&
-                   queue->s.type != ODP_QUEUE_TYPE_PKTIN)
+               if (queue->s.status == QUEUE_STATUS_SCHED)
                        queue->s.status = QUEUE_STATUS_NOTSCHED;
        } else {
                odp_buffer_hdr_t *hdr = queue->s.head;
@@ -453,3 +435,24 @@  void queue_unlock(queue_entry_t *queue)
 {
        UNLOCK(&queue->s.lock);
 }
+
+void queue_set_pktin(queue_entry_t *queue, odp_pktio_t pktio_id)
+{
+       queue->s.pktin = pktio_id;
+       queue->s.enqueue = pktin_enqueue;
+       queue->s.dequeue = pktin_dequeue;
+       queue->s.enqueue_multi = pktin_enq_multi;
+       queue->s.dequeue_multi = pktin_deq_multi;
+       if (queue->s.type == ODP_QUEUE_TYPE_SCHED)
+               queue->s.status = QUEUE_STATUS_SCHED;
+}
+
+void queue_set_pktout(queue_entry_t *queue, odp_pktio_t pktio_id)
+{
+       queue->s.pktout = pktio_id;
+       queue->s.enqueue = pktout_enqueue;
+       queue->s.dequeue = pktout_dequeue;
+       queue->s.enqueue_multi = pktout_enq_multi;
+       queue->s.dequeue_multi = pktout_deq_multi;
+}
+
diff --git a/platform/linux-generic/odp_schedule.c b/platform/linux-generic/odp_schedule.c
index 1bf819b..5742196 100644
--- a/platform/linux-generic/odp_schedule.c
+++ b/platform/linux-generic/odp_schedule.c
@@ -301,8 +301,8 @@  static int schedule(odp_queue_t *out_queue, odp_buffer_t out_buf[],
                                        /* Remove empty queue from scheduling,
                                         * except packet input queues
                                         */
-                                       if (odp_queue_type(queue) ==
-                                           ODP_QUEUE_TYPE_PKTIN)
+                                       queue_entry_t *qentry = queue_to_qentry(queue);
+                                       if (qentry->s.pktin != ODP_PKTIO_INVALID)
                                                odp_queue_enq(pri_q, desc_buf);

                                        continue;