diff mbox

[1/3] Shared memory handle

Message ID 1410355344-2938-1-git-send-email-petri.savolainen@linaro.org
State New
Headers show

Commit Message

Petri Savolainen Sept. 10, 2014, 1:22 p.m. UTC
- Changed API to return shm handle instead of pointer
- Added shm info

Signed-off-by: Petri Savolainen <petri.savolainen@linaro.org>
---
 .../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                  |  11 +-
 platform/linux-generic/odp_schedule.c              |  15 ++-
 platform/linux-generic/odp_shared_memory.c         | 124 +++++++++++++++------
 8 files changed, 175 insertions(+), 57 deletions(-)

Comments

Maxim Uvarov Sept. 22, 2014, 9:49 a.m. UTC | #1
Reviewed-by: Maxim Uvarov <maxim.uvarov@linaro.org>

Petri, please merge this patch with test patches and add crypto and ks2 
fixes to final patch.

Thanks,
Maxim.

On 09/10/2014 05:22 PM, Petri Savolainen wrote:
> - Changed API to return shm handle instead of pointer
> - Added shm info
>
> Signed-off-by: Petri Savolainen <petri.savolainen@linaro.org>
> ---
>   .../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                  |  11 +-
>   platform/linux-generic/odp_schedule.c              |  15 ++-
>   platform/linux-generic/odp_shared_memory.c         | 124 +++++++++++++++------
>   8 files changed, 175 insertions(+), 57 deletions(-)
>
> 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 3e72952..a4079aa 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 */
> @@ -549,7 +552,11 @@ void odph_ring_list_dump(void)
>   /* search a ring from its name */
>   odph_ring_t *odph_ring_lookup(const char *name)
>   {
> -	odph_ring_t *r = odp_shm_lookup(name);
> +	odp_shm_t shm;
> +	odph_ring_t *r;
> +
> +	shm = odp_shm_lookup(name);
> +	r   = odp_shm_addr(shm);
>   
>   	odp_rwlock_read_lock(&qlock);
>   	TAILQ_FOREACH(r, &odp_ring_list, next) {
> 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;
>   }
>   
>
Savolainen, Petri (NSN - FI/Espoo) Sept. 22, 2014, 12:06 p.m. UTC | #2
> -----Original Message-----
> From: lng-odp-bounces@lists.linaro.org [mailto:lng-odp-
> bounces@lists.linaro.org] On Behalf Of ext Maxim Uvarov
> Sent: Monday, September 22, 2014 12:49 PM
> To: lng-odp@lists.linaro.org
> Subject: Re: [lng-odp] [PATCH 1/3] Shared memory handle
> 
> Reviewed-by: Maxim Uvarov <maxim.uvarov@linaro.org>
> 
> Petri, please merge this patch with test patches and add crypto and ks2
> fixes to final patch.
> 
> Thanks,
> Maxim.


OK. So, it's not required anymore that implementation and test app modifications are sent in separate patches.

-Petri
Maxim Uvarov Sept. 22, 2014, 12:10 p.m. UTC | #3
On 09/22/2014 04:06 PM, Savolainen, Petri (NSN - FI/Espoo) wrote:
>
>> -----Original Message-----
>> From: lng-odp-bounces@lists.linaro.org [mailto:lng-odp-
>> bounces@lists.linaro.org] On Behalf Of ext Maxim Uvarov
>> Sent: Monday, September 22, 2014 12:49 PM
>> To: lng-odp@lists.linaro.org
>> Subject: Re: [lng-odp] [PATCH 1/3] Shared memory handle
>>
>> Reviewed-by: Maxim Uvarov <maxim.uvarov@linaro.org>
>>
>> Petri, please merge this patch with test patches and add crypto and ks2
>> fixes to final patch.
>>
>> Thanks,
>> Maxim.
>
> OK. So, it's not required anymore that implementation and test app modifications are sent in separate patches.
>
> -Petri
It's required to be sent for review. It's much more clear to review 
that. But I'm trying to make git friendly with 'git bisect' command.
So and any slice we can compile it. And I can merge all commits that 
commits just before pushing to repo. Or if they were reviewed you
can merge them.

Thanks,
Maxim.
diff mbox

Patch

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 3e72952..a4079aa 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 */
@@ -549,7 +552,11 @@  void odph_ring_list_dump(void)
 /* search a ring from its name */
 odph_ring_t *odph_ring_lookup(const char *name)
 {
-	odph_ring_t *r = odp_shm_lookup(name);
+	odp_shm_t shm;
+	odph_ring_t *r;
+
+	shm = odp_shm_lookup(name);
+	r   = odp_shm_addr(shm);
 
 	odp_rwlock_read_lock(&qlock);
 	TAILQ_FOREACH(r, &odp_ring_list, next) {
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;
 }