[API-NEXT,v5,1/1] linux-generic: queue: modular queue interface

Message ID 1496462408-20583-2-git-send-email-odpbot@yandex.ru
State New
Headers show
Series
  • Modular queue interface
Related show

Commit Message

Github ODP bot June 3, 2017, 4 a.m.
From: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>


Created abstract queue type. Queue APIs and functions towards the
internal components are converted into function pointers.

Signed-off-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>

---
/** Email created from pull request 43 (nagarahalli:api-next-mod-queue1)
 ** https://github.com/Linaro/odp/pull/43
 ** Patch: https://github.com/Linaro/odp/pull/43.patch
 ** Base sha: 57783b35f4383bdfdd146f2a3333bbc8bb995896
 ** Merge commit sha: 9b21e1979ace878bb44efcfb9b40922b706ea7e8
 **/
 platform/linux-generic/Makefile.am                 |   2 +
 .../include/odp_classification_datamodel.h         |   4 +-
 .../linux-generic/include/odp_packet_io_queue.h    |  20 +-
 platform/linux-generic/include/odp_queue_if.h      | 104 ++++++++
 .../linux-generic/include/odp_queue_internal.h     |  41 +---
 platform/linux-generic/include/odp_schedule_if.h   |   2 +-
 .../include/odp_traffic_mngr_internal.h            |   4 +-
 platform/linux-generic/odp_classification.c        |  10 +-
 platform/linux-generic/odp_init.c                  |  17 +-
 platform/linux-generic/odp_packet_io.c             |  90 ++++---
 platform/linux-generic/odp_queue.c                 | 261 +++++++++++++++------
 platform/linux-generic/odp_queue_if.c              | 103 ++++++++
 platform/linux-generic/odp_schedule.c              |   6 +-
 platform/linux-generic/odp_schedule_iquery.c       |   6 +-
 platform/linux-generic/odp_schedule_sp.c           |   4 +-
 platform/linux-generic/odp_traffic_mngr.c          |  21 +-
 platform/linux-generic/pktio/loop.c                |  13 +-
 17 files changed, 515 insertions(+), 193 deletions(-)
 create mode 100644 platform/linux-generic/include/odp_queue_if.h
 create mode 100644 platform/linux-generic/odp_queue_if.c

Comments

Savolainen, Petri (Nokia - FI/Espoo) June 6, 2017, 10:53 a.m. | #1
Couple of general comments first:

1) Discussion about various versions of this patch has not reached the mailing list. That needs to be fixed in Github configuration...

2) Queue handle/qentry naming should be consistent over the entire patch.

Today:
* "handle" refers to odp_queue_t
* "queue" or "qe" refers to *queue_entry_t when inside of queue.c
* "qentry" or "qe" refers to *queue_entry_t when outside of queue.c

After this patch, the same should apply - especially for "handle". Try to minimize changes inside queue.c. When you add queue_t it should *not* be referred as "handle" (which is odp_queue_t), but something else - maybe consistently "queue_int". Otherwise, it's hard to follow which variable refers to odp_queue_t, queue_t or queue_entry_t.



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

> From: lng-odp [mailto:lng-odp-bounces@lists.linaro.org] On Behalf Of

> Github ODP bot

> Sent: Saturday, June 03, 2017 7:00 AM

> To: lng-odp@lists.linaro.org

> Subject: [lng-odp] [PATCH API-NEXT v5 1/1] linux-generic: queue: modular

> queue interface

> 

> From: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>

> 

> Created abstract queue type. Queue APIs and functions towards the

> internal components are converted into function pointers.

> 

> Signed-off-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>



> diff --git a/platform/linux-generic/odp_queue.c b/platform/linux-

> generic/odp_queue.c

> index dd430cd1..bc73728d 100644

> --- a/platform/linux-generic/odp_queue.c

> +++ b/platform/linux-generic/odp_queue.c

> @@ -6,6 +6,7 @@

> 

>  #include <odp/api/queue.h>

>  #include <odp_queue_internal.h>

> +#include <odp_queue_if.h>

>  #include <odp/api/std_types.h>

>  #include <odp/api/align.h>

>  #include <odp/api/buffer.h>

> @@ -40,6 +41,14 @@ typedef struct queue_table_t {

> 

>  static queue_table_t *queue_tbl;

> 

> +static int _queue_enq(queue_t handle, odp_buffer_hdr_t *buf_hdr);

> +static odp_buffer_hdr_t *_queue_deq(queue_t handle);

> +

> +static int _queue_enq_multi(queue_t handle, odp_buffer_hdr_t *buf_hdr[],

> +			    int num);

> +static int _queue_deq_multi(queue_t handle, odp_buffer_hdr_t *buf_hdr[],

> +			    int num);

> +

>  static inline odp_queue_t queue_from_id(uint32_t queue_id)

>  {

>  	return _odp_cast_scalar(odp_queue_t, queue_id + 1);

> @@ -89,10 +98,10 @@ static int queue_init(queue_entry_t *queue, const char

> *name,

>  	}

>  	queue->s.type = queue->s.param.type;

> 

> -	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.enqueue = _queue_enq;

> +	queue->s.dequeue = _queue_deq;

> +	queue->s.enqueue_multi = _queue_enq_multi;

> +	queue->s.dequeue_multi = _queue_deq_multi;


No need to rename these. Static functions do not need prefix (not even '_').



> 

> -odp_queue_type_t odp_queue_type(odp_queue_t handle)

> +static odp_queue_type_t queue_type(odp_queue_t handle)

>  {

> -	queue_entry_t *queue;

> -

> -	queue = queue_to_qentry(handle);

> -

> -	return queue->s.type;

> +	return qentry_from_int(queue_fn->from_ext(handle))->s.type;

>  }


No need to use queue interface inside queue.c. It causes unnecessary indirection, which is harmful for both performance and code readability. Use a direct, inlined call instead. I'd prefer to keep it queue_to_qentry(). There should not be  real reason to change, since this is internal queue.c. Keeping it the same would limit the change to minimum set that it needed for the new interface.



> 

> -odp_schedule_sync_t odp_queue_sched_type(odp_queue_t handle)

> +static odp_schedule_sync_t queue_sched_type(odp_queue_t handle)

>  {

> -	queue_entry_t *queue;

> -

> -	queue = queue_to_qentry(handle);

> -

> -	return queue->s.param.sched.sync;

> +	return qentry_from_int(queue_fn->from_ext(handle))-

> >s.param.sched.sync;

>  }


No need to use queue interface. Do not change implementation if not really needed.


> 

> -odp_schedule_prio_t odp_queue_sched_prio(odp_queue_t handle)

> +static odp_schedule_prio_t queue_sched_prio(odp_queue_t handle)

>  {

> -	queue_entry_t *queue;

> -

> -	queue = queue_to_qentry(handle);

> -

> -	return queue->s.param.sched.prio;

> +	return qentry_from_int(queue_fn->from_ext(handle))-

> >s.param.sched.prio;

>  }


No need to use queue interface.

> 

> -odp_schedule_group_t odp_queue_sched_group(odp_queue_t handle)

> +static odp_schedule_group_t queue_sched_group(odp_queue_t handle)

>  {

> -	queue_entry_t *queue;

> -

> -	queue = queue_to_qentry(handle);

> -

> -	return queue->s.param.sched.group;

> +	return qentry_from_int(queue_fn->from_ext(handle))

> +			       ->s.param.sched.group;

>  }


No need to use queue interface.

> 

> -int odp_queue_lock_count(odp_queue_t handle)

> +static int queue_lock_count(odp_queue_t handle)

>  {

> -	queue_entry_t *queue = queue_to_qentry(handle);

> +	queue_entry_t *queue = qentry_from_int(queue_fn-

> >from_ext(handle));

> 

>  	return queue->s.param.sched.sync == ODP_SCHED_SYNC_ORDERED ?

>  		(int)queue->s.param.sched.lock_count : -1;

>  }


No need to use queue interface.

> 

> -odp_queue_t odp_queue_create(const char *name, const odp_queue_param_t

> *param)

> +static odp_queue_t queue_create(const char *name,

> +				const odp_queue_param_t *param)

>  {

>  	uint32_t i;

>  	queue_entry_t *queue;

> @@ -291,10 +296,10 @@ void sched_cb_queue_destroy_finalize(uint32_t

> queue_index)

>  	UNLOCK(&queue->s.lock);

>  }

> 

> -int odp_queue_destroy(odp_queue_t handle)

> +static int queue_destroy(odp_queue_t handle)

>  {

>  	queue_entry_t *queue;

> -	queue = queue_to_qentry(handle);

> +	queue = qentry_from_int(queue_fn->from_ext(handle));

> 

>  	if (handle == ODP_QUEUE_INVALID)

>  		return -1;

> @@ -343,25 +348,21 @@ int odp_queue_destroy(odp_queue_t handle)

>  	return 0;

>  }


No need to use queue interface.

> 

> -int odp_queue_context_set(odp_queue_t handle, void *context,

> -			  uint32_t len ODP_UNUSED)

> +static int queue_context_set(odp_queue_t handle, void *context,

> +			     uint32_t len ODP_UNUSED)

>  {

> -	queue_entry_t *queue;

> -	queue = queue_to_qentry(handle);

>  	odp_mb_full();

> -	queue->s.param.context = context;

> +	qentry_from_int(queue_fn->from_ext(handle))->s.param.context =

> context;

>  	odp_mb_full();

>  	return 0;

>  }


No need to use queue interface.

> 

> -void *odp_queue_context(odp_queue_t handle)

> +static void *queue_context(odp_queue_t handle)

>  {

> -	queue_entry_t *queue;

> -	queue = queue_to_qentry(handle);

> -	return queue->s.param.context;

> +	return qentry_from_int(queue_fn->from_ext(handle))-

> >s.param.context;

>  }


No need to use queue interface.

> 

> -odp_queue_t odp_queue_lookup(const char *name)

> +static odp_queue_t queue_lookup(const char *name)

>  {

>  	uint32_t i;

> 

> @@ -384,15 +385,16 @@ odp_queue_t odp_queue_lookup(const char *name)

>  	return ODP_QUEUE_INVALID;

>  }

> 

> -static inline int enq_multi(queue_entry_t *queue, odp_buffer_hdr_t

> *buf_hdr[],

> +static inline int enq_multi(queue_t handle, odp_buffer_hdr_t *buf_hdr[],

>  			    int num)

>  {

>  	int sched = 0;

>  	int i, ret;

> +	queue_entry_t *queue;

>  	odp_buffer_hdr_t *hdr, *tail, *next_hdr;

> 

> -	if (sched_fn->ord_enq_multi(queue->s.index, (void **)buf_hdr,

> num,

> -			&ret))

> +	queue = qentry_from_int(handle);

> +	if (sched_fn->ord_enq_multi(handle, (void **)buf_hdr, num,

> &ret))

>  		return ret;

> 

>  	/* Optimize the common case of single enqueue */

> @@ -460,16 +462,17 @@ static inline int enq_multi(queue_entry_t *queue,

> odp_buffer_hdr_t *buf_hdr[],

>  	return num; /* All events enqueued */

>  }

> 

> -int queue_enq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[],

> int num)

> +static int _queue_enq_multi(queue_t handle, odp_buffer_hdr_t *buf_hdr[],

> +			    int num)

>  {

> -	return enq_multi(queue, buf_hdr, num);

> +	return enq_multi(handle, buf_hdr, num);

>  }

> 

> -int queue_enq(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr)

> +static int _queue_enq(queue_t handle, odp_buffer_hdr_t *buf_hdr)

>  {

>  	int ret;

> 

> -	ret = enq_multi(queue, &buf_hdr, 1);

> +	ret = enq_multi(handle, &buf_hdr, 1);

> 

>  	if (ret == 1)

>  		return 0;

> @@ -477,7 +480,7 @@ int queue_enq(queue_entry_t *queue, odp_buffer_hdr_t

> *buf_hdr)

>  		return -1;

>  }

> 

> -int odp_queue_enq_multi(odp_queue_t handle, const odp_event_t ev[], int

> num)

> +static int queue_enq_multi(odp_queue_t handle, const odp_event_t ev[],

> int num)

>  {

>  	odp_buffer_hdr_t *buf_hdr[QUEUE_MULTI_MAX];

>  	queue_entry_t *queue;

> @@ -486,33 +489,35 @@ int odp_queue_enq_multi(odp_queue_t handle, const

> odp_event_t ev[], int num)

>  	if (num > QUEUE_MULTI_MAX)

>  		num = QUEUE_MULTI_MAX;

> 

> -	queue = queue_to_qentry(handle);

> +	queue = qentry_from_int(queue_fn->from_ext(handle));


No need to use queue interface.

> 

>  	for (i = 0; i < num; i++)

>  		buf_hdr[i] =

> buf_hdl_to_hdr(odp_buffer_from_event(ev[i]));

> 

> -	return num == 0 ? 0 : queue->s.enqueue_multi(queue, buf_hdr,

> -

> num);

> +	return num == 0 ? 0 : queue-

> >s.enqueue_multi(qentry_to_int(queue),

> +

> buf_hdr, num);

>  }

> 

> -int odp_queue_enq(odp_queue_t handle, odp_event_t ev)

> +static int queue_enq(odp_queue_t handle, odp_event_t ev)

>  {

>  	odp_buffer_hdr_t *buf_hdr;

>  	queue_entry_t *queue;

> 

> -	queue   = queue_to_qentry(handle);

> +	queue   = qentry_from_int(queue_fn->from_ext(handle));


No need to use queue interface.

>  	buf_hdr = buf_hdl_to_hdr(odp_buffer_from_event(ev));

> 

> -	return queue->s.enqueue(queue, buf_hdr);

> +	return queue->s.enqueue(qentry_to_int(queue), buf_hdr);

>  }

> 

> -static inline int deq_multi(queue_entry_t *queue, odp_buffer_hdr_t

> *buf_hdr[],

> +static inline int deq_multi(queue_t handle, odp_buffer_hdr_t *buf_hdr[],

>  			    int num)

>  {

>  	odp_buffer_hdr_t *hdr, *next;

>  	int i, j;

> +	queue_entry_t *queue;

>  	int updated = 0;

> 

> +	queue = qentry_from_int(handle);

>  	LOCK(&queue->s.lock);

>  	if (odp_unlikely(queue->s.status < QUEUE_STATUS_READY)) {

>  		/* Bad queue, or queue has been destroyed.

> @@ -578,17 +583,18 @@ static inline int deq_multi(queue_entry_t *queue,

> odp_buffer_hdr_t *buf_hdr[],

>  	return i;

>  }

> 

> -int queue_deq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[],

> int num)

> +static int _queue_deq_multi(queue_t handle, odp_buffer_hdr_t *buf_hdr[],

> +			    int num)

>  {

> -	return deq_multi(queue, buf_hdr, num);

> +	return deq_multi(handle, buf_hdr, num);

>  }

> 

> -odp_buffer_hdr_t *queue_deq(queue_entry_t *queue)

> +static odp_buffer_hdr_t *_queue_deq(queue_t handle)

>  {

>  	odp_buffer_hdr_t *buf_hdr = NULL;

>  	int ret;

> 

> -	ret = deq_multi(queue, &buf_hdr, 1);

> +	ret = deq_multi(handle, &buf_hdr, 1);

> 

>  	if (ret == 1)

>  		return buf_hdr;

> @@ -596,7 +602,7 @@ odp_buffer_hdr_t *queue_deq(queue_entry_t *queue)

>  		return NULL;

>  }

> 

> -int odp_queue_deq_multi(odp_queue_t handle, odp_event_t events[], int

> num)

> +static int queue_deq_multi(odp_queue_t handle, odp_event_t events[], int

> num)

>  {

>  	queue_entry_t *queue;

>  	odp_buffer_hdr_t *buf_hdr[QUEUE_MULTI_MAX];

> @@ -605,9 +611,9 @@ int odp_queue_deq_multi(odp_queue_t handle,

> odp_event_t events[], int num)

>  	if (num > QUEUE_MULTI_MAX)

>  		num = QUEUE_MULTI_MAX;

> 

> -	queue = queue_to_qentry(handle);

> +	queue = qentry_from_int(queue_fn->from_ext(handle));


No need to use queue interface.

> 

> -	ret = queue->s.dequeue_multi(queue, buf_hdr, num);

> +	ret = queue->s.dequeue_multi(qentry_to_int(queue), buf_hdr,

> num);

> 

>  	for (i = 0; i < ret; i++)

>  		events[i] = odp_buffer_to_event(buf_hdr[i]-

> >handle.handle);

> @@ -616,13 +622,13 @@ int odp_queue_deq_multi(odp_queue_t handle,

> odp_event_t events[], int num)

>  }

> 

> 

> -odp_event_t odp_queue_deq(odp_queue_t handle)

> +static odp_event_t queue_deq(odp_queue_t handle)

>  {

>  	queue_entry_t *queue;

>  	odp_buffer_hdr_t *buf_hdr;

> 

> -	queue   = queue_to_qentry(handle);

> -	buf_hdr = queue->s.dequeue(queue);

> +	queue   = qentry_from_int(queue_fn->from_ext(handle));


No need to use queue interface.

> +	buf_hdr = queue->s.dequeue(qentry_to_int(queue));

> 

>  	if (buf_hdr)

>  		return odp_buffer_to_event(buf_hdr->handle.handle);

> @@ -640,7 +646,7 @@ void queue_unlock(queue_entry_t *queue)

>  	UNLOCK(&queue->s.lock);

>  }

> 

> -void odp_queue_param_init(odp_queue_param_t *params)

> +static void queue_param_init(odp_queue_param_t *params)

>  {

>  	memset(params, 0, sizeof(odp_queue_param_t));

>  	params->type = ODP_QUEUE_TYPE_PLAIN;

> @@ -651,7 +657,7 @@ void odp_queue_param_init(odp_queue_param_t *params)

>  	params->sched.group = ODP_SCHED_GROUP_ALL;

>  }

> 

> -int odp_queue_info(odp_queue_t handle, odp_queue_info_t *info)

> +static int queue_info(odp_queue_t handle, odp_queue_info_t *info)

>  {

>  	uint32_t queue_id;

>  	queue_entry_t *queue;

> @@ -730,7 +736,7 @@ int sched_cb_queue_deq_multi(uint32_t queue_index,

> odp_event_t ev[], int num)

>  	queue_entry_t *qe = get_qentry(queue_index);

>  	odp_buffer_hdr_t *buf_hdr[num];

> 

> -	ret = deq_multi(qe, buf_hdr, num);

> +	ret = deq_multi(qentry_to_int(qe), buf_hdr, num);

> 

>  	if (ret > 0)

>  		for (i = 0; i < ret; i++)

> @@ -765,7 +771,112 @@ int sched_cb_queue_empty(uint32_t queue_index)

>  	return ret;

>  }

> 

> -uint64_t odp_queue_to_u64(odp_queue_t hdl)

> +static uint64_t queue_to_u64(odp_queue_t hdl)

>  {

>  	return _odp_pri(hdl);

>  }

> +

> +static odp_pktout_queue_t queue_get_pktout(queue_t handle)

> +{

> +	return qentry_from_int(handle)->s.pktout;

> +}

> +

> +static void queue_set_pktout(queue_t handle, odp_pktio_t pktio, int

> index)

> +{

> +	qentry_from_int(handle)->s.pktout.pktio = pktio;

> +	qentry_from_int(handle)->s.pktout.index = index;

> +}

> +

> +static odp_pktin_queue_t queue_get_pktin(queue_t handle)

> +{

> +	return qentry_from_int(handle)->s.pktin;

> +}

> +

> +static void queue_set_pktin(queue_t handle, odp_pktio_t pktio, int index)

> +{

> +	qentry_from_int(handle)->s.pktin.pktio = pktio;

> +	qentry_from_int(handle)->s.pktin.index = index;

> +}

> +

> +static void queue_set_enq_func(queue_t handle, queue_enq_fn_t func)

> +{

> +	qentry_from_int(handle)->s.enqueue = func;

> +}

> +

> +static void queue_set_enq_multi_func(queue_t handle, queue_enq_multi_fn_t

> func)

> +{

> +	qentry_from_int(handle)->s.enqueue_multi = func;

> +}

> +

> +static void queue_set_deq_func(queue_t handle, queue_deq_fn_t func)

> +{

> +	qentry_from_int(handle)->s.dequeue = func;

> +}

> +

> +static void queue_set_deq_multi_func(queue_t handle, queue_deq_multi_fn_t

> func)

> +{

> +	qentry_from_int(handle)->s.dequeue_multi = func;

> +}

> +

> +static void queue_set_type(queue_t handle, odp_queue_type_t type)

> +{

> +	qentry_from_int(handle)->s.type = type;

> +}

> +

> +static queue_t queue_from_ext(odp_queue_t handle)

> +{

> +	uint32_t queue_id;

> +

> +	queue_id = queue_to_id(handle);

> +	return qentry_to_int(get_qentry(queue_id));

> +}


I'd keep the old queue_to_qentry() as is, and implement this one by using it.


> +

> +static odp_queue_t queue_to_ext(queue_t handle)

> +{

> +	return qentry_from_int(handle)->s.handle;

> +}

> +

> +/* API functions */

> +queue_api_t queue_default_api = {

> +	.queue_create = queue_create,

> +	.queue_destroy = queue_destroy,

> +	.queue_lookup = queue_lookup,

> +	.queue_capability = queue_capability,

> +	.queue_context_set = queue_context_set,

> +	.queue_context = queue_context,

> +	.queue_enq = queue_enq,

> +	.queue_enq_multi = queue_enq_multi,

> +	.queue_deq = queue_deq,

> +	.queue_deq_multi = queue_deq_multi,

> +	.queue_type = queue_type,

> +	.queue_sched_type = queue_sched_type,

> +	.queue_sched_prio = queue_sched_prio,

> +	.queue_sched_group = queue_sched_group,

> +	.queue_lock_count = queue_lock_count,

> +	.queue_to_u64 = queue_to_u64,

> +	.queue_param_init = queue_param_init,

> +	.queue_info = queue_info

> +};

> +

> +/* Functions towards internal components */

> +queue_fn_t queue_default_fn = {

> +	.init_global = queue_init_global,

> +	.term_global = queue_term_global,

> +	.init_local = queue_init_local,

> +	.term_local = queue_term_local,

> +	.from_ext = queue_from_ext,

> +	.to_ext = queue_to_ext,

> +	.enq = _queue_enq,

> +	.enq_multi = _queue_enq_multi,

> +	.deq = _queue_deq,

> +	.deq_multi = _queue_deq_multi,

> +	.get_pktout = queue_get_pktout,

> +	.set_pktout = queue_set_pktout,

> +	.get_pktin = queue_get_pktin,

> +	.set_pktin = queue_set_pktin,

> +	.set_enq_fn = queue_set_enq_func,

> +	.set_enq_multi_fn = queue_set_enq_multi_func,

> +	.set_deq_fn = queue_set_deq_func,

> +	.set_deq_multi_fn = queue_set_deq_multi_func,

> +	.set_type = queue_set_type

> +};

> diff --git a/platform/linux-generic/odp_queue_if.c b/platform/linux-

> generic/odp_queue_if.c

> new file mode 100644

> index 00000000..5a4f7194

> --- /dev/null

> +++ b/platform/linux-generic/odp_queue_if.c

> @@ -0,0 +1,103 @@

> +/* Copyright (c) 2016, ARM Limited



Year 2017



-Petri
Honnappa Nagarahalli June 6, 2017, 7:42 p.m. | #2
On 6 June 2017 at 05:53, Savolainen, Petri (Nokia - FI/Espoo)
<petri.savolainen@nokia.com> wrote:
> Couple of general comments first:

>

> 1) Discussion about various versions of this patch has not reached the mailing list. That needs to be fixed in Github configuration...

>

> 2) Queue handle/qentry naming should be consistent over the entire patch.

>

> Today:

> * "handle" refers to odp_queue_t

> * "queue" or "qe" refers to *queue_entry_t when inside of queue.c

> * "qentry" or "qe" refers to *queue_entry_t when outside of queue.c

>

> After this patch, the same should apply - especially for "handle". Try to minimize changes inside queue.c. When you add queue_t it should *not* be referred as "handle" (which is odp_queue_t), but something else - maybe consistently "queue_int". Otherwise, it's hard to follow which variable refers to odp_queue_t, queue_t or queue_entry_t.

>


The same should not apply because this patch has introduced another
level of abstract data type and the code should reflect that. I do
agree that consistent naming needs to be used. Following is my
proposal:

Looking at "outside of queue.c" (including odp_schedule*.c)
1) structure members of type 'odp_queue_t' and 'queue_t'. Naming is
not consistent. The naming is according to the context/purpose of
those members. I suggest that we do not rename these. Except members
of type 'queue_t' can be suffixed with '_int'.
2) local variables and function arguments of type 'odp_queue_t' and
'queue_t'. These can be named 'queue' and 'queue_int' respectively
There is no point in referring to these as 'handle' or 'handle_int',
these do not convey anything outside queue.* files.

Looking at "inside of queue.c"
1) anything that refers to *queue_entry_t can be called as 'qentry' or 'qe'
2) variables and function arguments of type 'odp_queue_t' and
'queue_t'. These can be named 'handle' and 'handle_int' respectively.

>

>

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

>> From: lng-odp [mailto:lng-odp-bounces@lists.linaro.org] On Behalf Of

>> Github ODP bot

>> Sent: Saturday, June 03, 2017 7:00 AM

>> To: lng-odp@lists.linaro.org

>> Subject: [lng-odp] [PATCH API-NEXT v5 1/1] linux-generic: queue: modular

>> queue interface

>>

>> From: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>

>>

>> Created abstract queue type. Queue APIs and functions towards the

>> internal components are converted into function pointers.

>>

>> Signed-off-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>

>

>

>> diff --git a/platform/linux-generic/odp_queue.c b/platform/linux-

>> generic/odp_queue.c

>> index dd430cd1..bc73728d 100644

>> --- a/platform/linux-generic/odp_queue.c

>> +++ b/platform/linux-generic/odp_queue.c

>> @@ -6,6 +6,7 @@

>>

>>  #include <odp/api/queue.h>

>>  #include <odp_queue_internal.h>

>> +#include <odp_queue_if.h>

>>  #include <odp/api/std_types.h>

>>  #include <odp/api/align.h>

>>  #include <odp/api/buffer.h>

>> @@ -40,6 +41,14 @@ typedef struct queue_table_t {

>>

>>  static queue_table_t *queue_tbl;

>>

>> +static int _queue_enq(queue_t handle, odp_buffer_hdr_t *buf_hdr);

>> +static odp_buffer_hdr_t *_queue_deq(queue_t handle);

>> +

>> +static int _queue_enq_multi(queue_t handle, odp_buffer_hdr_t *buf_hdr[],

>> +                         int num);

>> +static int _queue_deq_multi(queue_t handle, odp_buffer_hdr_t *buf_hdr[],

>> +                         int num);

>> +

>>  static inline odp_queue_t queue_from_id(uint32_t queue_id)

>>  {

>>       return _odp_cast_scalar(odp_queue_t, queue_id + 1);

>> @@ -89,10 +98,10 @@ static int queue_init(queue_entry_t *queue, const char

>> *name,

>>       }

>>       queue->s.type = queue->s.param.type;

>>

>> -     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.enqueue = _queue_enq;

>> +     queue->s.dequeue = _queue_deq;

>> +     queue->s.enqueue_multi = _queue_enq_multi;

>> +     queue->s.dequeue_multi = _queue_deq_multi;

>

> No need to rename these. Static functions do not need prefix (not even '_').

>

>

>

>>

>> -odp_queue_type_t odp_queue_type(odp_queue_t handle)

>> +static odp_queue_type_t queue_type(odp_queue_t handle)

>>  {

>> -     queue_entry_t *queue;

>> -

>> -     queue = queue_to_qentry(handle);

>> -

>> -     return queue->s.type;

>> +     return qentry_from_int(queue_fn->from_ext(handle))->s.type;

>>  }

>

> No need to use queue interface inside queue.c. It causes unnecessary indirection, which is harmful for both performance and code readability. Use a direct, inlined call instead. I'd prefer to keep it queue_to_qentry(). There should not be  real reason to change, since this is internal queue.c. Keeping it the same would limit the change to minimum set that it needed for the new interface.

>

Agree on not using the functions via the queue interface within queue.
'queue_from_ext' and 'qentry_from_int' are needed to be implemented.
'queue_to_qentry' becomes redundant. This code reflects how the
handles gets converted to internal handle nicely.

>

>

>>

>> -odp_schedule_sync_t odp_queue_sched_type(odp_queue_t handle)

>> +static odp_schedule_sync_t queue_sched_type(odp_queue_t handle)

>>  {

>> -     queue_entry_t *queue;

>> -

>> -     queue = queue_to_qentry(handle);

>> -

>> -     return queue->s.param.sched.sync;

>> +     return qentry_from_int(queue_fn->from_ext(handle))-

>> >s.param.sched.sync;

>>  }

>

> No need to use queue interface. Do not change implementation if not really needed.

>

>

>>

>> -odp_schedule_prio_t odp_queue_sched_prio(odp_queue_t handle)

>> +static odp_schedule_prio_t queue_sched_prio(odp_queue_t handle)

>>  {

>> -     queue_entry_t *queue;

>> -

>> -     queue = queue_to_qentry(handle);

>> -

>> -     return queue->s.param.sched.prio;

>> +     return qentry_from_int(queue_fn->from_ext(handle))-

>> >s.param.sched.prio;

>>  }

>

> No need to use queue interface.

>

>>

>> -odp_schedule_group_t odp_queue_sched_group(odp_queue_t handle)

>> +static odp_schedule_group_t queue_sched_group(odp_queue_t handle)

>>  {

>> -     queue_entry_t *queue;

>> -

>> -     queue = queue_to_qentry(handle);

>> -

>> -     return queue->s.param.sched.group;

>> +     return qentry_from_int(queue_fn->from_ext(handle))

>> +                            ->s.param.sched.group;

>>  }

>

> No need to use queue interface.

>

>>

>> -int odp_queue_lock_count(odp_queue_t handle)

>> +static int queue_lock_count(odp_queue_t handle)

>>  {

>> -     queue_entry_t *queue = queue_to_qentry(handle);

>> +     queue_entry_t *queue = qentry_from_int(queue_fn-

>> >from_ext(handle));

>>

>>       return queue->s.param.sched.sync == ODP_SCHED_SYNC_ORDERED ?

>>               (int)queue->s.param.sched.lock_count : -1;

>>  }

>

> No need to use queue interface.

>

>>

>> -odp_queue_t odp_queue_create(const char *name, const odp_queue_param_t

>> *param)

>> +static odp_queue_t queue_create(const char *name,

>> +                             const odp_queue_param_t *param)

>>  {

>>       uint32_t i;

>>       queue_entry_t *queue;

>> @@ -291,10 +296,10 @@ void sched_cb_queue_destroy_finalize(uint32_t

>> queue_index)

>>       UNLOCK(&queue->s.lock);

>>  }

>>

>> -int odp_queue_destroy(odp_queue_t handle)

>> +static int queue_destroy(odp_queue_t handle)

>>  {

>>       queue_entry_t *queue;

>> -     queue = queue_to_qentry(handle);

>> +     queue = qentry_from_int(queue_fn->from_ext(handle));

>>

>>       if (handle == ODP_QUEUE_INVALID)

>>               return -1;

>> @@ -343,25 +348,21 @@ int odp_queue_destroy(odp_queue_t handle)

>>       return 0;

>>  }

>

> No need to use queue interface.

>

>>

>> -int odp_queue_context_set(odp_queue_t handle, void *context,

>> -                       uint32_t len ODP_UNUSED)

>> +static int queue_context_set(odp_queue_t handle, void *context,

>> +                          uint32_t len ODP_UNUSED)

>>  {

>> -     queue_entry_t *queue;

>> -     queue = queue_to_qentry(handle);

>>       odp_mb_full();

>> -     queue->s.param.context = context;

>> +     qentry_from_int(queue_fn->from_ext(handle))->s.param.context =

>> context;

>>       odp_mb_full();

>>       return 0;

>>  }

>

> No need to use queue interface.

>

>>

>> -void *odp_queue_context(odp_queue_t handle)

>> +static void *queue_context(odp_queue_t handle)

>>  {

>> -     queue_entry_t *queue;

>> -     queue = queue_to_qentry(handle);

>> -     return queue->s.param.context;

>> +     return qentry_from_int(queue_fn->from_ext(handle))-

>> >s.param.context;

>>  }

>

> No need to use queue interface.

>

>>

>> -odp_queue_t odp_queue_lookup(const char *name)

>> +static odp_queue_t queue_lookup(const char *name)

>>  {

>>       uint32_t i;

>>

>> @@ -384,15 +385,16 @@ odp_queue_t odp_queue_lookup(const char *name)

>>       return ODP_QUEUE_INVALID;

>>  }

>>

>> -static inline int enq_multi(queue_entry_t *queue, odp_buffer_hdr_t

>> *buf_hdr[],

>> +static inline int enq_multi(queue_t handle, odp_buffer_hdr_t *buf_hdr[],

>>                           int num)

>>  {

>>       int sched = 0;

>>       int i, ret;

>> +     queue_entry_t *queue;

>>       odp_buffer_hdr_t *hdr, *tail, *next_hdr;

>>

>> -     if (sched_fn->ord_enq_multi(queue->s.index, (void **)buf_hdr,

>> num,

>> -                     &ret))

>> +     queue = qentry_from_int(handle);

>> +     if (sched_fn->ord_enq_multi(handle, (void **)buf_hdr, num,

>> &ret))

>>               return ret;

>>

>>       /* Optimize the common case of single enqueue */

>> @@ -460,16 +462,17 @@ static inline int enq_multi(queue_entry_t *queue,

>> odp_buffer_hdr_t *buf_hdr[],

>>       return num; /* All events enqueued */

>>  }

>>

>> -int queue_enq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[],

>> int num)

>> +static int _queue_enq_multi(queue_t handle, odp_buffer_hdr_t *buf_hdr[],

>> +                         int num)

>>  {

>> -     return enq_multi(queue, buf_hdr, num);

>> +     return enq_multi(handle, buf_hdr, num);

>>  }

>>

>> -int queue_enq(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr)

>> +static int _queue_enq(queue_t handle, odp_buffer_hdr_t *buf_hdr)

>>  {

>>       int ret;

>>

>> -     ret = enq_multi(queue, &buf_hdr, 1);

>> +     ret = enq_multi(handle, &buf_hdr, 1);

>>

>>       if (ret == 1)

>>               return 0;

>> @@ -477,7 +480,7 @@ int queue_enq(queue_entry_t *queue, odp_buffer_hdr_t

>> *buf_hdr)

>>               return -1;

>>  }

>>

>> -int odp_queue_enq_multi(odp_queue_t handle, const odp_event_t ev[], int

>> num)

>> +static int queue_enq_multi(odp_queue_t handle, const odp_event_t ev[],

>> int num)

>>  {

>>       odp_buffer_hdr_t *buf_hdr[QUEUE_MULTI_MAX];

>>       queue_entry_t *queue;

>> @@ -486,33 +489,35 @@ int odp_queue_enq_multi(odp_queue_t handle, const

>> odp_event_t ev[], int num)

>>       if (num > QUEUE_MULTI_MAX)

>>               num = QUEUE_MULTI_MAX;

>>

>> -     queue = queue_to_qentry(handle);

>> +     queue = qentry_from_int(queue_fn->from_ext(handle));

>

> No need to use queue interface.

>

>>

>>       for (i = 0; i < num; i++)

>>               buf_hdr[i] =

>> buf_hdl_to_hdr(odp_buffer_from_event(ev[i]));

>>

>> -     return num == 0 ? 0 : queue->s.enqueue_multi(queue, buf_hdr,

>> -

>> num);

>> +     return num == 0 ? 0 : queue-

>> >s.enqueue_multi(qentry_to_int(queue),

>> +

>> buf_hdr, num);

>>  }

>>

>> -int odp_queue_enq(odp_queue_t handle, odp_event_t ev)

>> +static int queue_enq(odp_queue_t handle, odp_event_t ev)

>>  {

>>       odp_buffer_hdr_t *buf_hdr;

>>       queue_entry_t *queue;

>>

>> -     queue   = queue_to_qentry(handle);

>> +     queue   = qentry_from_int(queue_fn->from_ext(handle));

>

> No need to use queue interface.

>

>>       buf_hdr = buf_hdl_to_hdr(odp_buffer_from_event(ev));

>>

>> -     return queue->s.enqueue(queue, buf_hdr);

>> +     return queue->s.enqueue(qentry_to_int(queue), buf_hdr);

>>  }

>>

>> -static inline int deq_multi(queue_entry_t *queue, odp_buffer_hdr_t

>> *buf_hdr[],

>> +static inline int deq_multi(queue_t handle, odp_buffer_hdr_t *buf_hdr[],

>>                           int num)

>>  {

>>       odp_buffer_hdr_t *hdr, *next;

>>       int i, j;

>> +     queue_entry_t *queue;

>>       int updated = 0;

>>

>> +     queue = qentry_from_int(handle);

>>       LOCK(&queue->s.lock);

>>       if (odp_unlikely(queue->s.status < QUEUE_STATUS_READY)) {

>>               /* Bad queue, or queue has been destroyed.

>> @@ -578,17 +583,18 @@ static inline int deq_multi(queue_entry_t *queue,

>> odp_buffer_hdr_t *buf_hdr[],

>>       return i;

>>  }

>>

>> -int queue_deq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[],

>> int num)

>> +static int _queue_deq_multi(queue_t handle, odp_buffer_hdr_t *buf_hdr[],

>> +                         int num)

>>  {

>> -     return deq_multi(queue, buf_hdr, num);

>> +     return deq_multi(handle, buf_hdr, num);

>>  }

>>

>> -odp_buffer_hdr_t *queue_deq(queue_entry_t *queue)

>> +static odp_buffer_hdr_t *_queue_deq(queue_t handle)

>>  {

>>       odp_buffer_hdr_t *buf_hdr = NULL;

>>       int ret;

>>

>> -     ret = deq_multi(queue, &buf_hdr, 1);

>> +     ret = deq_multi(handle, &buf_hdr, 1);

>>

>>       if (ret == 1)

>>               return buf_hdr;

>> @@ -596,7 +602,7 @@ odp_buffer_hdr_t *queue_deq(queue_entry_t *queue)

>>               return NULL;

>>  }

>>

>> -int odp_queue_deq_multi(odp_queue_t handle, odp_event_t events[], int

>> num)

>> +static int queue_deq_multi(odp_queue_t handle, odp_event_t events[], int

>> num)

>>  {

>>       queue_entry_t *queue;

>>       odp_buffer_hdr_t *buf_hdr[QUEUE_MULTI_MAX];

>> @@ -605,9 +611,9 @@ int odp_queue_deq_multi(odp_queue_t handle,

>> odp_event_t events[], int num)

>>       if (num > QUEUE_MULTI_MAX)

>>               num = QUEUE_MULTI_MAX;

>>

>> -     queue = queue_to_qentry(handle);

>> +     queue = qentry_from_int(queue_fn->from_ext(handle));

>

> No need to use queue interface.

>

>>

>> -     ret = queue->s.dequeue_multi(queue, buf_hdr, num);

>> +     ret = queue->s.dequeue_multi(qentry_to_int(queue), buf_hdr,

>> num);

>>

>>       for (i = 0; i < ret; i++)

>>               events[i] = odp_buffer_to_event(buf_hdr[i]-

>> >handle.handle);

>> @@ -616,13 +622,13 @@ int odp_queue_deq_multi(odp_queue_t handle,

>> odp_event_t events[], int num)

>>  }

>>

>>

>> -odp_event_t odp_queue_deq(odp_queue_t handle)

>> +static odp_event_t queue_deq(odp_queue_t handle)

>>  {

>>       queue_entry_t *queue;

>>       odp_buffer_hdr_t *buf_hdr;

>>

>> -     queue   = queue_to_qentry(handle);

>> -     buf_hdr = queue->s.dequeue(queue);

>> +     queue   = qentry_from_int(queue_fn->from_ext(handle));

>

> No need to use queue interface.

>

>> +     buf_hdr = queue->s.dequeue(qentry_to_int(queue));

>>

>>       if (buf_hdr)

>>               return odp_buffer_to_event(buf_hdr->handle.handle);

>> @@ -640,7 +646,7 @@ void queue_unlock(queue_entry_t *queue)

>>       UNLOCK(&queue->s.lock);

>>  }

>>

>> -void odp_queue_param_init(odp_queue_param_t *params)

>> +static void queue_param_init(odp_queue_param_t *params)

>>  {

>>       memset(params, 0, sizeof(odp_queue_param_t));

>>       params->type = ODP_QUEUE_TYPE_PLAIN;

>> @@ -651,7 +657,7 @@ void odp_queue_param_init(odp_queue_param_t *params)

>>       params->sched.group = ODP_SCHED_GROUP_ALL;

>>  }

>>

>> -int odp_queue_info(odp_queue_t handle, odp_queue_info_t *info)

>> +static int queue_info(odp_queue_t handle, odp_queue_info_t *info)

>>  {

>>       uint32_t queue_id;

>>       queue_entry_t *queue;

>> @@ -730,7 +736,7 @@ int sched_cb_queue_deq_multi(uint32_t queue_index,

>> odp_event_t ev[], int num)

>>       queue_entry_t *qe = get_qentry(queue_index);

>>       odp_buffer_hdr_t *buf_hdr[num];

>>

>> -     ret = deq_multi(qe, buf_hdr, num);

>> +     ret = deq_multi(qentry_to_int(qe), buf_hdr, num);

>>

>>       if (ret > 0)

>>               for (i = 0; i < ret; i++)

>> @@ -765,7 +771,112 @@ int sched_cb_queue_empty(uint32_t queue_index)

>>       return ret;

>>  }

>>

>> -uint64_t odp_queue_to_u64(odp_queue_t hdl)

>> +static uint64_t queue_to_u64(odp_queue_t hdl)

>>  {

>>       return _odp_pri(hdl);

>>  }

>> +

>> +static odp_pktout_queue_t queue_get_pktout(queue_t handle)

>> +{

>> +     return qentry_from_int(handle)->s.pktout;

>> +}

>> +

>> +static void queue_set_pktout(queue_t handle, odp_pktio_t pktio, int

>> index)

>> +{

>> +     qentry_from_int(handle)->s.pktout.pktio = pktio;

>> +     qentry_from_int(handle)->s.pktout.index = index;

>> +}

>> +

>> +static odp_pktin_queue_t queue_get_pktin(queue_t handle)

>> +{

>> +     return qentry_from_int(handle)->s.pktin;

>> +}

>> +

>> +static void queue_set_pktin(queue_t handle, odp_pktio_t pktio, int index)

>> +{

>> +     qentry_from_int(handle)->s.pktin.pktio = pktio;

>> +     qentry_from_int(handle)->s.pktin.index = index;

>> +}

>> +

>> +static void queue_set_enq_func(queue_t handle, queue_enq_fn_t func)

>> +{

>> +     qentry_from_int(handle)->s.enqueue = func;

>> +}

>> +

>> +static void queue_set_enq_multi_func(queue_t handle, queue_enq_multi_fn_t

>> func)

>> +{

>> +     qentry_from_int(handle)->s.enqueue_multi = func;

>> +}

>> +

>> +static void queue_set_deq_func(queue_t handle, queue_deq_fn_t func)

>> +{

>> +     qentry_from_int(handle)->s.dequeue = func;

>> +}

>> +

>> +static void queue_set_deq_multi_func(queue_t handle, queue_deq_multi_fn_t

>> func)

>> +{

>> +     qentry_from_int(handle)->s.dequeue_multi = func;

>> +}

>> +

>> +static void queue_set_type(queue_t handle, odp_queue_type_t type)

>> +{

>> +     qentry_from_int(handle)->s.type = type;

>> +}

>> +

>> +static queue_t queue_from_ext(odp_queue_t handle)

>> +{

>> +     uint32_t queue_id;

>> +

>> +     queue_id = queue_to_id(handle);

>> +     return qentry_to_int(get_qentry(queue_id));

>> +}

>

> I'd keep the old queue_to_qentry() as is, and implement this one by using it.


After implementing queue_from_ext and qentry_from_int,
queue_to_qentry() becomes redundant.

>

>

>> +

>> +static odp_queue_t queue_to_ext(queue_t handle)

>> +{

>> +     return qentry_from_int(handle)->s.handle;

>> +}

>> +

>> +/* API functions */

>> +queue_api_t queue_default_api = {

>> +     .queue_create = queue_create,

>> +     .queue_destroy = queue_destroy,

>> +     .queue_lookup = queue_lookup,

>> +     .queue_capability = queue_capability,

>> +     .queue_context_set = queue_context_set,

>> +     .queue_context = queue_context,

>> +     .queue_enq = queue_enq,

>> +     .queue_enq_multi = queue_enq_multi,

>> +     .queue_deq = queue_deq,

>> +     .queue_deq_multi = queue_deq_multi,

>> +     .queue_type = queue_type,

>> +     .queue_sched_type = queue_sched_type,

>> +     .queue_sched_prio = queue_sched_prio,

>> +     .queue_sched_group = queue_sched_group,

>> +     .queue_lock_count = queue_lock_count,

>> +     .queue_to_u64 = queue_to_u64,

>> +     .queue_param_init = queue_param_init,

>> +     .queue_info = queue_info

>> +};

>> +

>> +/* Functions towards internal components */

>> +queue_fn_t queue_default_fn = {

>> +     .init_global = queue_init_global,

>> +     .term_global = queue_term_global,

>> +     .init_local = queue_init_local,

>> +     .term_local = queue_term_local,

>> +     .from_ext = queue_from_ext,

>> +     .to_ext = queue_to_ext,

>> +     .enq = _queue_enq,

>> +     .enq_multi = _queue_enq_multi,

>> +     .deq = _queue_deq,

>> +     .deq_multi = _queue_deq_multi,

>> +     .get_pktout = queue_get_pktout,

>> +     .set_pktout = queue_set_pktout,

>> +     .get_pktin = queue_get_pktin,

>> +     .set_pktin = queue_set_pktin,

>> +     .set_enq_fn = queue_set_enq_func,

>> +     .set_enq_multi_fn = queue_set_enq_multi_func,

>> +     .set_deq_fn = queue_set_deq_func,

>> +     .set_deq_multi_fn = queue_set_deq_multi_func,

>> +     .set_type = queue_set_type

>> +};

>> diff --git a/platform/linux-generic/odp_queue_if.c b/platform/linux-

>> generic/odp_queue_if.c

>> new file mode 100644

>> index 00000000..5a4f7194

>> --- /dev/null

>> +++ b/platform/linux-generic/odp_queue_if.c

>> @@ -0,0 +1,103 @@

>> +/* Copyright (c) 2016, ARM Limited

>

>

> Year 2017

>

Agree
>

>

> -Petri

>

>
Savolainen, Petri (Nokia - FI/Espoo) June 7, 2017, 7:12 a.m. | #3
> -----Original Message-----

> From: Honnappa Nagarahalli [mailto:honnappa.nagarahalli@linaro.org]

> Sent: Tuesday, June 06, 2017 10:43 PM

> To: Savolainen, Petri (Nokia - FI/Espoo) <petri.savolainen@nokia.com>

> Cc: Github ODP bot <odpbot@yandex.ru>; lng-odp@lists.linaro.org

> Subject: Re: [lng-odp] [PATCH API-NEXT v5 1/1] linux-generic: queue:

> modular queue interface

> 

> On 6 June 2017 at 05:53, Savolainen, Petri (Nokia - FI/Espoo)

> <petri.savolainen@nokia.com> wrote:

> > Couple of general comments first:

> >

> > 1) Discussion about various versions of this patch has not reached the

> mailing list. That needs to be fixed in Github configuration...

> >

> > 2) Queue handle/qentry naming should be consistent over the entire

> patch.

> >

> > Today:

> > * "handle" refers to odp_queue_t

> > * "queue" or "qe" refers to *queue_entry_t when inside of queue.c

> > * "qentry" or "qe" refers to *queue_entry_t when outside of queue.c

> >

> > After this patch, the same should apply - especially for "handle". Try

> to minimize changes inside queue.c. When you add queue_t it should *not*

> be referred as "handle" (which is odp_queue_t), but something else - maybe

> consistently "queue_int". Otherwise, it's hard to follow which variable

> refers to odp_queue_t, queue_t or queue_entry_t.

> >

> 

> The same should not apply because this patch has introduced another

> level of abstract data type and the code should reflect that. I do

> agree that consistent naming needs to be used. Following is my

> proposal:

> 

> Looking at "outside of queue.c" (including odp_schedule*.c)

> 1) structure members of type 'odp_queue_t' and 'queue_t'. Naming is

> not consistent. The naming is according to the context/purpose of

> those members. I suggest that we do not rename these. Except members

> of type 'queue_t' can be suffixed with '_int'.

> 2) local variables and function arguments of type 'odp_queue_t' and

> 'queue_t'. These can be named 'queue' and 'queue_int' respectively

> There is no point in referring to these as 'handle' or 'handle_int',

> these do not convey anything outside queue.* files.

> 

> Looking at "inside of queue.c"

> 1) anything that refers to *queue_entry_t can be called as 'qentry' or

> 'qe'

> 2) variables and function arguments of type 'odp_queue_t' and

> 'queue_t'. These can be named 'handle' and 'handle_int' respectively.



The internal interface may change later to pass through odp_queue_t instead of queue_t on some occasions. Now it's just a copy-paste replacement of qentry->xxx accesses. That in mind something that is today queue_t may change to odp_queue_t later.

Conversions happen only in two levels:
* Outside of queue.c
  * odp_queue_t <-> queue_t
    ==> between API handle and internal queue type (==> new interface)
* Inside of queue.c
  * odp_queue_t <-> queue_entry_t
    ==> directly between API handle and queue_entry_t pointer (==> queue_to_qentry())
  * queue_t <-> queue_entry_t
    ==> between internal queue type and queue_entry_t pointer (==> just a cast)

Inside queue.c there's no need or benefit on two step conversion (odp_queue_t -> queue_t -> queue_entry_t), since the last two types are defined/known by the queue implementation itself.

queue.c
-------------

static inline queue_entry_t *queue_to_qentry(odp_queue_t handle)
{
	uint32_t queue_id;

	queue_id = queue_to_id(handle);
	return get_qentry(queue_id);
}

static queue_t queue_from_ext(odp_queue_t handle)
{
	return (queue_t)queue_to_qentry(handle);
}

static inline queue_entry_t *qentry_from_int(queue_t queue_int)
{
	return (queue_entry_t *)(void *)(queue_int);
}


The direct handle to qentry should remain as a single operation (queue_to_qentry() above). If you keep the same name, you save a lot of unnecessary changes in queue.c. This patch should touch mainly outside of queue.c (change direct queue entry accesses to functions).

-Petri

Patch hide | download patch | download mbox

diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am
index 79f0e70c..58c73767 100644
--- a/platform/linux-generic/Makefile.am
+++ b/platform/linux-generic/Makefile.am
@@ -170,6 +170,7 @@  noinst_HEADERS = \
 		  ${srcdir}/include/odp_posix_extensions.h \
 		  ${srcdir}/include/odp_queue_internal.h \
 		  ${srcdir}/include/odp_ring_internal.h \
+		  ${srcdir}/include/odp_queue_if.h \
 		  ${srcdir}/include/odp_schedule_if.h \
 		  ${srcdir}/include/odp_sorted_list_internal.h \
 		  ${srcdir}/include/odp_shm_internal.h \
@@ -225,6 +226,7 @@  __LIB__libodp_linux_la_SOURCES = \
 			   odp_pkt_queue.c \
 			   odp_pool.c \
 			   odp_queue.c \
+			   odp_queue_if.c \
 			   odp_rwlock.c \
 			   odp_rwlock_recursive.c \
 			   odp_schedule.c \
diff --git a/platform/linux-generic/include/odp_classification_datamodel.h b/platform/linux-generic/include/odp_classification_datamodel.h
index 9df756bf..fbe10cb4 100644
--- a/platform/linux-generic/include/odp_classification_datamodel.h
+++ b/platform/linux-generic/include/odp_classification_datamodel.h
@@ -24,7 +24,7 @@  extern "C" {
 #include <odp_pool_internal.h>
 #include <odp_packet_internal.h>
 #include <odp_packet_io_internal.h>
-#include <odp_queue_internal.h>
+#include <odp_queue_if.h>
 #include <protocols/ip.h>
 
 /* Maximum Class Of Service Entry */
@@ -85,7 +85,7 @@  typedef struct pmr_term_value {
 Class Of Service
 */
 struct cos_s {
-	queue_entry_t *queue;		/* Associated Queue */
+	queue_t queue;			/* Associated Queue */
 	odp_pool_t pool;		/* Associated Buffer pool */
 	union pmr_u *pmr[ODP_PMR_PER_COS_MAX];	/* Chained PMR */
 	union cos_u *linked_cos[ODP_PMR_PER_COS_MAX]; /* Chained CoS with PMR*/
diff --git a/platform/linux-generic/include/odp_packet_io_queue.h b/platform/linux-generic/include/odp_packet_io_queue.h
index d1d4b225..71333ddc 100644
--- a/platform/linux-generic/include/odp_packet_io_queue.h
+++ b/platform/linux-generic/include/odp_packet_io_queue.h
@@ -18,7 +18,7 @@ 
 extern "C" {
 #endif
 
-#include <odp_queue_internal.h>
+#include <odp_queue_if.h>
 #include <odp_buffer_internal.h>
 #include <odp_config_internal.h>
 
@@ -28,20 +28,18 @@  extern "C" {
 ODP_STATIC_ASSERT(ODP_PKTIN_QUEUE_MAX_BURST >= QUEUE_MULTI_MAX,
 		  "ODP_PKTIN_DEQ_MULTI_MAX_ERROR");
 
-int pktin_enqueue(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr);
-odp_buffer_hdr_t *pktin_dequeue(queue_entry_t *queue);
+int pktin_enqueue(queue_t queue, odp_buffer_hdr_t *buf_hdr);
+odp_buffer_hdr_t *pktin_dequeue(queue_t queue);
 
-int pktin_enq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[], int num);
-int pktin_deq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[], int num);
+int pktin_enq_multi(queue_t queue, odp_buffer_hdr_t *buf_hdr[], int num);
+int pktin_deq_multi(queue_t queue, odp_buffer_hdr_t *buf_hdr[], int num);
 
 
-int pktout_enqueue(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr);
-odp_buffer_hdr_t *pktout_dequeue(queue_entry_t *queue);
+int pktout_enqueue(queue_t queue, odp_buffer_hdr_t *buf_hdr);
+odp_buffer_hdr_t *pktout_dequeue(queue_t queue);
 
-int pktout_enq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[],
-		     int num);
-int pktout_deq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[],
-		     int num);
+int pktout_enq_multi(queue_t queue, odp_buffer_hdr_t *buf_hdr[], int num);
+int pktout_deq_multi(queue_t queue, odp_buffer_hdr_t *buf_hdr[], int num);
 
 #ifdef __cplusplus
 }
diff --git a/platform/linux-generic/include/odp_queue_if.h b/platform/linux-generic/include/odp_queue_if.h
new file mode 100644
index 00000000..4359435f
--- /dev/null
+++ b/platform/linux-generic/include/odp_queue_if.h
@@ -0,0 +1,104 @@ 
+/* Copyright (c) 2017, ARM Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:     BSD-3-Clause
+ */
+
+#ifndef ODP_QUEUE_IF_H_
+#define ODP_QUEUE_IF_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <odp/api/queue.h>
+#include <odp/api/schedule.h>
+#include <odp/api/packet_io.h>
+#include <odp_forward_typedefs_internal.h>
+
+#define QUEUE_MULTI_MAX CONFIG_BURST_SIZE
+
+/* Queue API functions */
+typedef struct {
+	odp_queue_t (*queue_create)(const char *name,
+				    const odp_queue_param_t *param);
+	int (*queue_destroy)(odp_queue_t queue);
+	odp_queue_t (*queue_lookup)(const char *name);
+	int (*queue_capability)(odp_queue_capability_t *capa);
+	int (*queue_context_set)(odp_queue_t queue, void *context,
+				 uint32_t len);
+	void *(*queue_context)(odp_queue_t queue);
+	int (*queue_enq)(odp_queue_t queue, odp_event_t ev);
+	int (*queue_enq_multi)(odp_queue_t queue, const odp_event_t events[],
+			       int num);
+	odp_event_t (*queue_deq)(odp_queue_t queue);
+	int (*queue_deq_multi)(odp_queue_t queue, odp_event_t events[],
+			       int num);
+	odp_queue_type_t (*queue_type)(odp_queue_t queue);
+	odp_schedule_sync_t (*queue_sched_type)(odp_queue_t queue);
+	odp_schedule_prio_t (*queue_sched_prio)(odp_queue_t queue);
+	odp_schedule_group_t (*queue_sched_group)(odp_queue_t queue);
+	int (*queue_lock_count)(odp_queue_t queue);
+	uint64_t (*queue_to_u64)(odp_queue_t hdl);
+	void (*queue_param_init)(odp_queue_param_t *param);
+	int (*queue_info)(odp_queue_t queue, odp_queue_info_t *info);
+} queue_api_t;
+
+/* Internal abstract queue handle */
+typedef struct { char dummy; } _queue_t;
+typedef _queue_t *queue_t;
+
+typedef int (*queue_init_global_fn_t)(void);
+typedef int (*queue_term_global_fn_t)(void);
+typedef int (*queue_init_local_fn_t)(void);
+typedef int (*queue_term_local_fn_t)(void);
+typedef queue_t (*queue_from_ext_fn_t)(odp_queue_t handle);
+typedef odp_queue_t (*queue_to_ext_fn_t)(queue_t handle);
+typedef int (*queue_enq_fn_t)(queue_t handle, odp_buffer_hdr_t *);
+typedef int (*queue_enq_multi_fn_t)(queue_t handle, odp_buffer_hdr_t **, int);
+typedef odp_buffer_hdr_t *(*queue_deq_fn_t)(queue_t handle);
+typedef int (*queue_deq_multi_fn_t)(queue_t handle, odp_buffer_hdr_t **, int);
+typedef odp_pktout_queue_t (*queue_get_pktout_fn_t)(queue_t handle);
+typedef void (*queue_set_pktout_fn_t)(queue_t handle, odp_pktio_t pktio,
+				      int index);
+typedef odp_pktin_queue_t (*queue_get_pktin_fn_t)(queue_t handle);
+typedef void (*queue_set_pktin_fn_t)(queue_t handle, odp_pktio_t pktio,
+				     int index);
+typedef void (*queue_set_enq_fn_t)(queue_t handle, queue_enq_fn_t func);
+typedef void (*queue_set_enq_multi_fn_t)(queue_t handle,
+					 queue_enq_multi_fn_t func);
+typedef void (*queue_set_deq_fn_t)(queue_t handle, queue_deq_fn_t func);
+typedef void (*queue_set_deq_multi_fn_t)(queue_t handle,
+					 queue_deq_multi_fn_t func);
+typedef void (*queue_set_type_fn_t)(queue_t handle, odp_queue_type_t type);
+
+/* Queue functions towards other internal components */
+typedef struct {
+	queue_init_global_fn_t init_global;
+	queue_term_global_fn_t term_global;
+	queue_init_local_fn_t init_local;
+	queue_term_local_fn_t term_local;
+	queue_from_ext_fn_t from_ext;
+	queue_to_ext_fn_t to_ext;
+	queue_enq_fn_t enq;
+	queue_enq_multi_fn_t enq_multi;
+	queue_deq_fn_t deq;
+	queue_deq_multi_fn_t deq_multi;
+	queue_get_pktout_fn_t get_pktout;
+	queue_set_pktout_fn_t set_pktout;
+	queue_get_pktin_fn_t get_pktin;
+	queue_set_pktin_fn_t set_pktin;
+	queue_set_enq_fn_t set_enq_fn;
+	queue_set_enq_multi_fn_t set_enq_multi_fn;
+	queue_set_deq_fn_t set_deq_fn;
+	queue_set_deq_multi_fn_t set_deq_multi_fn;
+	queue_set_type_fn_t set_type;
+} queue_fn_t;
+
+extern const queue_fn_t *queue_fn;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/platform/linux-generic/include/odp_queue_internal.h b/platform/linux-generic/include/odp_queue_internal.h
index 560f826e..0c31ce8a 100644
--- a/platform/linux-generic/include/odp_queue_internal.h
+++ b/platform/linux-generic/include/odp_queue_internal.h
@@ -20,7 +20,7 @@  extern "C" {
 
 #include <odp/api/queue.h>
 #include <odp_forward_typedefs_internal.h>
-#include <odp_schedule_if.h>
+#include <odp_queue_if.h>
 #include <odp_buffer_internal.h>
 #include <odp_align_internal.h>
 #include <odp/api/packet_io.h>
@@ -29,26 +29,12 @@  extern "C" {
 #include <odp/api/ticketlock.h>
 #include <odp_config_internal.h>
 
-#define QUEUE_MULTI_MAX CONFIG_BURST_SIZE
-
 #define QUEUE_STATUS_FREE         0
 #define QUEUE_STATUS_DESTROYED    1
 #define QUEUE_STATUS_READY        2
 #define QUEUE_STATUS_NOTSCHED     3
 #define QUEUE_STATUS_SCHED        4
 
-
-/* forward declaration */
-union queue_entry_u;
-
-typedef int (*enq_func_t)(union queue_entry_u *, odp_buffer_hdr_t *);
-typedef	odp_buffer_hdr_t *(*deq_func_t)(union queue_entry_u *);
-
-typedef int (*enq_multi_func_t)(union queue_entry_u *,
-				odp_buffer_hdr_t **, int);
-typedef	int (*deq_multi_func_t)(union queue_entry_u *,
-				odp_buffer_hdr_t **, int);
-
 struct queue_entry_s {
 	odp_ticketlock_t  lock ODP_ALIGNED_CACHE;
 
@@ -63,10 +49,10 @@  struct queue_entry_s {
 		odp_atomic_u64_t  lock[CONFIG_QUEUE_MAX_ORD_LOCKS];
 	} ordered ODP_ALIGNED_CACHE;
 
-	enq_func_t       enqueue ODP_ALIGNED_CACHE;
-	deq_func_t       dequeue;
-	enq_multi_func_t enqueue_multi;
-	deq_multi_func_t dequeue_multi;
+	queue_enq_fn_t       enqueue ODP_ALIGNED_CACHE;
+	queue_deq_fn_t       dequeue;
+	queue_enq_multi_fn_t enqueue_multi;
+	queue_deq_multi_fn_t dequeue_multi;
 
 	uint32_t          index;
 	odp_queue_t       handle;
@@ -82,15 +68,8 @@  union queue_entry_u {
 	uint8_t pad[ROUNDUP_CACHE_LINE(sizeof(struct queue_entry_s))];
 };
 
-
 queue_entry_t *get_qentry(uint32_t queue_id);
 
-int queue_enq(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr);
-odp_buffer_hdr_t *queue_deq(queue_entry_t *queue);
-
-int queue_enq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[], int num);
-int queue_deq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[], int num);
-
 void queue_lock(queue_entry_t *queue);
 void queue_unlock(queue_entry_t *queue);
 
@@ -99,12 +78,14 @@  static inline uint32_t queue_to_id(odp_queue_t handle)
 	return _odp_typeval(handle) - 1;
 }
 
-static inline queue_entry_t *queue_to_qentry(odp_queue_t handle)
+static inline queue_entry_t *qentry_from_int(queue_t handle)
 {
-	uint32_t queue_id;
+	return (queue_entry_t *)(void *)(handle);
+}
 
-	queue_id = queue_to_id(handle);
-	return get_qentry(queue_id);
+static inline queue_t qentry_to_int(queue_entry_t *qentry)
+{
+	return (queue_t)(qentry);
 }
 
 #ifdef __cplusplus
diff --git a/platform/linux-generic/include/odp_schedule_if.h b/platform/linux-generic/include/odp_schedule_if.h
index 530d157f..9adacef7 100644
--- a/platform/linux-generic/include/odp_schedule_if.h
+++ b/platform/linux-generic/include/odp_schedule_if.h
@@ -26,7 +26,7 @@  typedef int (*schedule_init_queue_fn_t)(uint32_t queue_index,
 typedef void (*schedule_destroy_queue_fn_t)(uint32_t queue_index);
 typedef int (*schedule_sched_queue_fn_t)(uint32_t queue_index);
 typedef int (*schedule_unsched_queue_fn_t)(uint32_t queue_index);
-typedef int (*schedule_ord_enq_multi_fn_t)(uint32_t queue_index,
+typedef int (*schedule_ord_enq_multi_fn_t)(queue_t handle,
 					   void *buf_hdr[], int num, int *ret);
 typedef int (*schedule_init_global_fn_t)(void);
 typedef int (*schedule_term_global_fn_t)(void);
diff --git a/platform/linux-generic/include/odp_traffic_mngr_internal.h b/platform/linux-generic/include/odp_traffic_mngr_internal.h
index 9f821fe4..e8254f5e 100644
--- a/platform/linux-generic/include/odp_traffic_mngr_internal.h
+++ b/platform/linux-generic/include/odp_traffic_mngr_internal.h
@@ -29,7 +29,7 @@  extern "C" {
 #include <odp_internal.h>
 #include <odp_debug_internal.h>
 #include <odp_buffer_internal.h>
-#include <odp_queue_internal.h>
+#include <odp_queue_if.h>
 #include <odp_packet_internal.h>
 
 typedef struct stat  file_stat_t;
@@ -286,7 +286,7 @@  struct tm_queue_obj_s {
 	uint8_t tm_idx;
 	uint8_t delayed_cnt;
 	uint8_t blocked_cnt;
-	queue_entry_t tm_qentry;
+	queue_t tm_qentry;
 };
 
 struct tm_node_obj_s {
diff --git a/platform/linux-generic/odp_classification.c b/platform/linux-generic/odp_classification.c
index 7ebc47d7..5f153e73 100644
--- a/platform/linux-generic/odp_classification.c
+++ b/platform/linux-generic/odp_classification.c
@@ -157,14 +157,14 @@  int odp_cls_capability(odp_cls_capability_t *capability)
 odp_cos_t odp_cls_cos_create(const char *name, odp_cls_cos_param_t *param)
 {
 	int i, j;
-	queue_entry_t *queue;
+	queue_t queue;
 	odp_cls_drop_t drop_policy;
 
 	/* Packets are dropped if Queue or Pool is invalid*/
 	if (param->queue == ODP_QUEUE_INVALID)
 		queue = NULL;
 	else
-		queue = queue_to_qentry(param->queue);
+		queue = queue_fn->from_ext(param->queue);
 
 	drop_policy = param->drop_policy;
 
@@ -266,7 +266,7 @@  int odp_cos_queue_set(odp_cos_t cos_id, odp_queue_t queue_id)
 	if (queue_id == ODP_QUEUE_INVALID)
 		cos->s.queue = NULL;
 	else
-		cos->s.queue = queue_to_qentry(queue_id);
+		cos->s.queue = queue_fn->from_ext(queue_id);
 	return 0;
 }
 
@@ -282,7 +282,7 @@  odp_queue_t odp_cos_queue(odp_cos_t cos_id)
 	if (!cos->s.queue)
 		return ODP_QUEUE_INVALID;
 
-	return cos->s.queue->s.handle;
+	return queue_fn->to_ext(cos->s.queue);
 }
 
 int odp_cos_drop_set(odp_cos_t cos_id, odp_cls_drop_t drop_policy)
@@ -846,7 +846,7 @@  int cls_classify_packet(pktio_entry_t *entry, const uint8_t *base,
 
 	*pool = cos->s.pool;
 	pkt_hdr->p.input_flags.dst_queue = 1;
-	pkt_hdr->dst_queue = cos->s.queue->s.handle;
+	pkt_hdr->dst_queue = queue_fn->to_ext(cos->s.queue);
 
 	return 0;
 }
diff --git a/platform/linux-generic/odp_init.c b/platform/linux-generic/odp_init.c
index 685e02fa..31bd7c73 100644
--- a/platform/linux-generic/odp_init.c
+++ b/platform/linux-generic/odp_init.c
@@ -218,7 +218,7 @@  int odp_init_global(odp_instance_t *instance,
 	}
 	stage = POOL_INIT;
 
-	if (odp_queue_init_global()) {
+	if (queue_fn->init_global()) {
 		ODP_ERR("ODP queue init failed.\n");
 		goto init_failed;
 	}
@@ -346,7 +346,7 @@  int _odp_term_global(enum init_stage stage)
 		/* Fall through */
 
 	case QUEUE_INIT:
-		if (odp_queue_term_global()) {
+		if (queue_fn->term_global()) {
 			ODP_ERR("ODP queue term failed.\n");
 			rc = -1;
 		}
@@ -441,6 +441,12 @@  int odp_init_local(odp_instance_t instance, odp_thread_type_t thr_type)
 	}
 	stage = POOL_INIT;
 
+	if (queue_fn->init_local()) {
+		ODP_ERR("ODP queue local init failed.\n");
+		goto init_fail;
+	}
+	stage = QUEUE_INIT;
+
 	if (sched_fn->init_local()) {
 		ODP_ERR("ODP schedule local init failed.\n");
 		goto init_fail;
@@ -474,6 +480,13 @@  int _odp_term_local(enum init_stage stage)
 		}
 		/* Fall through */
 
+	case QUEUE_INIT:
+		if (queue_fn->term_local()) {
+			ODP_ERR("ODP queue local term failed.\n");
+			rc = -1;
+		}
+		/* Fall through */
+
 	case POOL_INIT:
 		if (odp_pool_term_local()) {
 			ODP_ERR("ODP buffer pool local term failed.\n");
diff --git a/platform/linux-generic/odp_packet_io.c b/platform/linux-generic/odp_packet_io.c
index 877978ba..8fb5b5ee 100644
--- a/platform/linux-generic/odp_packet_io.c
+++ b/platform/linux-generic/odp_packet_io.c
@@ -16,7 +16,7 @@ 
 #include <odp/api/shared_memory.h>
 #include <odp_packet_socket.h>
 #include <odp_config_internal.h>
-#include <odp_queue_internal.h>
+#include <odp_queue_if.h>
 #include <odp_schedule_if.h>
 #include <odp_classification_internal.h>
 #include <odp_debug_internal.h>
@@ -568,11 +568,11 @@  static inline int pktin_recv_buf(odp_pktin_queue_t queue,
 		buf_hdr = buf_hdl_to_hdr(buf);
 
 		if (pkt_hdr->p.input_flags.dst_queue) {
-			queue_entry_t *dst_queue;
+			queue_t dst_queue;
 			int ret;
 
-			dst_queue = queue_to_qentry(pkt_hdr->dst_queue);
-			ret = queue_enq(dst_queue, buf_hdr);
+			dst_queue = queue_fn->from_ext(pkt_hdr->dst_queue);
+			ret = queue_fn->enq(dst_queue, buf_hdr);
 			if (ret < 0)
 				odp_packet_free(pkt);
 			continue;
@@ -582,45 +582,42 @@  static inline int pktin_recv_buf(odp_pktin_queue_t queue,
 	return num_rx;
 }
 
-int pktout_enqueue(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr)
+int pktout_enqueue(queue_t qentry, odp_buffer_hdr_t *buf_hdr)
 {
 	odp_packet_t pkt = _odp_packet_from_buffer(buf_hdr->handle.handle);
 	int len = 1;
 	int nbr;
 
-	if (sched_fn->ord_enq_multi(qentry->s.index, (void **)buf_hdr, len,
-				    &nbr))
+	if (sched_fn->ord_enq_multi(qentry, (void **)buf_hdr, len, &nbr))
 		return (nbr == len ? 0 : -1);
 
-	nbr = odp_pktout_send(qentry->s.pktout, &pkt, len);
+	nbr = odp_pktout_send(queue_fn->get_pktout(qentry), &pkt, len);
 	return (nbr == len ? 0 : -1);
 }
 
-odp_buffer_hdr_t *pktout_dequeue(queue_entry_t *qentry ODP_UNUSED)
+odp_buffer_hdr_t *pktout_dequeue(queue_t qentry ODP_UNUSED)
 {
 	ODP_ABORT("attempted dequeue from a pktout queue");
 	return NULL;
 }
 
-int pktout_enq_multi(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr[],
-		     int num)
+int pktout_enq_multi(queue_t qentry, odp_buffer_hdr_t *buf_hdr[], int num)
 {
 	odp_packet_t pkt_tbl[QUEUE_MULTI_MAX];
 	int nbr;
 	int i;
 
-	if (sched_fn->ord_enq_multi(qentry->s.index, (void **)buf_hdr, num,
-				    &nbr))
+	if (sched_fn->ord_enq_multi(qentry, (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);
 
-	nbr = odp_pktout_send(qentry->s.pktout, pkt_tbl, num);
+	nbr = odp_pktout_send(queue_fn->get_pktout(qentry), pkt_tbl, num);
 	return nbr;
 }
 
-int pktout_deq_multi(queue_entry_t *qentry ODP_UNUSED,
+int pktout_deq_multi(queue_t qentry ODP_UNUSED,
 		     odp_buffer_hdr_t *buf_hdr[] ODP_UNUSED,
 		     int num ODP_UNUSED)
 {
@@ -628,48 +625,49 @@  int pktout_deq_multi(queue_entry_t *qentry ODP_UNUSED,
 	return 0;
 }
 
-int pktin_enqueue(queue_entry_t *qentry ODP_UNUSED,
+int pktin_enqueue(queue_t qentry ODP_UNUSED,
 		  odp_buffer_hdr_t *buf_hdr ODP_UNUSED)
 {
 	ODP_ABORT("attempted enqueue to a pktin queue");
 	return -1;
 }
 
-odp_buffer_hdr_t *pktin_dequeue(queue_entry_t *qentry)
+odp_buffer_hdr_t *pktin_dequeue(queue_t qentry)
 {
 	odp_buffer_hdr_t *buf_hdr;
 	odp_buffer_hdr_t *hdr_tbl[QUEUE_MULTI_MAX];
 	int pkts;
 
-	buf_hdr = queue_deq(qentry);
+	buf_hdr = queue_fn->deq(qentry);
 	if (buf_hdr != NULL)
 		return buf_hdr;
 
-	pkts = pktin_recv_buf(qentry->s.pktin, hdr_tbl, QUEUE_MULTI_MAX);
+	pkts = pktin_recv_buf(queue_fn->get_pktin(qentry),
+			      hdr_tbl, QUEUE_MULTI_MAX);
 
 	if (pkts <= 0)
 		return NULL;
 
 	if (pkts > 1)
-		queue_enq_multi(qentry, &hdr_tbl[1], pkts - 1);
+		queue_fn->enq_multi(qentry, &hdr_tbl[1], pkts - 1);
 	buf_hdr = hdr_tbl[0];
 	return buf_hdr;
 }
 
-int pktin_enq_multi(queue_entry_t *qentry ODP_UNUSED,
+int pktin_enq_multi(queue_t qentry ODP_UNUSED,
 		    odp_buffer_hdr_t *buf_hdr[] ODP_UNUSED, int num ODP_UNUSED)
 {
 	ODP_ABORT("attempted enqueue to a pktin queue");
 	return 0;
 }
 
-int pktin_deq_multi(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr[], int num)
+int pktin_deq_multi(queue_t qentry, odp_buffer_hdr_t *buf_hdr[], int num)
 {
 	int nbr;
 	odp_buffer_hdr_t *hdr_tbl[QUEUE_MULTI_MAX];
 	int pkts, i, j;
 
-	nbr = queue_deq_multi(qentry, buf_hdr, num);
+	nbr = queue_fn->deq_multi(qentry, buf_hdr, num);
 	if (odp_unlikely(nbr > num))
 		ODP_ABORT("queue_deq_multi req: %d, returned %d\n", num, nbr);
 
@@ -679,7 +677,8 @@  int pktin_deq_multi(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr[], int num)
 	if (nbr == num)
 		return nbr;
 
-	pkts = pktin_recv_buf(qentry->s.pktin, hdr_tbl, QUEUE_MULTI_MAX);
+	pkts = pktin_recv_buf(queue_fn->get_pktin(qentry),
+			      hdr_tbl, QUEUE_MULTI_MAX);
 	if (pkts <= 0)
 		return nbr;
 
@@ -691,7 +690,7 @@  int pktin_deq_multi(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr[], int num)
 		hdr_tbl[j] = hdr_tbl[i];
 
 	if (j)
-		queue_enq_multi(qentry, hdr_tbl, j);
+		queue_fn->enq_multi(qentry, hdr_tbl, j);
 	return nbr;
 }
 
@@ -713,7 +712,7 @@  int sched_cb_pktin_poll(int pktio_index, int num_queue, int index[])
 	}
 
 	for (idx = 0; idx < num_queue; idx++) {
-		queue_entry_t *qentry;
+		queue_t qentry;
 		odp_queue_t queue;
 		odp_pktin_queue_t pktin = entry->s.in_queue[index[idx]].pktin;
 
@@ -728,8 +727,8 @@  int sched_cb_pktin_poll(int pktio_index, int num_queue, int index[])
 		}
 
 		queue = entry->s.in_queue[index[idx]].queue;
-		qentry = queue_to_qentry(queue);
-		queue_enq_multi(qentry, hdr_tbl, num);
+		qentry = queue_fn->from_ext(queue);
+		queue_fn->enq_multi(qentry, hdr_tbl, num);
 	}
 
 	return 0;
@@ -1273,16 +1272,16 @@  int odp_pktin_queue_config(odp_pktio_t pktio,
 			}
 
 			if (mode == ODP_PKTIN_MODE_QUEUE) {
-				queue_entry_t *qentry;
-
-				qentry = queue_to_qentry(queue);
-				qentry->s.pktin.index  = i;
-				qentry->s.pktin.pktio  = pktio;
-
-				qentry->s.enqueue = pktin_enqueue;
-				qentry->s.dequeue = pktin_dequeue;
-				qentry->s.enqueue_multi = pktin_enq_multi;
-				qentry->s.dequeue_multi = pktin_deq_multi;
+				queue_t qentry;
+
+				qentry = queue_fn->from_ext(queue);
+				queue_fn->set_pktin(qentry, pktio, i);
+				queue_fn->set_enq_fn(qentry, pktin_enqueue);
+				queue_fn->set_deq_fn(qentry, pktin_dequeue);
+				queue_fn->set_enq_multi_fn(qentry,
+							   pktin_enq_multi);
+				queue_fn->set_deq_multi_fn(qentry,
+							   pktin_deq_multi);
 			}
 
 			entry->s.in_queue[i].queue = queue;
@@ -1379,7 +1378,7 @@  int odp_pktout_queue_config(odp_pktio_t pktio,
 		for (i = 0; i < num_queues; i++) {
 			odp_queue_t queue;
 			odp_queue_param_t queue_param;
-			queue_entry_t *qentry;
+			queue_t qentry;
 			char name[ODP_QUEUE_NAME_LEN];
 			int pktio_id = pktio_to_id(pktio);
 
@@ -1399,15 +1398,14 @@  int odp_pktout_queue_config(odp_pktio_t pktio,
 				return -1;
 			}
 
-			qentry = queue_to_qentry(queue);
-			qentry->s.pktout.index  = i;
-			qentry->s.pktout.pktio  = pktio;
+			qentry = queue_fn->from_ext(queue);
+			queue_fn->set_pktout(qentry, pktio, i);
 
 			/* Override default enqueue / dequeue functions */
-			qentry->s.enqueue       = pktout_enqueue;
-			qentry->s.dequeue       = pktout_dequeue;
-			qentry->s.enqueue_multi = pktout_enq_multi;
-			qentry->s.dequeue_multi = pktout_deq_multi;
+			queue_fn->set_enq_fn(qentry, pktout_enqueue);
+			queue_fn->set_deq_fn(qentry, pktout_dequeue);
+			queue_fn->set_enq_multi_fn(qentry, pktout_enq_multi);
+			queue_fn->set_deq_multi_fn(qentry, pktout_deq_multi);
 
 			entry->s.out_queue[i].queue = queue;
 		}
diff --git a/platform/linux-generic/odp_queue.c b/platform/linux-generic/odp_queue.c
index dd430cd1..bc73728d 100644
--- a/platform/linux-generic/odp_queue.c
+++ b/platform/linux-generic/odp_queue.c
@@ -6,6 +6,7 @@ 
 
 #include <odp/api/queue.h>
 #include <odp_queue_internal.h>
+#include <odp_queue_if.h>
 #include <odp/api/std_types.h>
 #include <odp/api/align.h>
 #include <odp/api/buffer.h>
@@ -40,6 +41,14 @@  typedef struct queue_table_t {
 
 static queue_table_t *queue_tbl;
 
+static int _queue_enq(queue_t handle, odp_buffer_hdr_t *buf_hdr);
+static odp_buffer_hdr_t *_queue_deq(queue_t handle);
+
+static int _queue_enq_multi(queue_t handle, odp_buffer_hdr_t *buf_hdr[],
+			    int num);
+static int _queue_deq_multi(queue_t handle, odp_buffer_hdr_t *buf_hdr[],
+			    int num);
+
 static inline odp_queue_t queue_from_id(uint32_t queue_id)
 {
 	return _odp_cast_scalar(odp_queue_t, queue_id + 1);
@@ -89,10 +98,10 @@  static int queue_init(queue_entry_t *queue, const char *name,
 	}
 	queue->s.type = queue->s.param.type;
 
-	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.enqueue = _queue_enq;
+	queue->s.dequeue = _queue_deq;
+	queue->s.enqueue_multi = _queue_enq_multi;
+	queue->s.dequeue_multi = _queue_deq_multi;
 
 	queue->s.pktin = PKTIN_INVALID;
 	queue->s.pktout = PKTOUT_INVALID;
@@ -104,7 +113,7 @@  static int queue_init(queue_entry_t *queue, const char *name,
 }
 
 
-int odp_queue_init_global(void)
+static int queue_init_global(void)
 {
 	uint32_t i;
 	odp_shm_t shm;
@@ -141,7 +150,17 @@  int odp_queue_init_global(void)
 	return 0;
 }
 
-int odp_queue_term_global(void)
+static int queue_init_local(void)
+{
+	return 0;
+}
+
+static int queue_term_local(void)
+{
+	return 0;
+}
+
+static int queue_term_global(void)
 {
 	int ret = 0;
 	int rc = 0;
@@ -167,7 +186,7 @@  int odp_queue_term_global(void)
 	return rc;
 }
 
-int odp_queue_capability(odp_queue_capability_t *capa)
+static int queue_capability(odp_queue_capability_t *capa)
 {
 	memset(capa, 0, sizeof(odp_queue_capability_t));
 
@@ -182,51 +201,37 @@  int odp_queue_capability(odp_queue_capability_t *capa)
 	return 0;
 }
 
-odp_queue_type_t odp_queue_type(odp_queue_t handle)
+static odp_queue_type_t queue_type(odp_queue_t handle)
 {
-	queue_entry_t *queue;
-
-	queue = queue_to_qentry(handle);
-
-	return queue->s.type;
+	return qentry_from_int(queue_fn->from_ext(handle))->s.type;
 }
 
-odp_schedule_sync_t odp_queue_sched_type(odp_queue_t handle)
+static odp_schedule_sync_t queue_sched_type(odp_queue_t handle)
 {
-	queue_entry_t *queue;
-
-	queue = queue_to_qentry(handle);
-
-	return queue->s.param.sched.sync;
+	return qentry_from_int(queue_fn->from_ext(handle))->s.param.sched.sync;
 }
 
-odp_schedule_prio_t odp_queue_sched_prio(odp_queue_t handle)
+static odp_schedule_prio_t queue_sched_prio(odp_queue_t handle)
 {
-	queue_entry_t *queue;
-
-	queue = queue_to_qentry(handle);
-
-	return queue->s.param.sched.prio;
+	return qentry_from_int(queue_fn->from_ext(handle))->s.param.sched.prio;
 }
 
-odp_schedule_group_t odp_queue_sched_group(odp_queue_t handle)
+static odp_schedule_group_t queue_sched_group(odp_queue_t handle)
 {
-	queue_entry_t *queue;
-
-	queue = queue_to_qentry(handle);
-
-	return queue->s.param.sched.group;
+	return qentry_from_int(queue_fn->from_ext(handle))
+			       ->s.param.sched.group;
 }
 
-int odp_queue_lock_count(odp_queue_t handle)
+static int queue_lock_count(odp_queue_t handle)
 {
-	queue_entry_t *queue = queue_to_qentry(handle);
+	queue_entry_t *queue = qentry_from_int(queue_fn->from_ext(handle));
 
 	return queue->s.param.sched.sync == ODP_SCHED_SYNC_ORDERED ?
 		(int)queue->s.param.sched.lock_count : -1;
 }
 
-odp_queue_t odp_queue_create(const char *name, const odp_queue_param_t *param)
+static odp_queue_t queue_create(const char *name,
+				const odp_queue_param_t *param)
 {
 	uint32_t i;
 	queue_entry_t *queue;
@@ -291,10 +296,10 @@  void sched_cb_queue_destroy_finalize(uint32_t queue_index)
 	UNLOCK(&queue->s.lock);
 }
 
-int odp_queue_destroy(odp_queue_t handle)
+static int queue_destroy(odp_queue_t handle)
 {
 	queue_entry_t *queue;
-	queue = queue_to_qentry(handle);
+	queue = qentry_from_int(queue_fn->from_ext(handle));
 
 	if (handle == ODP_QUEUE_INVALID)
 		return -1;
@@ -343,25 +348,21 @@  int odp_queue_destroy(odp_queue_t handle)
 	return 0;
 }
 
-int odp_queue_context_set(odp_queue_t handle, void *context,
-			  uint32_t len ODP_UNUSED)
+static int queue_context_set(odp_queue_t handle, void *context,
+			     uint32_t len ODP_UNUSED)
 {
-	queue_entry_t *queue;
-	queue = queue_to_qentry(handle);
 	odp_mb_full();
-	queue->s.param.context = context;
+	qentry_from_int(queue_fn->from_ext(handle))->s.param.context = context;
 	odp_mb_full();
 	return 0;
 }
 
-void *odp_queue_context(odp_queue_t handle)
+static void *queue_context(odp_queue_t handle)
 {
-	queue_entry_t *queue;
-	queue = queue_to_qentry(handle);
-	return queue->s.param.context;
+	return qentry_from_int(queue_fn->from_ext(handle))->s.param.context;
 }
 
-odp_queue_t odp_queue_lookup(const char *name)
+static odp_queue_t queue_lookup(const char *name)
 {
 	uint32_t i;
 
@@ -384,15 +385,16 @@  odp_queue_t odp_queue_lookup(const char *name)
 	return ODP_QUEUE_INVALID;
 }
 
-static inline int enq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[],
+static inline int enq_multi(queue_t handle, odp_buffer_hdr_t *buf_hdr[],
 			    int num)
 {
 	int sched = 0;
 	int i, ret;
+	queue_entry_t *queue;
 	odp_buffer_hdr_t *hdr, *tail, *next_hdr;
 
-	if (sched_fn->ord_enq_multi(queue->s.index, (void **)buf_hdr, num,
-			&ret))
+	queue = qentry_from_int(handle);
+	if (sched_fn->ord_enq_multi(handle, (void **)buf_hdr, num, &ret))
 		return ret;
 
 	/* Optimize the common case of single enqueue */
@@ -460,16 +462,17 @@  static inline int enq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[],
 	return num; /* All events enqueued */
 }
 
-int queue_enq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[], int num)
+static int _queue_enq_multi(queue_t handle, odp_buffer_hdr_t *buf_hdr[],
+			    int num)
 {
-	return enq_multi(queue, buf_hdr, num);
+	return enq_multi(handle, buf_hdr, num);
 }
 
-int queue_enq(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr)
+static int _queue_enq(queue_t handle, odp_buffer_hdr_t *buf_hdr)
 {
 	int ret;
 
-	ret = enq_multi(queue, &buf_hdr, 1);
+	ret = enq_multi(handle, &buf_hdr, 1);
 
 	if (ret == 1)
 		return 0;
@@ -477,7 +480,7 @@  int queue_enq(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr)
 		return -1;
 }
 
-int odp_queue_enq_multi(odp_queue_t handle, const odp_event_t ev[], int num)
+static int queue_enq_multi(odp_queue_t handle, const odp_event_t ev[], int num)
 {
 	odp_buffer_hdr_t *buf_hdr[QUEUE_MULTI_MAX];
 	queue_entry_t *queue;
@@ -486,33 +489,35 @@  int odp_queue_enq_multi(odp_queue_t handle, const odp_event_t ev[], int num)
 	if (num > QUEUE_MULTI_MAX)
 		num = QUEUE_MULTI_MAX;
 
-	queue = queue_to_qentry(handle);
+	queue = qentry_from_int(queue_fn->from_ext(handle));
 
 	for (i = 0; i < num; i++)
 		buf_hdr[i] = buf_hdl_to_hdr(odp_buffer_from_event(ev[i]));
 
-	return num == 0 ? 0 : queue->s.enqueue_multi(queue, buf_hdr,
-						     num);
+	return num == 0 ? 0 : queue->s.enqueue_multi(qentry_to_int(queue),
+						     buf_hdr, num);
 }
 
-int odp_queue_enq(odp_queue_t handle, odp_event_t ev)
+static int queue_enq(odp_queue_t handle, odp_event_t ev)
 {
 	odp_buffer_hdr_t *buf_hdr;
 	queue_entry_t *queue;
 
-	queue   = queue_to_qentry(handle);
+	queue   = qentry_from_int(queue_fn->from_ext(handle));
 	buf_hdr = buf_hdl_to_hdr(odp_buffer_from_event(ev));
 
-	return queue->s.enqueue(queue, buf_hdr);
+	return queue->s.enqueue(qentry_to_int(queue), buf_hdr);
 }
 
-static inline int deq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[],
+static inline int deq_multi(queue_t handle, odp_buffer_hdr_t *buf_hdr[],
 			    int num)
 {
 	odp_buffer_hdr_t *hdr, *next;
 	int i, j;
+	queue_entry_t *queue;
 	int updated = 0;
 
+	queue = qentry_from_int(handle);
 	LOCK(&queue->s.lock);
 	if (odp_unlikely(queue->s.status < QUEUE_STATUS_READY)) {
 		/* Bad queue, or queue has been destroyed.
@@ -578,17 +583,18 @@  static inline int deq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[],
 	return i;
 }
 
-int queue_deq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[], int num)
+static int _queue_deq_multi(queue_t handle, odp_buffer_hdr_t *buf_hdr[],
+			    int num)
 {
-	return deq_multi(queue, buf_hdr, num);
+	return deq_multi(handle, buf_hdr, num);
 }
 
-odp_buffer_hdr_t *queue_deq(queue_entry_t *queue)
+static odp_buffer_hdr_t *_queue_deq(queue_t handle)
 {
 	odp_buffer_hdr_t *buf_hdr = NULL;
 	int ret;
 
-	ret = deq_multi(queue, &buf_hdr, 1);
+	ret = deq_multi(handle, &buf_hdr, 1);
 
 	if (ret == 1)
 		return buf_hdr;
@@ -596,7 +602,7 @@  odp_buffer_hdr_t *queue_deq(queue_entry_t *queue)
 		return NULL;
 }
 
-int odp_queue_deq_multi(odp_queue_t handle, odp_event_t events[], int num)
+static int queue_deq_multi(odp_queue_t handle, odp_event_t events[], int num)
 {
 	queue_entry_t *queue;
 	odp_buffer_hdr_t *buf_hdr[QUEUE_MULTI_MAX];
@@ -605,9 +611,9 @@  int odp_queue_deq_multi(odp_queue_t handle, odp_event_t events[], int num)
 	if (num > QUEUE_MULTI_MAX)
 		num = QUEUE_MULTI_MAX;
 
-	queue = queue_to_qentry(handle);
+	queue = qentry_from_int(queue_fn->from_ext(handle));
 
-	ret = queue->s.dequeue_multi(queue, buf_hdr, num);
+	ret = queue->s.dequeue_multi(qentry_to_int(queue), buf_hdr, num);
 
 	for (i = 0; i < ret; i++)
 		events[i] = odp_buffer_to_event(buf_hdr[i]->handle.handle);
@@ -616,13 +622,13 @@  int odp_queue_deq_multi(odp_queue_t handle, odp_event_t events[], int num)
 }
 
 
-odp_event_t odp_queue_deq(odp_queue_t handle)
+static odp_event_t queue_deq(odp_queue_t handle)
 {
 	queue_entry_t *queue;
 	odp_buffer_hdr_t *buf_hdr;
 
-	queue   = queue_to_qentry(handle);
-	buf_hdr = queue->s.dequeue(queue);
+	queue   = qentry_from_int(queue_fn->from_ext(handle));
+	buf_hdr = queue->s.dequeue(qentry_to_int(queue));
 
 	if (buf_hdr)
 		return odp_buffer_to_event(buf_hdr->handle.handle);
@@ -640,7 +646,7 @@  void queue_unlock(queue_entry_t *queue)
 	UNLOCK(&queue->s.lock);
 }
 
-void odp_queue_param_init(odp_queue_param_t *params)
+static void queue_param_init(odp_queue_param_t *params)
 {
 	memset(params, 0, sizeof(odp_queue_param_t));
 	params->type = ODP_QUEUE_TYPE_PLAIN;
@@ -651,7 +657,7 @@  void odp_queue_param_init(odp_queue_param_t *params)
 	params->sched.group = ODP_SCHED_GROUP_ALL;
 }
 
-int odp_queue_info(odp_queue_t handle, odp_queue_info_t *info)
+static int queue_info(odp_queue_t handle, odp_queue_info_t *info)
 {
 	uint32_t queue_id;
 	queue_entry_t *queue;
@@ -730,7 +736,7 @@  int sched_cb_queue_deq_multi(uint32_t queue_index, odp_event_t ev[], int num)
 	queue_entry_t *qe = get_qentry(queue_index);
 	odp_buffer_hdr_t *buf_hdr[num];
 
-	ret = deq_multi(qe, buf_hdr, num);
+	ret = deq_multi(qentry_to_int(qe), buf_hdr, num);
 
 	if (ret > 0)
 		for (i = 0; i < ret; i++)
@@ -765,7 +771,112 @@  int sched_cb_queue_empty(uint32_t queue_index)
 	return ret;
 }
 
-uint64_t odp_queue_to_u64(odp_queue_t hdl)
+static uint64_t queue_to_u64(odp_queue_t hdl)
 {
 	return _odp_pri(hdl);
 }
+
+static odp_pktout_queue_t queue_get_pktout(queue_t handle)
+{
+	return qentry_from_int(handle)->s.pktout;
+}
+
+static void queue_set_pktout(queue_t handle, odp_pktio_t pktio, int index)
+{
+	qentry_from_int(handle)->s.pktout.pktio = pktio;
+	qentry_from_int(handle)->s.pktout.index = index;
+}
+
+static odp_pktin_queue_t queue_get_pktin(queue_t handle)
+{
+	return qentry_from_int(handle)->s.pktin;
+}
+
+static void queue_set_pktin(queue_t handle, odp_pktio_t pktio, int index)
+{
+	qentry_from_int(handle)->s.pktin.pktio = pktio;
+	qentry_from_int(handle)->s.pktin.index = index;
+}
+
+static void queue_set_enq_func(queue_t handle, queue_enq_fn_t func)
+{
+	qentry_from_int(handle)->s.enqueue = func;
+}
+
+static void queue_set_enq_multi_func(queue_t handle, queue_enq_multi_fn_t func)
+{
+	qentry_from_int(handle)->s.enqueue_multi = func;
+}
+
+static void queue_set_deq_func(queue_t handle, queue_deq_fn_t func)
+{
+	qentry_from_int(handle)->s.dequeue = func;
+}
+
+static void queue_set_deq_multi_func(queue_t handle, queue_deq_multi_fn_t func)
+{
+	qentry_from_int(handle)->s.dequeue_multi = func;
+}
+
+static void queue_set_type(queue_t handle, odp_queue_type_t type)
+{
+	qentry_from_int(handle)->s.type = type;
+}
+
+static queue_t queue_from_ext(odp_queue_t handle)
+{
+	uint32_t queue_id;
+
+	queue_id = queue_to_id(handle);
+	return qentry_to_int(get_qentry(queue_id));
+}
+
+static odp_queue_t queue_to_ext(queue_t handle)
+{
+	return qentry_from_int(handle)->s.handle;
+}
+
+/* API functions */
+queue_api_t queue_default_api = {
+	.queue_create = queue_create,
+	.queue_destroy = queue_destroy,
+	.queue_lookup = queue_lookup,
+	.queue_capability = queue_capability,
+	.queue_context_set = queue_context_set,
+	.queue_context = queue_context,
+	.queue_enq = queue_enq,
+	.queue_enq_multi = queue_enq_multi,
+	.queue_deq = queue_deq,
+	.queue_deq_multi = queue_deq_multi,
+	.queue_type = queue_type,
+	.queue_sched_type = queue_sched_type,
+	.queue_sched_prio = queue_sched_prio,
+	.queue_sched_group = queue_sched_group,
+	.queue_lock_count = queue_lock_count,
+	.queue_to_u64 = queue_to_u64,
+	.queue_param_init = queue_param_init,
+	.queue_info = queue_info
+};
+
+/* Functions towards internal components */
+queue_fn_t queue_default_fn = {
+	.init_global = queue_init_global,
+	.term_global = queue_term_global,
+	.init_local = queue_init_local,
+	.term_local = queue_term_local,
+	.from_ext = queue_from_ext,
+	.to_ext = queue_to_ext,
+	.enq = _queue_enq,
+	.enq_multi = _queue_enq_multi,
+	.deq = _queue_deq,
+	.deq_multi = _queue_deq_multi,
+	.get_pktout = queue_get_pktout,
+	.set_pktout = queue_set_pktout,
+	.get_pktin = queue_get_pktin,
+	.set_pktin = queue_set_pktin,
+	.set_enq_fn = queue_set_enq_func,
+	.set_enq_multi_fn = queue_set_enq_multi_func,
+	.set_deq_fn = queue_set_deq_func,
+	.set_deq_multi_fn = queue_set_deq_multi_func,
+	.set_type = queue_set_type
+};
diff --git a/platform/linux-generic/odp_queue_if.c b/platform/linux-generic/odp_queue_if.c
new file mode 100644
index 00000000..5a4f7194
--- /dev/null
+++ b/platform/linux-generic/odp_queue_if.c
@@ -0,0 +1,103 @@ 
+/* Copyright (c) 2016, ARM Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:     BSD-3-Clause
+ */
+
+#include <odp_queue_if.h>
+
+extern const queue_api_t queue_default_api;
+extern const queue_fn_t queue_default_fn;
+
+const queue_api_t *queue_api = &queue_default_api;
+const queue_fn_t *queue_fn = &queue_default_fn;
+
+odp_queue_t odp_queue_create(const char *name, const odp_queue_param_t *param)
+{
+	return queue_api->queue_create(name, param);
+}
+
+int odp_queue_destroy(odp_queue_t queue)
+{
+	return queue_api->queue_destroy(queue);
+}
+
+odp_queue_t odp_queue_lookup(const char *name)
+{
+	return queue_api->queue_lookup(name);
+}
+
+int odp_queue_capability(odp_queue_capability_t *capa)
+{
+	return queue_api->queue_capability(capa);
+}
+
+int odp_queue_context_set(odp_queue_t queue, void *context, uint32_t len)
+{
+	return queue_api->queue_context_set(queue, context, len);
+}
+
+void *odp_queue_context(odp_queue_t queue)
+{
+	return queue_api->queue_context(queue);
+}
+
+int odp_queue_enq(odp_queue_t queue, odp_event_t ev)
+{
+	return queue_api->queue_enq(queue, ev);
+}
+
+int odp_queue_enq_multi(odp_queue_t queue, const odp_event_t events[], int num)
+{
+	return queue_api->queue_enq_multi(queue, events, num);
+}
+
+odp_event_t odp_queue_deq(odp_queue_t queue)
+{
+	return queue_api->queue_deq(queue);
+}
+
+int odp_queue_deq_multi(odp_queue_t queue, odp_event_t events[], int num)
+{
+	return queue_api->queue_deq_multi(queue, events, num);
+}
+
+odp_queue_type_t odp_queue_type(odp_queue_t queue)
+{
+	return queue_api->queue_type(queue);
+}
+
+odp_schedule_sync_t odp_queue_sched_type(odp_queue_t queue)
+{
+	return queue_api->queue_sched_type(queue);
+}
+
+odp_schedule_prio_t odp_queue_sched_prio(odp_queue_t queue)
+{
+	return queue_api->queue_sched_prio(queue);
+}
+
+odp_schedule_group_t odp_queue_sched_group(odp_queue_t queue)
+{
+	return queue_api->queue_sched_group(queue);
+}
+
+int odp_queue_lock_count(odp_queue_t queue)
+{
+	return queue_api->queue_lock_count(queue);
+}
+
+uint64_t odp_queue_to_u64(odp_queue_t hdl)
+{
+	return queue_api->queue_to_u64(hdl);
+}
+
+void odp_queue_param_init(odp_queue_param_t *param)
+{
+	return queue_api->queue_param_init(param);
+}
+
+int odp_queue_info(odp_queue_t queue, odp_queue_info_t *info)
+{
+	return queue_api->queue_info(queue, info);
+}
diff --git a/platform/linux-generic/odp_schedule.c b/platform/linux-generic/odp_schedule.c
index c4567d81..011d4dc4 100644
--- a/platform/linux-generic/odp_schedule.c
+++ b/platform/linux-generic/odp_schedule.c
@@ -646,7 +646,7 @@  static inline void ordered_stash_release(void)
 		buf_hdr = sched_local.ordered.stash[i].buf_hdr;
 		num = sched_local.ordered.stash[i].num;
 
-		queue_enq_multi(queue, buf_hdr, num);
+		queue_fn->enq_multi(qentry_to_int(queue), buf_hdr, num);
 	}
 	sched_local.ordered.stash_num = 0;
 }
@@ -712,12 +712,12 @@  static inline int copy_events(odp_event_t out_ev[], unsigned int max)
 	return i;
 }
 
-static int schedule_ord_enq_multi(uint32_t queue_index, void *buf_hdr[],
+static int schedule_ord_enq_multi(queue_t handle, void *buf_hdr[],
 				  int num, int *ret)
 {
 	int i;
 	uint32_t stash_num = sched_local.ordered.stash_num;
-	queue_entry_t *dst_queue = get_qentry(queue_index);
+	queue_entry_t *dst_queue = qentry_from_int(handle);
 	queue_entry_t *src_queue = sched_local.ordered.src_queue;
 
 	if (!sched_local.ordered.src_queue || sched_local.ordered.in_order)
diff --git a/platform/linux-generic/odp_schedule_iquery.c b/platform/linux-generic/odp_schedule_iquery.c
index 75470aff..bdf1a460 100644
--- a/platform/linux-generic/odp_schedule_iquery.c
+++ b/platform/linux-generic/odp_schedule_iquery.c
@@ -1108,7 +1108,7 @@  static inline void ordered_stash_release(void)
 		buf_hdr = thread_local.ordered.stash[i].buf_hdr;
 		num = thread_local.ordered.stash[i].num;
 
-		queue_enq_multi(queue, buf_hdr, num);
+		queue_fn->enq_multi(qentry_to_int(queue), buf_hdr, num);
 	}
 	thread_local.ordered.stash_num = 0;
 }
@@ -1159,12 +1159,12 @@  static inline void schedule_release_context(void)
 		schedule_release_atomic();
 }
 
-static int schedule_ord_enq_multi(uint32_t queue_index, void *buf_hdr[],
+static int schedule_ord_enq_multi(queue_t handle, void *buf_hdr[],
 				  int num, int *ret)
 {
 	int i;
 	uint32_t stash_num = thread_local.ordered.stash_num;
-	queue_entry_t *dst_queue = get_qentry(queue_index);
+	queue_entry_t *dst_queue = qentry_from_int(handle);
 	queue_entry_t *src_queue = thread_local.ordered.src_queue;
 
 	if (!thread_local.ordered.src_queue || thread_local.ordered.in_order)
diff --git a/platform/linux-generic/odp_schedule_sp.c b/platform/linux-generic/odp_schedule_sp.c
index 0fd4d87d..91d70e3a 100644
--- a/platform/linux-generic/odp_schedule_sp.c
+++ b/platform/linux-generic/odp_schedule_sp.c
@@ -414,10 +414,10 @@  static int unsched_queue(uint32_t qi ODP_UNUSED)
 	return 0;
 }
 
-static int ord_enq_multi(uint32_t queue_index, void *buf_hdr[], int num,
+static int ord_enq_multi(queue_t handle, void *buf_hdr[], int num,
 			 int *ret)
 {
-	(void)queue_index;
+	(void)handle;
 	(void)buf_hdr;
 	(void)num;
 	(void)ret;
diff --git a/platform/linux-generic/odp_traffic_mngr.c b/platform/linux-generic/odp_traffic_mngr.c
index a93b3ba9..8b5f3187 100644
--- a/platform/linux-generic/odp_traffic_mngr.c
+++ b/platform/linux-generic/odp_traffic_mngr.c
@@ -102,7 +102,7 @@  static odp_bool_t tm_demote_pkt_desc(tm_system_t *tm_system,
 				     tm_shaper_obj_t *timer_shaper,
 				     pkt_desc_t *demoted_pkt_desc);
 
-static int queue_tm_reenq(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr)
+static int queue_tm_reenq(queue_t queue, odp_buffer_hdr_t *buf_hdr)
 {
 	odp_tm_queue_t tm_queue = MAKE_ODP_TM_QUEUE((uint8_t *)queue -
 						    offsetof(tm_queue_obj_t,
@@ -112,7 +112,7 @@  static int queue_tm_reenq(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr)
 	return odp_tm_enq(tm_queue, pkt);
 }
 
-static int queue_tm_reenq_multi(queue_entry_t *queue ODP_UNUSED,
+static int queue_tm_reenq_multi(queue_t queue ODP_UNUSED,
 				odp_buffer_hdr_t *buf[] ODP_UNUSED,
 				int num ODP_UNUSED)
 {
@@ -3882,6 +3882,7 @@  odp_tm_queue_t odp_tm_queue_create(odp_tm_t odp_tm,
 	tm_queue_obj_t *tm_queue_obj;
 	tm_wred_node_t *tm_wred_node;
 	odp_tm_queue_t odp_tm_queue;
+	odp_queue_t queue;
 	odp_tm_wred_t wred_profile;
 	tm_system_t *tm_system;
 	uint32_t color;
@@ -3918,9 +3919,17 @@  odp_tm_queue_t odp_tm_queue_create(odp_tm_t odp_tm,
 	tm_queue_obj->pkt = ODP_PACKET_INVALID;
 	odp_ticketlock_init(&tm_wred_node->tm_wred_node_lock);
 
-	tm_queue_obj->tm_qentry.s.type = QUEUE_TYPE_TM;
-	tm_queue_obj->tm_qentry.s.enqueue = queue_tm_reenq;
-	tm_queue_obj->tm_qentry.s.enqueue_multi = queue_tm_reenq_multi;
+	queue = odp_queue_create(NULL, NULL);
+	if (queue == ODP_QUEUE_INVALID) {
+		free(tm_wred_node);
+		free(tm_queue_obj);
+		return ODP_TM_INVALID;
+	}
+	tm_queue_obj->tm_qentry = queue_fn->from_ext(queue);
+	queue_fn->set_type(tm_queue_obj->tm_qentry, QUEUE_TYPE_TM);
+	queue_fn->set_enq_fn(tm_queue_obj->tm_qentry, queue_tm_reenq);
+	queue_fn->set_enq_multi_fn(tm_queue_obj->tm_qentry,
+				   queue_tm_reenq_multi);
 
 	tm_system->queue_num_tbl[tm_queue_obj->queue_num - 1] = tm_queue_obj;
 	odp_ticketlock_lock(&tm_system->tm_system_lock);
@@ -3992,6 +4001,8 @@  int odp_tm_queue_destroy(odp_tm_queue_t tm_queue)
 	odp_ticketlock_lock(&tm_system->tm_system_lock);
 	tm_system->queue_num_tbl[tm_queue_obj->queue_num - 1] = NULL;
 
+	odp_queue_destroy(queue_fn->to_ext(tm_queue_obj->tm_qentry));
+
 	/* First delete any associated tm_wred_node and then the tm_queue_obj
 	 * itself */
 	free(tm_queue_obj->tm_wred_node);
diff --git a/platform/linux-generic/pktio/loop.c b/platform/linux-generic/pktio/loop.c
index e9ad22ba..c95a44be 100644
--- a/platform/linux-generic/pktio/loop.c
+++ b/platform/linux-generic/pktio/loop.c
@@ -11,6 +11,7 @@ 
 #include <odp_classification_internal.h>
 #include <odp_debug_internal.h>
 #include <odp/api/hints.h>
+#include <odp_queue_if.h>
 
 #include <protocols/eth.h>
 #include <protocols/ip.h>
@@ -55,7 +56,7 @@  static int loopback_recv(pktio_entry_t *pktio_entry, int index ODP_UNUSED,
 {
 	int nbr, i;
 	odp_buffer_hdr_t *hdr_tbl[QUEUE_MULTI_MAX];
-	queue_entry_t *qentry;
+	queue_t queue;
 	odp_packet_hdr_t *pkt_hdr;
 	odp_packet_hdr_t parsed_hdr;
 	odp_packet_t pkt;
@@ -69,8 +70,8 @@  static int loopback_recv(pktio_entry_t *pktio_entry, int index ODP_UNUSED,
 
 	odp_ticketlock_lock(&pktio_entry->s.rxl);
 
-	qentry = queue_to_qentry(pktio_entry->s.pkt_loop.loopq);
-	nbr = queue_deq_multi(qentry, hdr_tbl, len);
+	queue = queue_fn->from_ext(pktio_entry->s.pkt_loop.loopq);
+	nbr = queue_fn->deq_multi(queue, hdr_tbl, len);
 
 	if (pktio_entry->s.config.pktin.bit.ts_all ||
 	    pktio_entry->s.config.pktin.bit.ts_ptp) {
@@ -154,7 +155,7 @@  static int loopback_send(pktio_entry_t *pktio_entry, int index ODP_UNUSED,
 			 const odp_packet_t pkt_tbl[], int len)
 {
 	odp_buffer_hdr_t *hdr_tbl[QUEUE_MULTI_MAX];
-	queue_entry_t *qentry;
+	queue_t queue;
 	int i;
 	int ret;
 	uint32_t bytes = 0;
@@ -169,8 +170,8 @@  static int loopback_send(pktio_entry_t *pktio_entry, int index ODP_UNUSED,
 
 	odp_ticketlock_lock(&pktio_entry->s.txl);
 
-	qentry = queue_to_qentry(pktio_entry->s.pkt_loop.loopq);
-	ret = queue_enq_multi(qentry, hdr_tbl, len);
+	queue = queue_fn->from_ext(pktio_entry->s.pkt_loop.loopq);
+	ret = queue_fn->enq_multi(queue, hdr_tbl, len);
 
 	if (ret > 0) {
 		pktio_entry->s.stats.out_ucast_pkts += ret;