diff mbox

[RFC] Remove queue types ODP_QUEUE_TYPE_PKTIN and PKTOUT

Message ID 1412886823-18347-1-git-send-email-stuart.haslam@arm.com
State New
Headers show

Commit Message

Stuart Haslam Oct. 9, 2014, 8:33 p.m. UTC
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(-)

Comments

Savolainen, Petri (NSN - FI/Espoo) Oct. 10, 2014, 9:50 a.m. UTC | #1
This is needed. Look's about right with a quick look. Packet input is polled as part of scheduling, so you have to keep it scheduled also when it's empty. 


> -----Original Message-----
> From: lng-odp-bounces@lists.linaro.org [mailto:lng-odp-
> bounces@lists.linaro.org] On Behalf Of ext Stuart Haslam
> Sent: Thursday, October 09, 2014 11:34 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;

Should we still do check for input queues and keep scheduling those?


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

Same thing.

-Petri
Maxim Uvarov Oct. 10, 2014, 10:03 a.m. UTC | #2
On 10/10/2014 01:50 PM, Savolainen, Petri (NSN - FI/Espoo) wrote:
> +++ 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
A little bit down there is ifdef 1, can you please remove it once you 
started to fix that?

#if 1
         /* Use schedule to get buf from any input queue */
         buf = odp_schedule(NULL, ODP_SCHED_WAIT);
#else
         /* Always dequeue from the same input queue */
         buf = odp_queue_deq(inq_def);
         if (!odp_buffer_is_valid(buf))
             continue;
#endif

Maxim.
Stuart Haslam Oct. 10, 2014, 11:34 a.m. UTC | #3
On Fri, Oct 10, 2014 at 10:50:46AM +0100, Savolainen, Petri (NSN - FI/Espoo) wrote:

> > @@ -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;
> 
> Should we still do check for input queues and keep scheduling those?
> 

I've just had a good look at that and I think the answer is no, actually
it looks like it wasn't needed previously either. When a queue is set as
a pktin queue it's scheduled via odp_schedule_queue(), and in schedule()
there's a hook so that pktin queues never get removed from the schedule
queue.

I did find a problem with using ODP_QUEUE_TYPE_POLL for pktin though so
I'm sorting that out.
Savolainen, Petri (NSN - FI/Espoo) Oct. 10, 2014, 11:54 a.m. UTC | #4
> -----Original Message-----
> From: ext Stuart Haslam [mailto:stuart.haslam@arm.com]
> Sent: Friday, October 10, 2014 2:34 PM
> To: Savolainen, Petri (NSN - FI/Espoo)
> Cc: lng-odp@lists.linaro.org
> Subject: Re: [lng-odp] [RFC PATCH] Remove queue types ODP_QUEUE_TYPE_PKTIN
> and PKTOUT
> 
> On Fri, Oct 10, 2014 at 10:50:46AM +0100, Savolainen, Petri (NSN -
> FI/Espoo) wrote:
> 
> > > @@ -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;
> >
> > Should we still do check for input queues and keep scheduling those?
> >
> 
> I've just had a good look at that and I think the answer is no, actually
> it looks like it wasn't needed previously either. When a queue is set as
> a pktin queue it's scheduled via odp_schedule_queue(), and in schedule()
> there's a hook so that pktin queues never get removed from the schedule
> queue.
> 
> I did find a problem with using ODP_QUEUE_TYPE_POLL for pktin though so
> I'm sorting that out.
> 
> --
> Stuart.

Just a quick look again...

The status is needed here. NOTSCHED means that the queue needs to be added into scheduling (when doing the first enqueue into an empty queue). Now, when an input queue is never removed (even when it's empty), this would add it second/third/... time there.

	if (queue->s.status == QUEUE_STATUS_NOTSCHED) {
		queue->s.status = QUEUE_STATUS_SCHED;
		sched = 1; /* retval: schedule queue */
	}
	UNLOCK(&queue->s.lock);

	/* Add queue to scheduling */
	if (sched == 1)
		odp_schedule_queue(queue->s.handle, queue->s.param.sched.prio);


- Petri
Stuart Haslam Oct. 10, 2014, 12:29 p.m. UTC | #5
On Fri, Oct 10, 2014 at 12:54:15PM +0100, Savolainen, Petri (NSN - FI/Espoo) wrote:
> 
> 
> > -----Original Message-----
> > From: ext Stuart Haslam [mailto:stuart.haslam@arm.com]
> > Sent: Friday, October 10, 2014 2:34 PM
> > To: Savolainen, Petri (NSN - FI/Espoo)
> > Cc: lng-odp@lists.linaro.org
> > Subject: Re: [lng-odp] [RFC PATCH] Remove queue types ODP_QUEUE_TYPE_PKTIN
> > and PKTOUT
> > 
> > On Fri, Oct 10, 2014 at 10:50:46AM +0100, Savolainen, Petri (NSN -
> > FI/Espoo) wrote:
> > 
> > > > @@ -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;
> > >
> > > Should we still do check for input queues and keep scheduling those?
> > >
> > 
> > I've just had a good look at that and I think the answer is no, actually
> > it looks like it wasn't needed previously either. When a queue is set as
> > a pktin queue it's scheduled via odp_schedule_queue(), and in schedule()
> > there's a hook so that pktin queues never get removed from the schedule
> > queue.
> > 
> > I did find a problem with using ODP_QUEUE_TYPE_POLL for pktin though so
> > I'm sorting that out.
> > 
> > --
> > Stuart.
> 
> Just a quick look again...
> 
> The status is needed here. NOTSCHED means that the queue needs to be added into scheduling (when doing the first enqueue into an empty queue). Now, when an input queue is never removed (even when it's empty), this would add it second/third/... time there.
> 
> 	if (queue->s.status == QUEUE_STATUS_NOTSCHED) {
> 		queue->s.status = QUEUE_STATUS_SCHED;
> 		sched = 1; /* retval: schedule queue */
> 	}
> 	UNLOCK(&queue->s.lock);
> 
> 	/* Add queue to scheduling */
> 	if (sched == 1)
> 		odp_schedule_queue(queue->s.handle, queue->s.param.sched.prio);
> 
> 
> - Petri

Yes you're right, it is needed.
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;