diff mbox

[v2,1/3] Shared memory handle

Message ID 1411469133-5211-1-git-send-email-petri.savolainen@linaro.org
State Accepted
Commit ddfeadfe61c2913ca44dd424a118d5e8c7b9b3d3
Headers show

Commit Message

Petri Savolainen Sept. 23, 2014, 10:45 a.m. UTC
- Changed API to return shm handle instead of pointer
- Added shm info
- Tests updated to use shm handle and new addr function.

Signed-off-by: Petri Savolainen <petri.savolainen@linaro.org>
---
 example/generator/odp_generator.c                  |  13 ++-
 example/ipsec/odp_ipsec.c                          |  32 ++++--
 example/ipsec/odp_ipsec_cache.c                    |  13 ++-
 example/ipsec/odp_ipsec_fwd_db.c                   |  13 ++-
 example/ipsec/odp_ipsec_loop_db.c                  |  12 +-
 example/ipsec/odp_ipsec_sa_db.c                    |  13 ++-
 example/ipsec/odp_ipsec_sp_db.c                    |  13 ++-
 example/ipsec/odp_ipsec_stream.c                   |  13 ++-
 example/l2fwd/odp_l2fwd.c                          |  13 ++-
 example/odp_example/odp_example.c                  |  12 +-
 example/packet/odp_pktio.c                         |  13 ++-
 example/timer/odp_timer_test.c                     |   6 +-
 .../linux-generic/include/api/odp_shared_memory.h  |  48 +++++++-
 platform/linux-generic/odp_buffer_pool.c           |   9 +-
 platform/linux-generic/odp_crypto.c                |   7 +-
 platform/linux-generic/odp_packet_io.c             |   9 +-
 platform/linux-generic/odp_queue.c                 |   9 +-
 platform/linux-generic/odp_ring.c                  |   5 +-
 platform/linux-generic/odp_schedule.c              |  15 ++-
 platform/linux-generic/odp_shared_memory.c         | 124 +++++++++++++++------
 test/api_test/odp_shm_test.c                       |  10 +-
 test/api_test/odp_timer_ping.c                     |   6 +-
 22 files changed, 296 insertions(+), 112 deletions(-)

Comments

Maxim Uvarov Sept. 23, 2014, 4:21 p.m. UTC | #1
Merged, and did compilation check for dpdk and ks2.

Maxim.

On 09/23/2014 02:45 PM, Petri Savolainen wrote:
> - Changed API to return shm handle instead of pointer
> - Added shm info
> - Tests updated to use shm handle and new addr function.
>
> Signed-off-by: Petri Savolainen <petri.savolainen@linaro.org>
> ---
>   example/generator/odp_generator.c                  |  13 ++-
>   example/ipsec/odp_ipsec.c                          |  32 ++++--
>   example/ipsec/odp_ipsec_cache.c                    |  13 ++-
>   example/ipsec/odp_ipsec_fwd_db.c                   |  13 ++-
>   example/ipsec/odp_ipsec_loop_db.c                  |  12 +-
>   example/ipsec/odp_ipsec_sa_db.c                    |  13 ++-
>   example/ipsec/odp_ipsec_sp_db.c                    |  13 ++-
>   example/ipsec/odp_ipsec_stream.c                   |  13 ++-
>   example/l2fwd/odp_l2fwd.c                          |  13 ++-
>   example/odp_example/odp_example.c                  |  12 +-
>   example/packet/odp_pktio.c                         |  13 ++-
>   example/timer/odp_timer_test.c                     |   6 +-
>   .../linux-generic/include/api/odp_shared_memory.h  |  48 +++++++-
>   platform/linux-generic/odp_buffer_pool.c           |   9 +-
>   platform/linux-generic/odp_crypto.c                |   7 +-
>   platform/linux-generic/odp_packet_io.c             |   9 +-
>   platform/linux-generic/odp_queue.c                 |   9 +-
>   platform/linux-generic/odp_ring.c                  |   5 +-
>   platform/linux-generic/odp_schedule.c              |  15 ++-
>   platform/linux-generic/odp_shared_memory.c         | 124 +++++++++++++++------
>   test/api_test/odp_shm_test.c                       |  10 +-
>   test/api_test/odp_timer_ping.c                     |   6 +-
>   22 files changed, 296 insertions(+), 112 deletions(-)
>
> diff --git a/example/generator/odp_generator.c b/example/generator/odp_generator.c
> index 10c7b31..27fc868 100644
> --- a/example/generator/odp_generator.c
> +++ b/example/generator/odp_generator.c
> @@ -523,6 +523,7 @@ int main(int argc, char *argv[])
>   	int i;
>   	int first_core;
>   	int core_count;
> +	odp_shm_t shm;
>   
>   	/* Init ODP before calling anything else */
>   	if (odp_init_global()) {
> @@ -537,8 +538,10 @@ int main(int argc, char *argv[])
>   	odp_atomic_init_u64(&counters.icmp);
>   
>   	/* Reserve memory for args from shared mem */
> -	args = odp_shm_reserve("shm_args", sizeof(args_t),
> -			       ODP_CACHE_LINE_SIZE, 0);
> +	shm = odp_shm_reserve("shm_args", sizeof(args_t),
> +			      ODP_CACHE_LINE_SIZE, 0);
> +	args = odp_shm_addr(shm);
> +
>   	if (args == NULL) {
>   		ODP_ERR("Error: shared mem alloc failed.\n");
>   		exit(EXIT_FAILURE);
> @@ -582,8 +585,10 @@ int main(int argc, char *argv[])
>   	odp_init_local(thr_id);
>   
>   	/* Create packet pool */
> -	pool_base = odp_shm_reserve("shm_packet_pool",
> -				    SHM_PKT_POOL_SIZE, ODP_CACHE_LINE_SIZE, 0);
> +	shm = odp_shm_reserve("shm_packet_pool",
> +			      SHM_PKT_POOL_SIZE, ODP_CACHE_LINE_SIZE, 0);
> +	pool_base = odp_shm_addr(shm);
> +
>   	if (pool_base == NULL) {
>   		ODP_ERR("Error: packet pool mem alloc failed.\n");
>   		exit(EXIT_FAILURE);
> diff --git a/example/ipsec/odp_ipsec.c b/example/ipsec/odp_ipsec.c
> index 5b7abf6..a9bba24 100644
> --- a/example/ipsec/odp_ipsec.c
> +++ b/example/ipsec/odp_ipsec.c
> @@ -368,6 +368,7 @@ void ipsec_init_pre(void)
>   {
>   	odp_queue_param_t qparam;
>   	void *pool_base;
> +	odp_shm_t shm;
>   
>   	/*
>   	 * Create queues
> @@ -400,9 +401,10 @@ void ipsec_init_pre(void)
>   	}
>   
>   	/* Create output buffer pool */
> -	pool_base = odp_shm_reserve("shm_out_pool",
> -				    SHM_OUT_POOL_SIZE, ODP_CACHE_LINE_SIZE,
> -				    0);
> +	shm = odp_shm_reserve("shm_out_pool",
> +			      SHM_OUT_POOL_SIZE, ODP_CACHE_LINE_SIZE, 0);
> +
> +	pool_base = odp_shm_addr(shm);
>   
>   	out_pool = odp_buffer_pool_create("out_pool", pool_base,
>   					  SHM_OUT_POOL_SIZE,
> @@ -1179,6 +1181,7 @@ main(int argc, char *argv[])
>   	int first_core;
>   	int core_count;
>   	int stream_count;
> +	odp_shm_t shm;
>   
>   	/* Init ODP before calling anything else */
>   	if (odp_init_global()) {
> @@ -1191,8 +1194,11 @@ main(int argc, char *argv[])
>   	odp_init_local(thr_id);
>   
>   	/* Reserve memory for args from shared mem */
> -	args = odp_shm_reserve("shm_args", sizeof(args_t), ODP_CACHE_LINE_SIZE,
> -			       0);
> +	shm = odp_shm_reserve("shm_args", sizeof(args_t), ODP_CACHE_LINE_SIZE,
> +			      0);
> +
> +	args = odp_shm_addr(shm);
> +
>   	if (NULL == args) {
>   		ODP_ERR("Error: shared mem alloc failed.\n");
>   		exit(EXIT_FAILURE);
> @@ -1233,9 +1239,11 @@ main(int argc, char *argv[])
>   	printf("First core:         %i\n\n", first_core);
>   
>   	/* Create packet buffer pool */
> -	pool_base = odp_shm_reserve("shm_packet_pool",
> -				    SHM_PKT_POOL_SIZE, ODP_CACHE_LINE_SIZE,
> -				    0);
> +	shm = odp_shm_reserve("shm_packet_pool",
> +			      SHM_PKT_POOL_SIZE, ODP_CACHE_LINE_SIZE, 0);
> +
> +	pool_base = odp_shm_addr(shm);
> +
>   	if (NULL == pool_base) {
>   		ODP_ERR("Error: packet pool mem alloc failed.\n");
>   		exit(EXIT_FAILURE);
> @@ -1252,9 +1260,11 @@ main(int argc, char *argv[])
>   	}
>   
>   	/* Create context buffer pool */
> -	pool_base = odp_shm_reserve("shm_ctx_pool",
> -				    SHM_CTX_POOL_SIZE, ODP_CACHE_LINE_SIZE,
> -				    0);
> +	shm = odp_shm_reserve("shm_ctx_pool",
> +			      SHM_CTX_POOL_SIZE, ODP_CACHE_LINE_SIZE, 0);
> +
> +	pool_base = odp_shm_addr(shm);
> +
>   	if (NULL == pool_base) {
>   		ODP_ERR("Error: context pool mem alloc failed.\n");
>   		exit(EXIT_FAILURE);
> diff --git a/example/ipsec/odp_ipsec_cache.c b/example/ipsec/odp_ipsec_cache.c
> index 1b99218..01650d0 100644
> --- a/example/ipsec/odp_ipsec_cache.c
> +++ b/example/ipsec/odp_ipsec_cache.c
> @@ -19,10 +19,15 @@ ipsec_cache_t *ipsec_cache;
>   
>   void init_ipsec_cache(void)
>   {
> -	ipsec_cache = odp_shm_reserve("shm_ipsec_cache",
> -				      sizeof(ipsec_cache_t),
> -				      ODP_CACHE_LINE_SIZE,
> -				      0);
> +	odp_shm_t shm;
> +
> +	shm = odp_shm_reserve("shm_ipsec_cache",
> +			      sizeof(ipsec_cache_t),
> +			      ODP_CACHE_LINE_SIZE,
> +			      0);
> +
> +	ipsec_cache = odp_shm_addr(shm);
> +
>   	if (ipsec_cache == NULL) {
>   		ODP_ERR("Error: shared mem alloc failed.\n");
>   		exit(EXIT_FAILURE);
> diff --git a/example/ipsec/odp_ipsec_fwd_db.c b/example/ipsec/odp_ipsec_fwd_db.c
> index de2e43e..9ed5d00 100644
> --- a/example/ipsec/odp_ipsec_fwd_db.c
> +++ b/example/ipsec/odp_ipsec_fwd_db.c
> @@ -18,10 +18,15 @@ fwd_db_t *fwd_db;
>   
>   void init_fwd_db(void)
>   {
> -	fwd_db = odp_shm_reserve("shm_fwd_db",
> -				 sizeof(fwd_db_t),
> -				 ODP_CACHE_LINE_SIZE,
> -				 0);
> +	odp_shm_t shm;
> +
> +	shm = odp_shm_reserve("shm_fwd_db",
> +			      sizeof(fwd_db_t),
> +			      ODP_CACHE_LINE_SIZE,
> +			      0);
> +
> +	fwd_db = odp_shm_addr(shm);
> +
>   	if (fwd_db == NULL) {
>   		ODP_ERR("Error: shared mem alloc failed.\n");
>   		exit(EXIT_FAILURE);
> diff --git a/example/ipsec/odp_ipsec_loop_db.c b/example/ipsec/odp_ipsec_loop_db.c
> index 222ccb9..f773352 100644
> --- a/example/ipsec/odp_ipsec_loop_db.c
> +++ b/example/ipsec/odp_ipsec_loop_db.c
> @@ -18,11 +18,15 @@ loopback_db_t *loopback_db;
>   void init_loopback_db(void)
>   {
>   	int idx;
> +	odp_shm_t shm;
> +
> +	shm = odp_shm_reserve("loopback_db",
> +			      sizeof(loopback_db_t),
> +			      ODP_CACHE_LINE_SIZE,
> +			      0);
> +
> +	loopback_db = odp_shm_addr(shm);
>   
> -	loopback_db = odp_shm_reserve("loopback_db",
> -				      sizeof(loopback_db_t),
> -				      ODP_CACHE_LINE_SIZE,
> -				      0);
>   	if (loopback_db == NULL) {
>   		ODP_ERR("Error: shared mem alloc failed.\n");
>   		exit(EXIT_FAILURE);
> diff --git a/example/ipsec/odp_ipsec_sa_db.c b/example/ipsec/odp_ipsec_sa_db.c
> index 612da86..f6da623 100644
> --- a/example/ipsec/odp_ipsec_sa_db.c
> +++ b/example/ipsec/odp_ipsec_sa_db.c
> @@ -18,10 +18,15 @@ static sa_db_t *sa_db;
>   
>   void init_sa_db(void)
>   {
> -	sa_db = odp_shm_reserve("shm_sa_db",
> -				sizeof(sa_db_t),
> -				ODP_CACHE_LINE_SIZE,
> -				0);
> +	odp_shm_t shm;
> +
> +	shm = odp_shm_reserve("shm_sa_db",
> +			      sizeof(sa_db_t),
> +			      ODP_CACHE_LINE_SIZE,
> +			      0);
> +
> +	sa_db = odp_shm_addr(shm);
> +
>   	if (sa_db == NULL) {
>   		ODP_ERR("Error: shared mem alloc failed.\n");
>   		exit(EXIT_FAILURE);
> diff --git a/example/ipsec/odp_ipsec_sp_db.c b/example/ipsec/odp_ipsec_sp_db.c
> index 7d9bba1..f288dfe 100644
> --- a/example/ipsec/odp_ipsec_sp_db.c
> +++ b/example/ipsec/odp_ipsec_sp_db.c
> @@ -18,10 +18,15 @@ sp_db_t *sp_db;
>   
>   void init_sp_db(void)
>   {
> -	sp_db = odp_shm_reserve("shm_sp_db",
> -				sizeof(sp_db_t),
> -				ODP_CACHE_LINE_SIZE,
> -				0);
> +	odp_shm_t shm;
> +
> +	shm = odp_shm_reserve("shm_sp_db",
> +			      sizeof(sp_db_t),
> +			      ODP_CACHE_LINE_SIZE,
> +			      0);
> +
> +	sp_db = odp_shm_addr(shm);
> +
>   	if (sp_db == NULL) {
>   		ODP_ERR("Error: shared mem alloc failed.\n");
>   		exit(EXIT_FAILURE);
> diff --git a/example/ipsec/odp_ipsec_stream.c b/example/ipsec/odp_ipsec_stream.c
> index ced055a..de8305a 100644
> --- a/example/ipsec/odp_ipsec_stream.c
> +++ b/example/ipsec/odp_ipsec_stream.c
> @@ -48,10 +48,15 @@ stream_db_t *stream_db;
>   
>   void init_stream_db(void)
>   {
> -	stream_db = odp_shm_reserve("stream_db",
> -				    sizeof(stream_db_t),
> -				    ODP_CACHE_LINE_SIZE,
> -				    0);
> +	odp_shm_t shm;
> +
> +	shm = odp_shm_reserve("stream_db",
> +			      sizeof(stream_db_t),
> +			      ODP_CACHE_LINE_SIZE,
> +			      0);
> +
> +	stream_db = odp_shm_addr(shm);
> +
>   	if (stream_db == NULL) {
>   		ODP_ERR("Error: shared mem alloc failed.\n");
>   		exit(EXIT_FAILURE);
> diff --git a/example/l2fwd/odp_l2fwd.c b/example/l2fwd/odp_l2fwd.c
> index e19aa94..6c1d64a 100644
> --- a/example/l2fwd/odp_l2fwd.c
> +++ b/example/l2fwd/odp_l2fwd.c
> @@ -321,6 +321,7 @@ int main(int argc, char *argv[])
>   	int first_core;
>   	int core_count;
>   	odp_pktio_t pktio;
> +	odp_shm_t shm;
>   
>   	/* Init ODP before calling anything else */
>   	if (odp_init_global()) {
> @@ -329,8 +330,10 @@ int main(int argc, char *argv[])
>   	}
>   
>   	/* Reserve memory for args from shared mem */
> -	gbl_args = odp_shm_reserve("shm_args", sizeof(args_t),
> -				   ODP_CACHE_LINE_SIZE, 0);
> +	shm = odp_shm_reserve("shm_args", sizeof(args_t),
> +			      ODP_CACHE_LINE_SIZE, 0);
> +	gbl_args = odp_shm_addr(shm);
> +
>   	if (gbl_args == NULL) {
>   		ODP_ERR("Error: shared mem alloc failed.\n");
>   		exit(EXIT_FAILURE);
> @@ -380,8 +383,10 @@ int main(int argc, char *argv[])
>   	odp_init_local(thr_id);
>   
>   	/* Create packet pool */
> -	pool_base = odp_shm_reserve("shm_packet_pool",
> -				    SHM_PKT_POOL_SIZE, ODP_CACHE_LINE_SIZE, 0);
> +	shm = odp_shm_reserve("shm_packet_pool",
> +			      SHM_PKT_POOL_SIZE, ODP_CACHE_LINE_SIZE, 0);
> +	pool_base = odp_shm_addr(shm);
> +
>   	if (pool_base == NULL) {
>   		ODP_ERR("Error: packet pool mem alloc failed.\n");
>   		exit(EXIT_FAILURE);
> diff --git a/example/odp_example/odp_example.c b/example/odp_example/odp_example.c
> index e99df85..c80dbbc 100644
> --- a/example/odp_example/odp_example.c
> +++ b/example/odp_example/odp_example.c
> @@ -943,6 +943,7 @@ int main(int argc, char *argv[])
>   	int i, j;
>   	int prios;
>   	int first_core;
> +	odp_shm_t shm;
>   
>   	printf("\nODP example starts\n");
>   
> @@ -1003,8 +1004,15 @@ int main(int argc, char *argv[])
>   	/*
>   	 * Create message pool
>   	 */
> -	pool_base = odp_shm_reserve("msg_pool",
> -				    MSG_POOL_SIZE, ODP_CACHE_LINE_SIZE, 0);
> +	shm = odp_shm_reserve("msg_pool",
> +			      MSG_POOL_SIZE, ODP_CACHE_LINE_SIZE, 0);
> +
> +	pool_base = odp_shm_addr(shm);
> +
> +	if (pool_base == NULL) {
> +		ODP_ERR("Shared memory reserve failed.\n");
> +		return -1;
> +	}
>   
>   	pool = odp_buffer_pool_create("msg_pool", pool_base, MSG_POOL_SIZE,
>   				      sizeof(test_message_t),
> diff --git a/example/packet/odp_pktio.c b/example/packet/odp_pktio.c
> index 7f2d43f..41315f7 100644
> --- a/example/packet/odp_pktio.c
> +++ b/example/packet/odp_pktio.c
> @@ -309,6 +309,7 @@ int main(int argc, char *argv[])
>   	int i;
>   	int first_core;
>   	int core_count;
> +	odp_shm_t shm;
>   
>   	/* Init ODP before calling anything else */
>   	if (odp_init_global()) {
> @@ -317,8 +318,10 @@ int main(int argc, char *argv[])
>   	}
>   
>   	/* Reserve memory for args from shared mem */
> -	args = odp_shm_reserve("shm_args", sizeof(args_t),
> -			       ODP_CACHE_LINE_SIZE, 0);
> +	shm = odp_shm_reserve("shm_args", sizeof(args_t),
> +			      ODP_CACHE_LINE_SIZE, 0);
> +	args = odp_shm_addr(shm);
> +
>   	if (args == NULL) {
>   		ODP_ERR("Error: shared mem alloc failed.\n");
>   		exit(EXIT_FAILURE);
> @@ -358,8 +361,10 @@ int main(int argc, char *argv[])
>   	odp_init_local(thr_id);
>   
>   	/* Create packet pool */
> -	pool_base = odp_shm_reserve("shm_packet_pool",
> -				    SHM_PKT_POOL_SIZE, ODP_CACHE_LINE_SIZE, 0);
> +	shm = odp_shm_reserve("shm_packet_pool",
> +			      SHM_PKT_POOL_SIZE, ODP_CACHE_LINE_SIZE, 0);
> +	pool_base = odp_shm_addr(shm);
> +
>   	if (pool_base == NULL) {
>   		ODP_ERR("Error: packet pool mem alloc failed.\n");
>   		exit(EXIT_FAILURE);
> diff --git a/example/timer/odp_timer_test.c b/example/timer/odp_timer_test.c
> index fd46f16..6e1715d 100644
> --- a/example/timer/odp_timer_test.c
> +++ b/example/timer/odp_timer_test.c
> @@ -248,6 +248,7 @@ int main(int argc, char *argv[])
>   	int first_core;
>   	uint64_t cycles, ns;
>   	odp_queue_param_t param;
> +	odp_shm_t shm;
>   
>   	printf("\nODP timer example starts\n");
>   
> @@ -310,8 +311,9 @@ int main(int argc, char *argv[])
>   	/*
>   	 * Create message pool
>   	 */
> -	pool_base = odp_shm_reserve("msg_pool",
> -				    MSG_POOL_SIZE, ODP_CACHE_LINE_SIZE, 0);
> +	shm = odp_shm_reserve("msg_pool",
> +			      MSG_POOL_SIZE, ODP_CACHE_LINE_SIZE, 0);
> +	pool_base = odp_shm_addr(shm);
>   
>   	pool = odp_buffer_pool_create("msg_pool", pool_base, MSG_POOL_SIZE,
>   				      0,
> diff --git a/platform/linux-generic/include/api/odp_shared_memory.h b/platform/linux-generic/include/api/odp_shared_memory.h
> index 7d9fedd..7ad29c3 100644
> --- a/platform/linux-generic/include/api/odp_shared_memory.h
> +++ b/platform/linux-generic/include/api/odp_shared_memory.h
> @@ -32,10 +32,29 @@ extern "C" {
>   #define ODP_SHM_SW_ONLY 0x1 /**< Application SW only, no HW access */
>   #define ODP_SHM_PROC    0x2 /**< Share with external processes */
>   
> +/**
> + * ODP shared memory block
> + */
> +typedef uint32_t odp_shm_t;
> +
> +/** Invalid shared memory block */
> +#define ODP_SHM_INVALID 0
> +
> +
> +/**
> + * Shared memory block info
> + */
> +typedef struct odp_shm_info_t {
> +	const char *name;      /**< Block name */
> +	void       *addr;      /**< Block address */
> +	uint64_t    size;      /**< Block size in bytes */
> +	uint64_t    page_size; /**< Memory page size */
> +	uint32_t    flags;     /**< ODP_SHM_* flags */
> +} odp_shm_info_t;
>   
>   
>   /**
> - * Reserve a block of shared memory
> + * Reserve a contiguous block of shared memory
>    *
>    * @param name   Name of the block (maximum ODP_SHM_NAME_LEN - 1 chars)
>    * @param size   Block size in bytes
> @@ -44,8 +63,8 @@ extern "C" {
>    *
>    * @return Pointer to the reserved block, or NULL
>    */
> -void *odp_shm_reserve(const char *name, uint64_t size, uint64_t align,
> -		      uint32_t flags);
> +odp_shm_t odp_shm_reserve(const char *name, uint64_t size, uint64_t align,
> +			  uint32_t flags);
>   
>   /**
>    * Lookup for a block of shared memory
> @@ -54,7 +73,28 @@ void *odp_shm_reserve(const char *name, uint64_t size, uint64_t align,
>    *
>    * @return Pointer to the block, or NULL
>    */
> -void *odp_shm_lookup(const char *name);
> +odp_shm_t odp_shm_lookup(const char *name);
> +
> +
> +/**
> + * Shared memory block address
> + *
> + * @param shm   Block handle
> + *
> + * @return Memory block address, or NULL on error
> + */
> +void *odp_shm_addr(odp_shm_t shm);
> +
> +
> +/**
> + * Shared memory block info
> + *
> + * @param shm   Block handle
> + * @param info  Block info pointer for output
> + *
> + * @return 0 on success, otherwise non-zero
> + */
> +int odp_shm_info(odp_shm_t shm, odp_shm_info_t *info);
>   
>   
>   /**
> diff --git a/platform/linux-generic/odp_buffer_pool.c b/platform/linux-generic/odp_buffer_pool.c
> index f54a0c4..4d9ff45 100644
> --- a/platform/linux-generic/odp_buffer_pool.c
> +++ b/platform/linux-generic/odp_buffer_pool.c
> @@ -114,10 +114,13 @@ static inline void set_handle(odp_buffer_hdr_t *hdr,
>   int odp_buffer_pool_init_global(void)
>   {
>   	uint32_t i;
> +	odp_shm_t shm;
>   
> -	pool_tbl = odp_shm_reserve("odp_buffer_pools",
> -				   sizeof(pool_table_t),
> -				   sizeof(pool_entry_t), 0);
> +	shm = odp_shm_reserve("odp_buffer_pools",
> +			      sizeof(pool_table_t),
> +			      sizeof(pool_entry_t), 0);
> +
> +	pool_tbl = odp_shm_addr(shm);
>   
>   	if (pool_tbl == NULL)
>   		return -1;
> diff --git a/platform/linux-generic/odp_crypto.c b/platform/linux-generic/odp_crypto.c
> index 2942a84..12d0272 100644
> --- a/platform/linux-generic/odp_crypto.c
> +++ b/platform/linux-generic/odp_crypto.c
> @@ -403,14 +403,17 @@ int
>   odp_crypto_init_global(void)
>   {
>   	size_t mem_size;
> +	odp_shm_t shm;
>   
>   	/* Calculate the memory size we need */
>   	mem_size  = sizeof(*global);
>   	mem_size += (MAX_SESSIONS * sizeof(odp_crypto_generic_session_t));
>   
>   	/* Allocate our globally shared memory */
> -	global = odp_shm_reserve("crypto_pool", mem_size,
> -				 ODP_CACHE_LINE_SIZE, 0);
> +	shm = odp_shm_reserve("crypto_pool", mem_size,
> +			      ODP_CACHE_LINE_SIZE, 0);
> +
> +	global = odp_shm_addr(shm);
>   
>   	/* Clear it out */
>   	memset(global, 0, mem_size);
> diff --git a/platform/linux-generic/odp_packet_io.c b/platform/linux-generic/odp_packet_io.c
> index 944c1d4..06d8935 100644
> --- a/platform/linux-generic/odp_packet_io.c
> +++ b/platform/linux-generic/odp_packet_io.c
> @@ -52,10 +52,13 @@ int odp_pktio_init_global(void)
>   	queue_entry_t *queue_entry;
>   	odp_queue_t qid;
>   	int id;
> +	odp_shm_t shm;
> +
> +	shm = odp_shm_reserve("odp_pktio_entries",
> +			      sizeof(pktio_table_t),
> +			      sizeof(pktio_entry_t), 0);
> +	pktio_tbl = odp_shm_addr(shm);
>   
> -	pktio_tbl = odp_shm_reserve("odp_pktio_entries",
> -				    sizeof(pktio_table_t),
> -				    sizeof(pktio_entry_t), 0);
>   	if (pktio_tbl == NULL)
>   		return -1;
>   
> diff --git a/platform/linux-generic/odp_queue.c b/platform/linux-generic/odp_queue.c
> index 9852598..1318bcd 100644
> --- a/platform/linux-generic/odp_queue.c
> +++ b/platform/linux-generic/odp_queue.c
> @@ -94,12 +94,15 @@ static void queue_init(queue_entry_t *queue, const char *name,
>   int odp_queue_init_global(void)
>   {
>   	uint32_t i;
> +	odp_shm_t shm;
>   
>   	ODP_DBG("Queue init ... ");
>   
> -	queue_tbl = odp_shm_reserve("odp_queues",
> -				    sizeof(queue_table_t),
> -				    sizeof(queue_entry_t), 0);
> +	shm = odp_shm_reserve("odp_queues",
> +			      sizeof(queue_table_t),
> +			      sizeof(queue_entry_t), 0);
> +
> +	queue_tbl = odp_shm_addr(shm);
>   
>   	if (queue_tbl == NULL)
>   		return -1;
> diff --git a/platform/linux-generic/odp_ring.c b/platform/linux-generic/odp_ring.c
> index c415d7f..632aa66 100644
> --- a/platform/linux-generic/odp_ring.c
> +++ b/platform/linux-generic/odp_ring.c
> @@ -158,6 +158,7 @@ odph_ring_create(const char *name, unsigned count, unsigned flags)
>   	char ring_name[ODPH_RING_NAMESIZE];
>   	odph_ring_t *r;
>   	size_t ring_size;
> +	odp_shm_t shm;
>   
>   	/* count must be a power of 2 */
>   	if (!ODP_VAL_IS_POWER_2(count) || (count > ODPH_RING_SZ_MASK)) {
> @@ -171,7 +172,9 @@ odph_ring_create(const char *name, unsigned count, unsigned flags)
>   
>   	odp_rwlock_write_lock(&qlock);
>   	/* reserve a memory zone for this ring.*/
> -	r = odp_shm_reserve(ring_name, ring_size, ODP_CACHE_LINE_SIZE, 0);
> +	shm = odp_shm_reserve(ring_name, ring_size, ODP_CACHE_LINE_SIZE, 0);
> +
> +	r = odp_shm_addr(shm);
>   
>   	if (r != NULL) {
>   		/* init the ring structure */
> diff --git a/platform/linux-generic/odp_schedule.c b/platform/linux-generic/odp_schedule.c
> index 16ae4af..1bf819b 100644
> --- a/platform/linux-generic/odp_schedule.c
> +++ b/platform/linux-generic/odp_schedule.c
> @@ -81,23 +81,28 @@ static inline odp_queue_t select_pri_queue(odp_queue_t queue, int prio)
>   
>   int odp_schedule_init_global(void)
>   {
> +	odp_shm_t shm;
>   	odp_buffer_pool_t pool;
>   	void *pool_base;
>   	int i, j;
>   
>   	ODP_DBG("Schedule init ... ");
>   
> -	sched = odp_shm_reserve("odp_scheduler",
> -				sizeof(sched_t),
> -				ODP_CACHE_LINE_SIZE, 0);
> +	shm = odp_shm_reserve("odp_scheduler",
> +			      sizeof(sched_t),
> +			      ODP_CACHE_LINE_SIZE, 0);
> +
> +	sched = odp_shm_addr(shm);
>   
>   	if (sched == NULL) {
>   		ODP_ERR("Schedule init: Shm reserve failed.\n");
>   		return -1;
>   	}
>   
> -	pool_base = odp_shm_reserve("odp_sched_pool",
> -				    SCHED_POOL_SIZE, ODP_CACHE_LINE_SIZE, 0);
> +	shm = odp_shm_reserve("odp_sched_pool",
> +			      SCHED_POOL_SIZE, ODP_CACHE_LINE_SIZE, 0);
> +
> +	pool_base = odp_shm_addr(shm);
>   
>   	if (pool_base == NULL) {
>   		ODP_ERR("Schedule init: Shm reserve failed.\n");
> diff --git a/platform/linux-generic/odp_shared_memory.c b/platform/linux-generic/odp_shared_memory.c
> index 3d1e12a..1898a34 100644
> --- a/platform/linux-generic/odp_shared_memory.c
> +++ b/platform/linux-generic/odp_shared_memory.c
> @@ -24,12 +24,16 @@
>   
>   
>   typedef struct {
> -	char name[ODP_SHM_NAME_LEN];
> -	uint64_t size;
> -	uint64_t align;
> -	void *addr_orig;
> -	void *addr;
> -	int huge;
> +	char      name[ODP_SHM_NAME_LEN];
> +	uint64_t  size;
> +	uint64_t  align;
> +	void      *addr_orig;
> +	void      *addr;
> +	int       huge;
> +	odp_shm_t hdl;
> +	uint32_t  flags;
> +	uint64_t  page_sz;
> +	int       fd;
>   
>   } odp_shm_block_t;
>   
> @@ -50,6 +54,18 @@ typedef struct {
>   static odp_shm_table_t *odp_shm_tbl;
>   
>   
> +static inline uint32_t from_handle(odp_shm_t shm)
> +{
> +	return shm - 1;
> +}
> +
> +
> +static inline odp_shm_t to_handle(uint32_t index)
> +{
> +	return index + 1;
> +}
> +
> +
>   int odp_shm_init_global(void)
>   {
>   	void *addr;
> @@ -79,25 +95,28 @@ int odp_shm_init_local(void)
>   }
>   
>   
> -static int find_block(const char *name)
> +static int find_block(const char *name, uint32_t *index)
>   {
> -	int i;
> +	uint32_t i;
>   
>   	for (i = 0; i < ODP_SHM_NUM_BLOCKS; i++) {
>   		if (strcmp(name, odp_shm_tbl->block[i].name) == 0) {
>   			/* found it */
> -			return i;
> +			if (index != NULL)
> +				*index = i;
> +
> +			return 1;
>   		}
>   	}
>   
> -	return -1;
> +	return 0;
>   }
>   
>   
> -void *odp_shm_reserve(const char *name, uint64_t size, uint64_t align,
> -		      uint32_t flags)
> +odp_shm_t odp_shm_reserve(const char *name, uint64_t size, uint64_t align,
> +			  uint32_t flags)
>   {
> -	int i;
> +	uint32_t i;
>   	odp_shm_block_t *block;
>   	void *addr;
>   	int fd = -1;
> @@ -105,12 +124,10 @@ void *odp_shm_reserve(const char *name, uint64_t size, uint64_t align,
>   	/* If already exists: O_EXCL: error, O_TRUNC: truncate to zero */
>   	int oflag = O_RDWR | O_CREAT | O_TRUNC;
>   	uint64_t alloc_size = size + align;
> -#ifdef MAP_HUGETLB
> -	uint64_t huge_sz, page_sz;
> +	uint64_t page_sz, huge_sz;
>   
>   	huge_sz = odp_sys_huge_page_size();
>   	page_sz = odp_sys_page_size();
> -#endif
>   
>   	if (flags & ODP_SHM_PROC) {
>   		/* Creates a file to /dev/shm */
> @@ -119,12 +136,12 @@ void *odp_shm_reserve(const char *name, uint64_t size, uint64_t align,
>   
>   		if (fd == -1) {
>   			ODP_DBG("odp_shm_reserve: shm_open failed\n");
> -			return NULL;
> +			return ODP_SHM_INVALID;
>   		}
>   
>   		if (ftruncate(fd, alloc_size) == -1) {
>   			ODP_DBG("odp_shm_reserve: ftruncate failed\n");
> -			return NULL;
> +			return ODP_SHM_INVALID;
>   		}
>   
>   	} else {
> @@ -133,11 +150,11 @@ void *odp_shm_reserve(const char *name, uint64_t size, uint64_t align,
>   
>   	odp_spinlock_lock(&odp_shm_tbl->lock);
>   
> -	if (find_block(name) >= 0) {
> +	if (find_block(name, NULL)) {
>   		/* Found a block with the same name */
>   		odp_spinlock_unlock(&odp_shm_tbl->lock);
>   		ODP_DBG("odp_shm_reserve: name already used\n");
> -		return NULL;
> +		return ODP_SHM_INVALID;
>   	}
>   
>   	for (i = 0; i < ODP_SHM_NUM_BLOCKS; i++) {
> @@ -151,13 +168,14 @@ void *odp_shm_reserve(const char *name, uint64_t size, uint64_t align,
>   		/* Table full */
>   		odp_spinlock_unlock(&odp_shm_tbl->lock);
>   		ODP_DBG("odp_shm_reserve: no more blocks\n");
> -		return NULL;
> +		return ODP_SHM_INVALID;
>   	}
>   
>   	block = &odp_shm_tbl->block[i];
>   
> -	addr        = MAP_FAILED;
> +	block->hdl  = to_handle(i);
>   	block->huge = 0;
> +	addr        = MAP_FAILED;
>   
>   #ifdef MAP_HUGETLB
>   	/* Try first huge pages */
> @@ -171,16 +189,17 @@ void *odp_shm_reserve(const char *name, uint64_t size, uint64_t align,
>   	if (addr == MAP_FAILED) {
>   		addr = mmap(NULL, alloc_size, PROT_READ | PROT_WRITE,
>   			    map_flag, fd, 0);
> -
> +		block->page_sz = page_sz;
>   	} else {
> -		block->huge = 1;
> +		block->huge    = 1;
> +		block->page_sz = huge_sz;
>   	}
>   
>   	if (addr == MAP_FAILED) {
>   		/* Alloc failed */
>   		odp_spinlock_unlock(&odp_shm_tbl->lock);
>   		ODP_DBG("odp_shm_reserve: mmap failed\n");
> -		return NULL;
> +		return ODP_SHM_INVALID;
>   	}
>   
>   	block->addr_orig = addr;
> @@ -192,31 +211,66 @@ void *odp_shm_reserve(const char *name, uint64_t size, uint64_t align,
>   	block->name[ODP_SHM_NAME_LEN - 1] = 0;
>   	block->size   = size;
>   	block->align  = align;
> +	block->flags  = flags;
> +	block->fd     = fd;
>   	block->addr   = addr;
>   
>   	odp_spinlock_unlock(&odp_shm_tbl->lock);
> -	return addr;
> +	return block->hdl;
>   }
>   
>   
> -void *odp_shm_lookup(const char *name)
> +odp_shm_t odp_shm_lookup(const char *name)
>   {
> -	int i;
> -	void *addr;
> +	uint32_t i;
> +	odp_shm_t hdl;
>   
>   	odp_spinlock_lock(&odp_shm_tbl->lock);
>   
> -	i = find_block(name);
> -
> -	if (i < 0) {
> +	if (find_block(name, &i) == 0) {
>   		odp_spinlock_unlock(&odp_shm_tbl->lock);
> -		return NULL;
> +		return ODP_SHM_INVALID;
>   	}
>   
> -	addr = odp_shm_tbl->block[i].addr;
> +	hdl = odp_shm_tbl->block[i].hdl;
>   	odp_spinlock_unlock(&odp_shm_tbl->lock);
>   
> -	return addr;
> +	return hdl;
> +}
> +
> +
> +void *odp_shm_addr(odp_shm_t shm)
> +{
> +	uint32_t i;
> +
> +	i = from_handle(shm);
> +
> +	if (i > (ODP_SHM_NUM_BLOCKS - 1))
> +		return NULL;
> +
> +	return odp_shm_tbl->block[i].addr;
> +}
> +
> +
> +int odp_shm_info(odp_shm_t shm, odp_shm_info_t *info)
> +{
> +	odp_shm_block_t *block;
> +	uint32_t i;
> +
> +	i = from_handle(shm);
> +
> +	if (i > (ODP_SHM_NUM_BLOCKS - 1))
> +		return -1;
> +
> +	block = &odp_shm_tbl->block[i];
> +
> +	info->name      = block->name;
> +	info->addr      = block->addr;
> +	info->size      = block->size;
> +	info->page_size = block->page_sz;
> +	info->flags     = block->flags;
> +
> +	return 0;
>   }
>   
>   
> diff --git a/test/api_test/odp_shm_test.c b/test/api_test/odp_shm_test.c
> index 376b06f..6208e78 100644
> --- a/test/api_test/odp_shm_test.c
> +++ b/test/api_test/odp_shm_test.c
> @@ -19,6 +19,7 @@ static void *run_thread(void *arg)
>   {
>   	pthrd_arg *parg = (pthrd_arg *)arg;
>   	int thr;
> +	odp_shm_t shm;
>   
>   	thr = odp_thread_id();
>   
> @@ -26,7 +27,8 @@ static void *run_thread(void *arg)
>   
>   	switch (parg->testcase) {
>   	case ODP_SHM_TEST:
> -		test_shared_data = odp_shm_lookup("test_shared_data");
> +		shm = odp_shm_lookup("test_shared_data");
> +		test_shared_data = odp_shm_addr(shm);
>   		printf("  [%i] shared data at %p\n", thr, test_shared_data);
>   		break;
>   	default:
> @@ -40,14 +42,16 @@ static void *run_thread(void *arg)
>   int main(int argc ODP_UNUSED, char *argv[] ODP_UNUSED)
>   {
>   	pthrd_arg thrdarg;
> +	odp_shm_t shm;
>   
>   	if (odp_test_global_init() != 0)
>   		return -1;
>   
>   	odp_print_system_info();
>   
> -	test_shared_data = odp_shm_reserve("test_shared_data",
> -					   sizeof(test_shared_data_t), 128, 0);
> +	shm = odp_shm_reserve("test_shared_data",
> +			      sizeof(test_shared_data_t), 128, 0);
> +	test_shared_data = odp_shm_addr(shm);
>   	memset(test_shared_data, 0, sizeof(test_shared_data_t));
>   	printf("test shared data at %p\n\n", test_shared_data);
>   
> diff --git a/test/api_test/odp_timer_ping.c b/test/api_test/odp_timer_ping.c
> index a31567a..5ae379f 100644
> --- a/test/api_test/odp_timer_ping.c
> +++ b/test/api_test/odp_timer_ping.c
> @@ -315,6 +315,7 @@ int main(int argc ODP_UNUSED, char *argv[] ODP_UNUSED)
>   	odp_buffer_pool_t pool;
>   	void *pool_base;
>   	int i;
> +	odp_shm_t shm;
>   
>   	if (odp_test_global_init() != 0)
>   		return -1;
> @@ -327,8 +328,9 @@ int main(int argc ODP_UNUSED, char *argv[] ODP_UNUSED)
>   	/*
>   	 * Create message pool
>   	 */
> -	pool_base = odp_shm_reserve("msg_pool",
> -				    MSG_POOL_SIZE, ODP_CACHE_LINE_SIZE, 0);
> +	shm = odp_shm_reserve("msg_pool",
> +			      MSG_POOL_SIZE, ODP_CACHE_LINE_SIZE, 0);
> +	pool_base = odp_shm_addr(shm);
>   
>   	pool = odp_buffer_pool_create("msg_pool", pool_base, MSG_POOL_SIZE,
>   				      BUF_SIZE,
diff mbox

Patch

diff --git a/example/generator/odp_generator.c b/example/generator/odp_generator.c
index 10c7b31..27fc868 100644
--- a/example/generator/odp_generator.c
+++ b/example/generator/odp_generator.c
@@ -523,6 +523,7 @@  int main(int argc, char *argv[])
 	int i;
 	int first_core;
 	int core_count;
+	odp_shm_t shm;
 
 	/* Init ODP before calling anything else */
 	if (odp_init_global()) {
@@ -537,8 +538,10 @@  int main(int argc, char *argv[])
 	odp_atomic_init_u64(&counters.icmp);
 
 	/* Reserve memory for args from shared mem */
-	args = odp_shm_reserve("shm_args", sizeof(args_t),
-			       ODP_CACHE_LINE_SIZE, 0);
+	shm = odp_shm_reserve("shm_args", sizeof(args_t),
+			      ODP_CACHE_LINE_SIZE, 0);
+	args = odp_shm_addr(shm);
+
 	if (args == NULL) {
 		ODP_ERR("Error: shared mem alloc failed.\n");
 		exit(EXIT_FAILURE);
@@ -582,8 +585,10 @@  int main(int argc, char *argv[])
 	odp_init_local(thr_id);
 
 	/* Create packet pool */
-	pool_base = odp_shm_reserve("shm_packet_pool",
-				    SHM_PKT_POOL_SIZE, ODP_CACHE_LINE_SIZE, 0);
+	shm = odp_shm_reserve("shm_packet_pool",
+			      SHM_PKT_POOL_SIZE, ODP_CACHE_LINE_SIZE, 0);
+	pool_base = odp_shm_addr(shm);
+
 	if (pool_base == NULL) {
 		ODP_ERR("Error: packet pool mem alloc failed.\n");
 		exit(EXIT_FAILURE);
diff --git a/example/ipsec/odp_ipsec.c b/example/ipsec/odp_ipsec.c
index 5b7abf6..a9bba24 100644
--- a/example/ipsec/odp_ipsec.c
+++ b/example/ipsec/odp_ipsec.c
@@ -368,6 +368,7 @@  void ipsec_init_pre(void)
 {
 	odp_queue_param_t qparam;
 	void *pool_base;
+	odp_shm_t shm;
 
 	/*
 	 * Create queues
@@ -400,9 +401,10 @@  void ipsec_init_pre(void)
 	}
 
 	/* Create output buffer pool */
-	pool_base = odp_shm_reserve("shm_out_pool",
-				    SHM_OUT_POOL_SIZE, ODP_CACHE_LINE_SIZE,
-				    0);
+	shm = odp_shm_reserve("shm_out_pool",
+			      SHM_OUT_POOL_SIZE, ODP_CACHE_LINE_SIZE, 0);
+
+	pool_base = odp_shm_addr(shm);
 
 	out_pool = odp_buffer_pool_create("out_pool", pool_base,
 					  SHM_OUT_POOL_SIZE,
@@ -1179,6 +1181,7 @@  main(int argc, char *argv[])
 	int first_core;
 	int core_count;
 	int stream_count;
+	odp_shm_t shm;
 
 	/* Init ODP before calling anything else */
 	if (odp_init_global()) {
@@ -1191,8 +1194,11 @@  main(int argc, char *argv[])
 	odp_init_local(thr_id);
 
 	/* Reserve memory for args from shared mem */
-	args = odp_shm_reserve("shm_args", sizeof(args_t), ODP_CACHE_LINE_SIZE,
-			       0);
+	shm = odp_shm_reserve("shm_args", sizeof(args_t), ODP_CACHE_LINE_SIZE,
+			      0);
+
+	args = odp_shm_addr(shm);
+
 	if (NULL == args) {
 		ODP_ERR("Error: shared mem alloc failed.\n");
 		exit(EXIT_FAILURE);
@@ -1233,9 +1239,11 @@  main(int argc, char *argv[])
 	printf("First core:         %i\n\n", first_core);
 
 	/* Create packet buffer pool */
-	pool_base = odp_shm_reserve("shm_packet_pool",
-				    SHM_PKT_POOL_SIZE, ODP_CACHE_LINE_SIZE,
-				    0);
+	shm = odp_shm_reserve("shm_packet_pool",
+			      SHM_PKT_POOL_SIZE, ODP_CACHE_LINE_SIZE, 0);
+
+	pool_base = odp_shm_addr(shm);
+
 	if (NULL == pool_base) {
 		ODP_ERR("Error: packet pool mem alloc failed.\n");
 		exit(EXIT_FAILURE);
@@ -1252,9 +1260,11 @@  main(int argc, char *argv[])
 	}
 
 	/* Create context buffer pool */
-	pool_base = odp_shm_reserve("shm_ctx_pool",
-				    SHM_CTX_POOL_SIZE, ODP_CACHE_LINE_SIZE,
-				    0);
+	shm = odp_shm_reserve("shm_ctx_pool",
+			      SHM_CTX_POOL_SIZE, ODP_CACHE_LINE_SIZE, 0);
+
+	pool_base = odp_shm_addr(shm);
+
 	if (NULL == pool_base) {
 		ODP_ERR("Error: context pool mem alloc failed.\n");
 		exit(EXIT_FAILURE);
diff --git a/example/ipsec/odp_ipsec_cache.c b/example/ipsec/odp_ipsec_cache.c
index 1b99218..01650d0 100644
--- a/example/ipsec/odp_ipsec_cache.c
+++ b/example/ipsec/odp_ipsec_cache.c
@@ -19,10 +19,15 @@  ipsec_cache_t *ipsec_cache;
 
 void init_ipsec_cache(void)
 {
-	ipsec_cache = odp_shm_reserve("shm_ipsec_cache",
-				      sizeof(ipsec_cache_t),
-				      ODP_CACHE_LINE_SIZE,
-				      0);
+	odp_shm_t shm;
+
+	shm = odp_shm_reserve("shm_ipsec_cache",
+			      sizeof(ipsec_cache_t),
+			      ODP_CACHE_LINE_SIZE,
+			      0);
+
+	ipsec_cache = odp_shm_addr(shm);
+
 	if (ipsec_cache == NULL) {
 		ODP_ERR("Error: shared mem alloc failed.\n");
 		exit(EXIT_FAILURE);
diff --git a/example/ipsec/odp_ipsec_fwd_db.c b/example/ipsec/odp_ipsec_fwd_db.c
index de2e43e..9ed5d00 100644
--- a/example/ipsec/odp_ipsec_fwd_db.c
+++ b/example/ipsec/odp_ipsec_fwd_db.c
@@ -18,10 +18,15 @@  fwd_db_t *fwd_db;
 
 void init_fwd_db(void)
 {
-	fwd_db = odp_shm_reserve("shm_fwd_db",
-				 sizeof(fwd_db_t),
-				 ODP_CACHE_LINE_SIZE,
-				 0);
+	odp_shm_t shm;
+
+	shm = odp_shm_reserve("shm_fwd_db",
+			      sizeof(fwd_db_t),
+			      ODP_CACHE_LINE_SIZE,
+			      0);
+
+	fwd_db = odp_shm_addr(shm);
+
 	if (fwd_db == NULL) {
 		ODP_ERR("Error: shared mem alloc failed.\n");
 		exit(EXIT_FAILURE);
diff --git a/example/ipsec/odp_ipsec_loop_db.c b/example/ipsec/odp_ipsec_loop_db.c
index 222ccb9..f773352 100644
--- a/example/ipsec/odp_ipsec_loop_db.c
+++ b/example/ipsec/odp_ipsec_loop_db.c
@@ -18,11 +18,15 @@  loopback_db_t *loopback_db;
 void init_loopback_db(void)
 {
 	int idx;
+	odp_shm_t shm;
+
+	shm = odp_shm_reserve("loopback_db",
+			      sizeof(loopback_db_t),
+			      ODP_CACHE_LINE_SIZE,
+			      0);
+
+	loopback_db = odp_shm_addr(shm);
 
-	loopback_db = odp_shm_reserve("loopback_db",
-				      sizeof(loopback_db_t),
-				      ODP_CACHE_LINE_SIZE,
-				      0);
 	if (loopback_db == NULL) {
 		ODP_ERR("Error: shared mem alloc failed.\n");
 		exit(EXIT_FAILURE);
diff --git a/example/ipsec/odp_ipsec_sa_db.c b/example/ipsec/odp_ipsec_sa_db.c
index 612da86..f6da623 100644
--- a/example/ipsec/odp_ipsec_sa_db.c
+++ b/example/ipsec/odp_ipsec_sa_db.c
@@ -18,10 +18,15 @@  static sa_db_t *sa_db;
 
 void init_sa_db(void)
 {
-	sa_db = odp_shm_reserve("shm_sa_db",
-				sizeof(sa_db_t),
-				ODP_CACHE_LINE_SIZE,
-				0);
+	odp_shm_t shm;
+
+	shm = odp_shm_reserve("shm_sa_db",
+			      sizeof(sa_db_t),
+			      ODP_CACHE_LINE_SIZE,
+			      0);
+
+	sa_db = odp_shm_addr(shm);
+
 	if (sa_db == NULL) {
 		ODP_ERR("Error: shared mem alloc failed.\n");
 		exit(EXIT_FAILURE);
diff --git a/example/ipsec/odp_ipsec_sp_db.c b/example/ipsec/odp_ipsec_sp_db.c
index 7d9bba1..f288dfe 100644
--- a/example/ipsec/odp_ipsec_sp_db.c
+++ b/example/ipsec/odp_ipsec_sp_db.c
@@ -18,10 +18,15 @@  sp_db_t *sp_db;
 
 void init_sp_db(void)
 {
-	sp_db = odp_shm_reserve("shm_sp_db",
-				sizeof(sp_db_t),
-				ODP_CACHE_LINE_SIZE,
-				0);
+	odp_shm_t shm;
+
+	shm = odp_shm_reserve("shm_sp_db",
+			      sizeof(sp_db_t),
+			      ODP_CACHE_LINE_SIZE,
+			      0);
+
+	sp_db = odp_shm_addr(shm);
+
 	if (sp_db == NULL) {
 		ODP_ERR("Error: shared mem alloc failed.\n");
 		exit(EXIT_FAILURE);
diff --git a/example/ipsec/odp_ipsec_stream.c b/example/ipsec/odp_ipsec_stream.c
index ced055a..de8305a 100644
--- a/example/ipsec/odp_ipsec_stream.c
+++ b/example/ipsec/odp_ipsec_stream.c
@@ -48,10 +48,15 @@  stream_db_t *stream_db;
 
 void init_stream_db(void)
 {
-	stream_db = odp_shm_reserve("stream_db",
-				    sizeof(stream_db_t),
-				    ODP_CACHE_LINE_SIZE,
-				    0);
+	odp_shm_t shm;
+
+	shm = odp_shm_reserve("stream_db",
+			      sizeof(stream_db_t),
+			      ODP_CACHE_LINE_SIZE,
+			      0);
+
+	stream_db = odp_shm_addr(shm);
+
 	if (stream_db == NULL) {
 		ODP_ERR("Error: shared mem alloc failed.\n");
 		exit(EXIT_FAILURE);
diff --git a/example/l2fwd/odp_l2fwd.c b/example/l2fwd/odp_l2fwd.c
index e19aa94..6c1d64a 100644
--- a/example/l2fwd/odp_l2fwd.c
+++ b/example/l2fwd/odp_l2fwd.c
@@ -321,6 +321,7 @@  int main(int argc, char *argv[])
 	int first_core;
 	int core_count;
 	odp_pktio_t pktio;
+	odp_shm_t shm;
 
 	/* Init ODP before calling anything else */
 	if (odp_init_global()) {
@@ -329,8 +330,10 @@  int main(int argc, char *argv[])
 	}
 
 	/* Reserve memory for args from shared mem */
-	gbl_args = odp_shm_reserve("shm_args", sizeof(args_t),
-				   ODP_CACHE_LINE_SIZE, 0);
+	shm = odp_shm_reserve("shm_args", sizeof(args_t),
+			      ODP_CACHE_LINE_SIZE, 0);
+	gbl_args = odp_shm_addr(shm);
+
 	if (gbl_args == NULL) {
 		ODP_ERR("Error: shared mem alloc failed.\n");
 		exit(EXIT_FAILURE);
@@ -380,8 +383,10 @@  int main(int argc, char *argv[])
 	odp_init_local(thr_id);
 
 	/* Create packet pool */
-	pool_base = odp_shm_reserve("shm_packet_pool",
-				    SHM_PKT_POOL_SIZE, ODP_CACHE_LINE_SIZE, 0);
+	shm = odp_shm_reserve("shm_packet_pool",
+			      SHM_PKT_POOL_SIZE, ODP_CACHE_LINE_SIZE, 0);
+	pool_base = odp_shm_addr(shm);
+
 	if (pool_base == NULL) {
 		ODP_ERR("Error: packet pool mem alloc failed.\n");
 		exit(EXIT_FAILURE);
diff --git a/example/odp_example/odp_example.c b/example/odp_example/odp_example.c
index e99df85..c80dbbc 100644
--- a/example/odp_example/odp_example.c
+++ b/example/odp_example/odp_example.c
@@ -943,6 +943,7 @@  int main(int argc, char *argv[])
 	int i, j;
 	int prios;
 	int first_core;
+	odp_shm_t shm;
 
 	printf("\nODP example starts\n");
 
@@ -1003,8 +1004,15 @@  int main(int argc, char *argv[])
 	/*
 	 * Create message pool
 	 */
-	pool_base = odp_shm_reserve("msg_pool",
-				    MSG_POOL_SIZE, ODP_CACHE_LINE_SIZE, 0);
+	shm = odp_shm_reserve("msg_pool",
+			      MSG_POOL_SIZE, ODP_CACHE_LINE_SIZE, 0);
+
+	pool_base = odp_shm_addr(shm);
+
+	if (pool_base == NULL) {
+		ODP_ERR("Shared memory reserve failed.\n");
+		return -1;
+	}
 
 	pool = odp_buffer_pool_create("msg_pool", pool_base, MSG_POOL_SIZE,
 				      sizeof(test_message_t),
diff --git a/example/packet/odp_pktio.c b/example/packet/odp_pktio.c
index 7f2d43f..41315f7 100644
--- a/example/packet/odp_pktio.c
+++ b/example/packet/odp_pktio.c
@@ -309,6 +309,7 @@  int main(int argc, char *argv[])
 	int i;
 	int first_core;
 	int core_count;
+	odp_shm_t shm;
 
 	/* Init ODP before calling anything else */
 	if (odp_init_global()) {
@@ -317,8 +318,10 @@  int main(int argc, char *argv[])
 	}
 
 	/* Reserve memory for args from shared mem */
-	args = odp_shm_reserve("shm_args", sizeof(args_t),
-			       ODP_CACHE_LINE_SIZE, 0);
+	shm = odp_shm_reserve("shm_args", sizeof(args_t),
+			      ODP_CACHE_LINE_SIZE, 0);
+	args = odp_shm_addr(shm);
+
 	if (args == NULL) {
 		ODP_ERR("Error: shared mem alloc failed.\n");
 		exit(EXIT_FAILURE);
@@ -358,8 +361,10 @@  int main(int argc, char *argv[])
 	odp_init_local(thr_id);
 
 	/* Create packet pool */
-	pool_base = odp_shm_reserve("shm_packet_pool",
-				    SHM_PKT_POOL_SIZE, ODP_CACHE_LINE_SIZE, 0);
+	shm = odp_shm_reserve("shm_packet_pool",
+			      SHM_PKT_POOL_SIZE, ODP_CACHE_LINE_SIZE, 0);
+	pool_base = odp_shm_addr(shm);
+
 	if (pool_base == NULL) {
 		ODP_ERR("Error: packet pool mem alloc failed.\n");
 		exit(EXIT_FAILURE);
diff --git a/example/timer/odp_timer_test.c b/example/timer/odp_timer_test.c
index fd46f16..6e1715d 100644
--- a/example/timer/odp_timer_test.c
+++ b/example/timer/odp_timer_test.c
@@ -248,6 +248,7 @@  int main(int argc, char *argv[])
 	int first_core;
 	uint64_t cycles, ns;
 	odp_queue_param_t param;
+	odp_shm_t shm;
 
 	printf("\nODP timer example starts\n");
 
@@ -310,8 +311,9 @@  int main(int argc, char *argv[])
 	/*
 	 * Create message pool
 	 */
-	pool_base = odp_shm_reserve("msg_pool",
-				    MSG_POOL_SIZE, ODP_CACHE_LINE_SIZE, 0);
+	shm = odp_shm_reserve("msg_pool",
+			      MSG_POOL_SIZE, ODP_CACHE_LINE_SIZE, 0);
+	pool_base = odp_shm_addr(shm);
 
 	pool = odp_buffer_pool_create("msg_pool", pool_base, MSG_POOL_SIZE,
 				      0,
diff --git a/platform/linux-generic/include/api/odp_shared_memory.h b/platform/linux-generic/include/api/odp_shared_memory.h
index 7d9fedd..7ad29c3 100644
--- a/platform/linux-generic/include/api/odp_shared_memory.h
+++ b/platform/linux-generic/include/api/odp_shared_memory.h
@@ -32,10 +32,29 @@  extern "C" {
 #define ODP_SHM_SW_ONLY 0x1 /**< Application SW only, no HW access */
 #define ODP_SHM_PROC    0x2 /**< Share with external processes */
 
+/**
+ * ODP shared memory block
+ */
+typedef uint32_t odp_shm_t;
+
+/** Invalid shared memory block */
+#define ODP_SHM_INVALID 0
+
+
+/**
+ * Shared memory block info
+ */
+typedef struct odp_shm_info_t {
+	const char *name;      /**< Block name */
+	void       *addr;      /**< Block address */
+	uint64_t    size;      /**< Block size in bytes */
+	uint64_t    page_size; /**< Memory page size */
+	uint32_t    flags;     /**< ODP_SHM_* flags */
+} odp_shm_info_t;
 
 
 /**
- * Reserve a block of shared memory
+ * Reserve a contiguous block of shared memory
  *
  * @param name   Name of the block (maximum ODP_SHM_NAME_LEN - 1 chars)
  * @param size   Block size in bytes
@@ -44,8 +63,8 @@  extern "C" {
  *
  * @return Pointer to the reserved block, or NULL
  */
-void *odp_shm_reserve(const char *name, uint64_t size, uint64_t align,
-		      uint32_t flags);
+odp_shm_t odp_shm_reserve(const char *name, uint64_t size, uint64_t align,
+			  uint32_t flags);
 
 /**
  * Lookup for a block of shared memory
@@ -54,7 +73,28 @@  void *odp_shm_reserve(const char *name, uint64_t size, uint64_t align,
  *
  * @return Pointer to the block, or NULL
  */
-void *odp_shm_lookup(const char *name);
+odp_shm_t odp_shm_lookup(const char *name);
+
+
+/**
+ * Shared memory block address
+ *
+ * @param shm   Block handle
+ *
+ * @return Memory block address, or NULL on error
+ */
+void *odp_shm_addr(odp_shm_t shm);
+
+
+/**
+ * Shared memory block info
+ *
+ * @param shm   Block handle
+ * @param info  Block info pointer for output
+ *
+ * @return 0 on success, otherwise non-zero
+ */
+int odp_shm_info(odp_shm_t shm, odp_shm_info_t *info);
 
 
 /**
diff --git a/platform/linux-generic/odp_buffer_pool.c b/platform/linux-generic/odp_buffer_pool.c
index f54a0c4..4d9ff45 100644
--- a/platform/linux-generic/odp_buffer_pool.c
+++ b/platform/linux-generic/odp_buffer_pool.c
@@ -114,10 +114,13 @@  static inline void set_handle(odp_buffer_hdr_t *hdr,
 int odp_buffer_pool_init_global(void)
 {
 	uint32_t i;
+	odp_shm_t shm;
 
-	pool_tbl = odp_shm_reserve("odp_buffer_pools",
-				   sizeof(pool_table_t),
-				   sizeof(pool_entry_t), 0);
+	shm = odp_shm_reserve("odp_buffer_pools",
+			      sizeof(pool_table_t),
+			      sizeof(pool_entry_t), 0);
+
+	pool_tbl = odp_shm_addr(shm);
 
 	if (pool_tbl == NULL)
 		return -1;
diff --git a/platform/linux-generic/odp_crypto.c b/platform/linux-generic/odp_crypto.c
index 2942a84..12d0272 100644
--- a/platform/linux-generic/odp_crypto.c
+++ b/platform/linux-generic/odp_crypto.c
@@ -403,14 +403,17 @@  int
 odp_crypto_init_global(void)
 {
 	size_t mem_size;
+	odp_shm_t shm;
 
 	/* Calculate the memory size we need */
 	mem_size  = sizeof(*global);
 	mem_size += (MAX_SESSIONS * sizeof(odp_crypto_generic_session_t));
 
 	/* Allocate our globally shared memory */
-	global = odp_shm_reserve("crypto_pool", mem_size,
-				 ODP_CACHE_LINE_SIZE, 0);
+	shm = odp_shm_reserve("crypto_pool", mem_size,
+			      ODP_CACHE_LINE_SIZE, 0);
+
+	global = odp_shm_addr(shm);
 
 	/* Clear it out */
 	memset(global, 0, mem_size);
diff --git a/platform/linux-generic/odp_packet_io.c b/platform/linux-generic/odp_packet_io.c
index 944c1d4..06d8935 100644
--- a/platform/linux-generic/odp_packet_io.c
+++ b/platform/linux-generic/odp_packet_io.c
@@ -52,10 +52,13 @@  int odp_pktio_init_global(void)
 	queue_entry_t *queue_entry;
 	odp_queue_t qid;
 	int id;
+	odp_shm_t shm;
+
+	shm = odp_shm_reserve("odp_pktio_entries",
+			      sizeof(pktio_table_t),
+			      sizeof(pktio_entry_t), 0);
+	pktio_tbl = odp_shm_addr(shm);
 
-	pktio_tbl = odp_shm_reserve("odp_pktio_entries",
-				    sizeof(pktio_table_t),
-				    sizeof(pktio_entry_t), 0);
 	if (pktio_tbl == NULL)
 		return -1;
 
diff --git a/platform/linux-generic/odp_queue.c b/platform/linux-generic/odp_queue.c
index 9852598..1318bcd 100644
--- a/platform/linux-generic/odp_queue.c
+++ b/platform/linux-generic/odp_queue.c
@@ -94,12 +94,15 @@  static void queue_init(queue_entry_t *queue, const char *name,
 int odp_queue_init_global(void)
 {
 	uint32_t i;
+	odp_shm_t shm;
 
 	ODP_DBG("Queue init ... ");
 
-	queue_tbl = odp_shm_reserve("odp_queues",
-				    sizeof(queue_table_t),
-				    sizeof(queue_entry_t), 0);
+	shm = odp_shm_reserve("odp_queues",
+			      sizeof(queue_table_t),
+			      sizeof(queue_entry_t), 0);
+
+	queue_tbl = odp_shm_addr(shm);
 
 	if (queue_tbl == NULL)
 		return -1;
diff --git a/platform/linux-generic/odp_ring.c b/platform/linux-generic/odp_ring.c
index c415d7f..632aa66 100644
--- a/platform/linux-generic/odp_ring.c
+++ b/platform/linux-generic/odp_ring.c
@@ -158,6 +158,7 @@  odph_ring_create(const char *name, unsigned count, unsigned flags)
 	char ring_name[ODPH_RING_NAMESIZE];
 	odph_ring_t *r;
 	size_t ring_size;
+	odp_shm_t shm;
 
 	/* count must be a power of 2 */
 	if (!ODP_VAL_IS_POWER_2(count) || (count > ODPH_RING_SZ_MASK)) {
@@ -171,7 +172,9 @@  odph_ring_create(const char *name, unsigned count, unsigned flags)
 
 	odp_rwlock_write_lock(&qlock);
 	/* reserve a memory zone for this ring.*/
-	r = odp_shm_reserve(ring_name, ring_size, ODP_CACHE_LINE_SIZE, 0);
+	shm = odp_shm_reserve(ring_name, ring_size, ODP_CACHE_LINE_SIZE, 0);
+
+	r = odp_shm_addr(shm);
 
 	if (r != NULL) {
 		/* init the ring structure */
diff --git a/platform/linux-generic/odp_schedule.c b/platform/linux-generic/odp_schedule.c
index 16ae4af..1bf819b 100644
--- a/platform/linux-generic/odp_schedule.c
+++ b/platform/linux-generic/odp_schedule.c
@@ -81,23 +81,28 @@  static inline odp_queue_t select_pri_queue(odp_queue_t queue, int prio)
 
 int odp_schedule_init_global(void)
 {
+	odp_shm_t shm;
 	odp_buffer_pool_t pool;
 	void *pool_base;
 	int i, j;
 
 	ODP_DBG("Schedule init ... ");
 
-	sched = odp_shm_reserve("odp_scheduler",
-				sizeof(sched_t),
-				ODP_CACHE_LINE_SIZE, 0);
+	shm = odp_shm_reserve("odp_scheduler",
+			      sizeof(sched_t),
+			      ODP_CACHE_LINE_SIZE, 0);
+
+	sched = odp_shm_addr(shm);
 
 	if (sched == NULL) {
 		ODP_ERR("Schedule init: Shm reserve failed.\n");
 		return -1;
 	}
 
-	pool_base = odp_shm_reserve("odp_sched_pool",
-				    SCHED_POOL_SIZE, ODP_CACHE_LINE_SIZE, 0);
+	shm = odp_shm_reserve("odp_sched_pool",
+			      SCHED_POOL_SIZE, ODP_CACHE_LINE_SIZE, 0);
+
+	pool_base = odp_shm_addr(shm);
 
 	if (pool_base == NULL) {
 		ODP_ERR("Schedule init: Shm reserve failed.\n");
diff --git a/platform/linux-generic/odp_shared_memory.c b/platform/linux-generic/odp_shared_memory.c
index 3d1e12a..1898a34 100644
--- a/platform/linux-generic/odp_shared_memory.c
+++ b/platform/linux-generic/odp_shared_memory.c
@@ -24,12 +24,16 @@ 
 
 
 typedef struct {
-	char name[ODP_SHM_NAME_LEN];
-	uint64_t size;
-	uint64_t align;
-	void *addr_orig;
-	void *addr;
-	int huge;
+	char      name[ODP_SHM_NAME_LEN];
+	uint64_t  size;
+	uint64_t  align;
+	void      *addr_orig;
+	void      *addr;
+	int       huge;
+	odp_shm_t hdl;
+	uint32_t  flags;
+	uint64_t  page_sz;
+	int       fd;
 
 } odp_shm_block_t;
 
@@ -50,6 +54,18 @@  typedef struct {
 static odp_shm_table_t *odp_shm_tbl;
 
 
+static inline uint32_t from_handle(odp_shm_t shm)
+{
+	return shm - 1;
+}
+
+
+static inline odp_shm_t to_handle(uint32_t index)
+{
+	return index + 1;
+}
+
+
 int odp_shm_init_global(void)
 {
 	void *addr;
@@ -79,25 +95,28 @@  int odp_shm_init_local(void)
 }
 
 
-static int find_block(const char *name)
+static int find_block(const char *name, uint32_t *index)
 {
-	int i;
+	uint32_t i;
 
 	for (i = 0; i < ODP_SHM_NUM_BLOCKS; i++) {
 		if (strcmp(name, odp_shm_tbl->block[i].name) == 0) {
 			/* found it */
-			return i;
+			if (index != NULL)
+				*index = i;
+
+			return 1;
 		}
 	}
 
-	return -1;
+	return 0;
 }
 
 
-void *odp_shm_reserve(const char *name, uint64_t size, uint64_t align,
-		      uint32_t flags)
+odp_shm_t odp_shm_reserve(const char *name, uint64_t size, uint64_t align,
+			  uint32_t flags)
 {
-	int i;
+	uint32_t i;
 	odp_shm_block_t *block;
 	void *addr;
 	int fd = -1;
@@ -105,12 +124,10 @@  void *odp_shm_reserve(const char *name, uint64_t size, uint64_t align,
 	/* If already exists: O_EXCL: error, O_TRUNC: truncate to zero */
 	int oflag = O_RDWR | O_CREAT | O_TRUNC;
 	uint64_t alloc_size = size + align;
-#ifdef MAP_HUGETLB
-	uint64_t huge_sz, page_sz;
+	uint64_t page_sz, huge_sz;
 
 	huge_sz = odp_sys_huge_page_size();
 	page_sz = odp_sys_page_size();
-#endif
 
 	if (flags & ODP_SHM_PROC) {
 		/* Creates a file to /dev/shm */
@@ -119,12 +136,12 @@  void *odp_shm_reserve(const char *name, uint64_t size, uint64_t align,
 
 		if (fd == -1) {
 			ODP_DBG("odp_shm_reserve: shm_open failed\n");
-			return NULL;
+			return ODP_SHM_INVALID;
 		}
 
 		if (ftruncate(fd, alloc_size) == -1) {
 			ODP_DBG("odp_shm_reserve: ftruncate failed\n");
-			return NULL;
+			return ODP_SHM_INVALID;
 		}
 
 	} else {
@@ -133,11 +150,11 @@  void *odp_shm_reserve(const char *name, uint64_t size, uint64_t align,
 
 	odp_spinlock_lock(&odp_shm_tbl->lock);
 
-	if (find_block(name) >= 0) {
+	if (find_block(name, NULL)) {
 		/* Found a block with the same name */
 		odp_spinlock_unlock(&odp_shm_tbl->lock);
 		ODP_DBG("odp_shm_reserve: name already used\n");
-		return NULL;
+		return ODP_SHM_INVALID;
 	}
 
 	for (i = 0; i < ODP_SHM_NUM_BLOCKS; i++) {
@@ -151,13 +168,14 @@  void *odp_shm_reserve(const char *name, uint64_t size, uint64_t align,
 		/* Table full */
 		odp_spinlock_unlock(&odp_shm_tbl->lock);
 		ODP_DBG("odp_shm_reserve: no more blocks\n");
-		return NULL;
+		return ODP_SHM_INVALID;
 	}
 
 	block = &odp_shm_tbl->block[i];
 
-	addr        = MAP_FAILED;
+	block->hdl  = to_handle(i);
 	block->huge = 0;
+	addr        = MAP_FAILED;
 
 #ifdef MAP_HUGETLB
 	/* Try first huge pages */
@@ -171,16 +189,17 @@  void *odp_shm_reserve(const char *name, uint64_t size, uint64_t align,
 	if (addr == MAP_FAILED) {
 		addr = mmap(NULL, alloc_size, PROT_READ | PROT_WRITE,
 			    map_flag, fd, 0);
-
+		block->page_sz = page_sz;
 	} else {
-		block->huge = 1;
+		block->huge    = 1;
+		block->page_sz = huge_sz;
 	}
 
 	if (addr == MAP_FAILED) {
 		/* Alloc failed */
 		odp_spinlock_unlock(&odp_shm_tbl->lock);
 		ODP_DBG("odp_shm_reserve: mmap failed\n");
-		return NULL;
+		return ODP_SHM_INVALID;
 	}
 
 	block->addr_orig = addr;
@@ -192,31 +211,66 @@  void *odp_shm_reserve(const char *name, uint64_t size, uint64_t align,
 	block->name[ODP_SHM_NAME_LEN - 1] = 0;
 	block->size   = size;
 	block->align  = align;
+	block->flags  = flags;
+	block->fd     = fd;
 	block->addr   = addr;
 
 	odp_spinlock_unlock(&odp_shm_tbl->lock);
-	return addr;
+	return block->hdl;
 }
 
 
-void *odp_shm_lookup(const char *name)
+odp_shm_t odp_shm_lookup(const char *name)
 {
-	int i;
-	void *addr;
+	uint32_t i;
+	odp_shm_t hdl;
 
 	odp_spinlock_lock(&odp_shm_tbl->lock);
 
-	i = find_block(name);
-
-	if (i < 0) {
+	if (find_block(name, &i) == 0) {
 		odp_spinlock_unlock(&odp_shm_tbl->lock);
-		return NULL;
+		return ODP_SHM_INVALID;
 	}
 
-	addr = odp_shm_tbl->block[i].addr;
+	hdl = odp_shm_tbl->block[i].hdl;
 	odp_spinlock_unlock(&odp_shm_tbl->lock);
 
-	return addr;
+	return hdl;
+}
+
+
+void *odp_shm_addr(odp_shm_t shm)
+{
+	uint32_t i;
+
+	i = from_handle(shm);
+
+	if (i > (ODP_SHM_NUM_BLOCKS - 1))
+		return NULL;
+
+	return odp_shm_tbl->block[i].addr;
+}
+
+
+int odp_shm_info(odp_shm_t shm, odp_shm_info_t *info)
+{
+	odp_shm_block_t *block;
+	uint32_t i;
+
+	i = from_handle(shm);
+
+	if (i > (ODP_SHM_NUM_BLOCKS - 1))
+		return -1;
+
+	block = &odp_shm_tbl->block[i];
+
+	info->name      = block->name;
+	info->addr      = block->addr;
+	info->size      = block->size;
+	info->page_size = block->page_sz;
+	info->flags     = block->flags;
+
+	return 0;
 }
 
 
diff --git a/test/api_test/odp_shm_test.c b/test/api_test/odp_shm_test.c
index 376b06f..6208e78 100644
--- a/test/api_test/odp_shm_test.c
+++ b/test/api_test/odp_shm_test.c
@@ -19,6 +19,7 @@  static void *run_thread(void *arg)
 {
 	pthrd_arg *parg = (pthrd_arg *)arg;
 	int thr;
+	odp_shm_t shm;
 
 	thr = odp_thread_id();
 
@@ -26,7 +27,8 @@  static void *run_thread(void *arg)
 
 	switch (parg->testcase) {
 	case ODP_SHM_TEST:
-		test_shared_data = odp_shm_lookup("test_shared_data");
+		shm = odp_shm_lookup("test_shared_data");
+		test_shared_data = odp_shm_addr(shm);
 		printf("  [%i] shared data at %p\n", thr, test_shared_data);
 		break;
 	default:
@@ -40,14 +42,16 @@  static void *run_thread(void *arg)
 int main(int argc ODP_UNUSED, char *argv[] ODP_UNUSED)
 {
 	pthrd_arg thrdarg;
+	odp_shm_t shm;
 
 	if (odp_test_global_init() != 0)
 		return -1;
 
 	odp_print_system_info();
 
-	test_shared_data = odp_shm_reserve("test_shared_data",
-					   sizeof(test_shared_data_t), 128, 0);
+	shm = odp_shm_reserve("test_shared_data",
+			      sizeof(test_shared_data_t), 128, 0);
+	test_shared_data = odp_shm_addr(shm);
 	memset(test_shared_data, 0, sizeof(test_shared_data_t));
 	printf("test shared data at %p\n\n", test_shared_data);
 
diff --git a/test/api_test/odp_timer_ping.c b/test/api_test/odp_timer_ping.c
index a31567a..5ae379f 100644
--- a/test/api_test/odp_timer_ping.c
+++ b/test/api_test/odp_timer_ping.c
@@ -315,6 +315,7 @@  int main(int argc ODP_UNUSED, char *argv[] ODP_UNUSED)
 	odp_buffer_pool_t pool;
 	void *pool_base;
 	int i;
+	odp_shm_t shm;
 
 	if (odp_test_global_init() != 0)
 		return -1;
@@ -327,8 +328,9 @@  int main(int argc ODP_UNUSED, char *argv[] ODP_UNUSED)
 	/*
 	 * Create message pool
 	 */
-	pool_base = odp_shm_reserve("msg_pool",
-				    MSG_POOL_SIZE, ODP_CACHE_LINE_SIZE, 0);
+	shm = odp_shm_reserve("msg_pool",
+			      MSG_POOL_SIZE, ODP_CACHE_LINE_SIZE, 0);
+	pool_base = odp_shm_addr(shm);
 
 	pool = odp_buffer_pool_create("msg_pool", pool_base, MSG_POOL_SIZE,
 				      BUF_SIZE,