aboutsummaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
authorPetri Savolainen <petri.savolainen@linaro.org>2014-09-23 13:45:31 +0300
committerMaxim Uvarov <maxim.uvarov@linaro.org>2014-09-23 17:01:44 +0400
commitddfeadfe61c2913ca44dd424a118d5e8c7b9b3d3 (patch)
tree8ad9ecaa613ea8f57b8c51958967191dd643619c /platform
parent50fd9738f2d2cc121c083a843da7c46d1d34bc8b (diff)
Shared memory handle
- 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> Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
Diffstat (limited to 'platform')
-rw-r--r--platform/linux-generic/include/api/odp_shared_memory.h48
-rw-r--r--platform/linux-generic/odp_buffer_pool.c9
-rw-r--r--platform/linux-generic/odp_crypto.c7
-rw-r--r--platform/linux-generic/odp_packet_io.c9
-rw-r--r--platform/linux-generic/odp_queue.c9
-rw-r--r--platform/linux-generic/odp_ring.c5
-rw-r--r--platform/linux-generic/odp_schedule.c15
-rw-r--r--platform/linux-generic/odp_shared_memory.c124
8 files changed, 170 insertions, 56 deletions
diff --git a/platform/linux-generic/include/api/odp_shared_memory.h b/platform/linux-generic/include/api/odp_shared_memory.h
index 7d9fedd1b..7ad29c3cc 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 f54a0c440..4d9ff4510 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 2942a8413..12d027269 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 944c1d4e2..06d89350c 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 98525984a..1318bcd3d 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 c415d7fa1..632aa6606 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 16ae4af01..1bf819b7b 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 3d1e12a22..1898a3434 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;
}