The odp shared_memory API is changed to use the ODP internal memory
allocator: _ishm.
_ishm supports memory sharing between processes, regardless of fork time.
The test testing the ODP_SHM_PROC flag is also changed to cope with the
new OS sharing interface used by _ishm (link in /tmp).

Signed-off-by: Christophe Milard <christophe.mil...@linaro.org>
---
 platform/linux-generic/include/odp_internal.h      |   5 -
 platform/linux-generic/odp_init.c                  |  19 -
 platform/linux-generic/odp_shared_memory.c         | 405 ++-------------------
 .../validation/api/shmem/shmem_linux.c             |  23 +-
 4 files changed, 38 insertions(+), 414 deletions(-)

diff --git a/platform/linux-generic/include/odp_internal.h 
b/platform/linux-generic/include/odp_internal.h
index 6ea8cf0..e9d03bb 100644
--- a/platform/linux-generic/include/odp_internal.h
+++ b/platform/linux-generic/include/odp_internal.h
@@ -61,7 +61,6 @@ enum init_stage {
        SYSINFO_INIT,
        FDSERVER_INIT,
        ISHM_INIT,
-       SHM_INIT,
        THREAD_INIT,
        POOL_INIT,
        QUEUE_INIT,
@@ -91,10 +90,6 @@ int odp_thread_init_local(odp_thread_type_t type);
 int odp_thread_term_local(void);
 int odp_thread_term_global(void);
 
-int odp_shm_init_global(void);
-int odp_shm_term_global(void);
-int odp_shm_init_local(void);
-
 int odp_pool_init_global(void);
 int odp_pool_init_local(void);
 int odp_pool_term_global(void);
diff --git a/platform/linux-generic/odp_init.c 
b/platform/linux-generic/odp_init.c
index d33a3ae..90662c6 100644
--- a/platform/linux-generic/odp_init.c
+++ b/platform/linux-generic/odp_init.c
@@ -63,12 +63,6 @@ int odp_init_global(odp_instance_t *instance,
        }
        stage = ISHM_INIT;
 
-       if (odp_shm_init_global()) {
-               ODP_ERR("ODP shm init failed.\n");
-               goto init_failed;
-       }
-       stage = SHM_INIT;
-
        if (odp_thread_init_global()) {
                ODP_ERR("ODP thread init failed.\n");
                goto init_failed;
@@ -223,13 +217,6 @@ int _odp_term_global(enum init_stage stage)
                }
                /* Fall through */
 
-       case SHM_INIT:
-               if (odp_shm_term_global()) {
-                       ODP_ERR("ODP shm term failed.\n");
-                       rc = -1;
-               }
-               /* Fall through */
-
        case ISHM_INIT:
                if (_odp_ishm_term_global()) {
                        ODP_ERR("ODP ishm term failed.\n");
@@ -287,12 +274,6 @@ int odp_init_local(odp_instance_t instance, 
odp_thread_type_t thr_type)
        }
        stage = ISHM_INIT;
 
-       if (odp_shm_init_local()) {
-               ODP_ERR("ODP shm local init failed.\n");
-               goto init_fail;
-       }
-       stage = SHM_INIT;
-
        if (odp_thread_init_local(thr_type)) {
                ODP_ERR("ODP thread local init failed.\n");
                goto init_fail;
diff --git a/platform/linux-generic/odp_shared_memory.c 
b/platform/linux-generic/odp_shared_memory.c
index 550af27..609b324 100644
--- a/platform/linux-generic/odp_shared_memory.c
+++ b/platform/linux-generic/odp_shared_memory.c
@@ -4,434 +4,85 @@
  * SPDX-License-Identifier:     BSD-3-Clause
  */
 
-#include <odp_posix_extensions.h>
-
-#include <odp/api/shared_memory.h>
-#include <odp_internal.h>
-#include <odp/api/spinlock.h>
-#include <odp/api/align.h>
-#include <odp/api/system_info.h>
-#include <odp/api/debug.h>
-#include <odp_shm_internal.h>
-#include <odp_debug_internal.h>
-#include <odp_align_internal.h>
 #include <odp_config_internal.h>
-
-#include <unistd.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-#include <asm/mman.h>
-#include <fcntl.h>
-
-#include <stdio.h>
+#include <odp/api/debug.h>
+#include <odp/api/std_types.h>
+#include <odp/api/shared_memory.h>
+#include <_ishm_internal.h>
 #include <string.h>
-#include <errno.h>
-#include <inttypes.h>
 
 ODP_STATIC_ASSERT(ODP_CONFIG_SHM_BLOCKS >= ODP_CONFIG_POOLS,
                  "ODP_CONFIG_SHM_BLOCKS < ODP_CONFIG_POOLS");
 
-typedef struct {
-       char      name[ODP_SHM_NAME_LEN];
-       uint64_t  size;
-       uint64_t  align;
-       uint64_t  alloc_size;
-       void      *addr_orig;
-       void      *addr;
-       int       huge;
-       odp_shm_t hdl;
-       uint32_t  flags;
-       uint64_t  page_sz;
-       int       fd;
-
-} odp_shm_block_t;
-
-
-typedef struct {
-       odp_shm_block_t block[ODP_CONFIG_SHM_BLOCKS];
-       odp_spinlock_t  lock;
-
-} odp_shm_table_t;
-
-
-#ifndef MAP_ANONYMOUS
-#define MAP_ANONYMOUS MAP_ANON
-#endif
-
-
-/* Global shared memory table */
-static odp_shm_table_t *odp_shm_tbl;
-
-
 static inline uint32_t from_handle(odp_shm_t shm)
 {
        return _odp_typeval(shm) - 1;
 }
 
-
 static inline odp_shm_t to_handle(uint32_t index)
 {
        return _odp_cast_scalar(odp_shm_t, index + 1);
 }
 
-
-int odp_shm_init_global(void)
-{
-       void *addr;
-
-#ifndef MAP_HUGETLB
-       ODP_DBG("NOTE: mmap does not support huge pages\n");
-#endif
-
-       addr = mmap(NULL, sizeof(odp_shm_table_t),
-                   PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
-
-       if (addr == MAP_FAILED)
-               return -1;
-
-       odp_shm_tbl = addr;
-
-       memset(odp_shm_tbl, 0, sizeof(odp_shm_table_t));
-       odp_spinlock_init(&odp_shm_tbl->lock);
-
-       return 0;
-}
-
-int odp_shm_term_global(void)
-{
-       int ret;
-
-       ret = munmap(odp_shm_tbl, sizeof(odp_shm_table_t));
-       if (ret)
-               ODP_ERR("unable to munmap\n.");
-
-       return ret;
-}
-
-
-int odp_shm_init_local(void)
-{
-       return 0;
-}
-
 int odp_shm_capability(odp_shm_capability_t *capa)
 {
        memset(capa, 0, sizeof(odp_shm_capability_t));
 
        capa->max_blocks = ODP_CONFIG_SHM_BLOCKS;
-       capa->max_size   = 0;
-       capa->max_align  = 0;
-
-       return 0;
-}
-
-static int find_block(const char *name, uint32_t *index)
-{
-       uint32_t i;
-
-       for (i = 0; i < ODP_CONFIG_SHM_BLOCKS; i++) {
-               if (strcmp(name, odp_shm_tbl->block[i].name) == 0) {
-                       /* found it */
-                       if (index != NULL)
-                               *index = i;
-
-                       return 1;
-               }
-       }
-
-       return 0;
-}
-
-int odp_shm_free(odp_shm_t shm)
-{
-       uint32_t i;
-       int ret;
-       odp_shm_block_t *block;
-       char shm_devname[SHM_DEVNAME_MAXLEN];
+       capa->max_size = 0;
+       capa->max_align = 0;
 
-       if (shm == ODP_SHM_INVALID) {
-               ODP_DBG("odp_shm_free: Invalid handle\n");
-               return -1;
-       }
-
-       i = from_handle(shm);
-
-       if (i >= ODP_CONFIG_SHM_BLOCKS) {
-               ODP_DBG("odp_shm_free: Bad handle\n");
-               return -1;
-       }
-
-       odp_spinlock_lock(&odp_shm_tbl->lock);
-
-       block = &odp_shm_tbl->block[i];
-
-       if (block->addr == NULL) {
-               ODP_DBG("odp_shm_free: Free block\n");
-               odp_spinlock_unlock(&odp_shm_tbl->lock);
-               return 0;
-       }
-
-       ret = munmap(block->addr_orig, block->alloc_size);
-       if (0 != ret) {
-               ODP_DBG("odp_shm_free: munmap failed: %s, id %u, addr %p\n",
-                       strerror(errno), i, block->addr_orig);
-               odp_spinlock_unlock(&odp_shm_tbl->lock);
-               return -1;
-       }
-
-       if (block->flags & ODP_SHM_PROC || block->flags & 
_ODP_SHM_PROC_NOCREAT) {
-               int shm_ns_id;
-
-               if (odp_global_data.ipc_ns)
-                       shm_ns_id = odp_global_data.ipc_ns;
-               else
-                       shm_ns_id = odp_global_data.main_pid;
-
-               snprintf(shm_devname, SHM_DEVNAME_MAXLEN,
-                        SHM_DEVNAME_FORMAT, shm_ns_id, block->name);
-               ret = shm_unlink(shm_devname);
-               if (0 != ret) {
-                       ODP_DBG("odp_shm_free: shm_unlink failed\n");
-                       odp_spinlock_unlock(&odp_shm_tbl->lock);
-                       return -1;
-               }
-       }
-       memset(block, 0, sizeof(odp_shm_block_t));
-       odp_spinlock_unlock(&odp_shm_tbl->lock);
        return 0;
 }
 
 odp_shm_t odp_shm_reserve(const char *name, uint64_t size, uint64_t align,
                          uint32_t flags)
 {
-       uint32_t i;
-       char shm_devname[SHM_DEVNAME_MAXLEN];
-       odp_shm_block_t *block;
-       void *addr;
-       int fd = -1;
-       int map_flag = MAP_SHARED;
-       /* If already exists: O_EXCL: error, O_TRUNC: truncate to zero */
-       int oflag = O_RDWR;
-       uint64_t alloc_size;
-       uint64_t page_sz, huge_sz;
-#ifdef MAP_HUGETLB
-       int need_huge_page = 0;
-       uint64_t alloc_hp_size;
-#endif
-
-       page_sz = odp_sys_page_size();
-       alloc_size = size + align;
-
-#ifdef MAP_HUGETLB
-       huge_sz = odp_sys_huge_page_size();
-       need_huge_page =  (huge_sz && alloc_size > page_sz);
-       /* munmap for huge pages requires sizes round up by page */
-       alloc_hp_size = (size + align + (huge_sz - 1)) & (-huge_sz);
-#endif
+       int block_index;
+       int flgs = 0; /* internal ishm flags */
 
-       if (flags & ODP_SHM_PROC)
-               oflag |= O_CREAT | O_TRUNC;
-       if (flags & _ODP_SHM_O_EXCL)
-               oflag |= O_EXCL;
+       /* set internal ishm flags according to API flags: */
+       flgs |= (flags & ODP_SHM_PROC) ? _ODP_ISHM_LINK : 0;
 
-       if (flags & (ODP_SHM_PROC | _ODP_SHM_PROC_NOCREAT)) {
-               int shm_ns_id;
-
-               if (odp_global_data.ipc_ns)
-                       shm_ns_id = odp_global_data.ipc_ns;
-               else
-                       shm_ns_id = odp_global_data.main_pid;
-
-               need_huge_page = 0;
-
-               /* Creates a file to /dev/shm/odp */
-               snprintf(shm_devname, SHM_DEVNAME_MAXLEN,
-                        SHM_DEVNAME_FORMAT, shm_ns_id, name);
-               fd = shm_open(shm_devname, oflag,
-                             S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
-               if (fd == -1) {
-                       ODP_DBG("%s: shm_open failed.\n", shm_devname);
-                       return ODP_SHM_INVALID;
-               }
-       } else {
-               map_flag |= MAP_ANONYMOUS;
-       }
-
-       odp_spinlock_lock(&odp_shm_tbl->lock);
-
-       if (find_block(name, NULL)) {
-               /* Found a block with the same name */
-               odp_spinlock_unlock(&odp_shm_tbl->lock);
-               ODP_DBG("name \"%s\" already used.\n", name);
+       block_index = _odp_ishm_reserve(name, size, -1, align, flgs, flags);
+       if (block_index >= 0)
+               return to_handle(block_index);
+       else
                return ODP_SHM_INVALID;
-       }
-
-       for (i = 0; i < ODP_CONFIG_SHM_BLOCKS; i++) {
-               if (odp_shm_tbl->block[i].addr == NULL) {
-                       /* Found free block */
-                       break;
-               }
-       }
-
-       if (i > ODP_CONFIG_SHM_BLOCKS - 1) {
-               /* Table full */
-               odp_spinlock_unlock(&odp_shm_tbl->lock);
-               ODP_DBG("%s: no more blocks.\n", name);
-               return ODP_SHM_INVALID;
-       }
-
-       block = &odp_shm_tbl->block[i];
-
-       block->hdl  = to_handle(i);
-       addr        = MAP_FAILED;
-
-#ifdef MAP_HUGETLB
-       /* Try first huge pages */
-       if (need_huge_page) {
-               if ((flags & ODP_SHM_PROC) &&
-                   (ftruncate(fd, alloc_hp_size) == -1)) {
-                       odp_spinlock_unlock(&odp_shm_tbl->lock);
-                       ODP_DBG("%s: ftruncate huge pages failed.\n", name);
-                       return ODP_SHM_INVALID;
-               }
-
-               addr = mmap(NULL, alloc_hp_size, PROT_READ | PROT_WRITE,
-                               map_flag | MAP_HUGETLB, fd, 0);
-               if (addr == MAP_FAILED) {
-                       ODP_DBG(" %s:\n"
-                               "\tNo huge pages, fall back to normal pages,\n"
-                               "\tcheck: /proc/sys/vm/nr_hugepages.\n", name);
-               } else {
-                       block->alloc_size = alloc_hp_size;
-                       block->huge = 1;
-                       block->page_sz = huge_sz;
-               }
-       }
-#endif
-
-       /* Use normal pages for small or failed huge page allocations */
-       if (addr == MAP_FAILED) {
-               if ((flags & ODP_SHM_PROC) &&
-                   (ftruncate(fd, alloc_size) == -1)) {
-                       odp_spinlock_unlock(&odp_shm_tbl->lock);
-                       ODP_ERR("%s: ftruncate failed.\n", name);
-                       return ODP_SHM_INVALID;
-               }
-
-               addr = mmap(NULL, alloc_size, PROT_READ | PROT_WRITE,
-                               map_flag, fd, 0);
-               if (addr == MAP_FAILED) {
-                       odp_spinlock_unlock(&odp_shm_tbl->lock);
-                       ODP_DBG("%s mmap failed.\n", name);
-                       return ODP_SHM_INVALID;
-               } else {
-                       block->alloc_size = alloc_size;
-                       block->huge = 0;
-                       block->page_sz = page_sz;
-               }
-       }
-
-       block->addr_orig = addr;
-
-       /* move to correct alignment */
-       addr = ODP_ALIGN_ROUNDUP_PTR(addr, align);
-
-       strncpy(block->name, name, ODP_SHM_NAME_LEN - 1);
-       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 block->hdl;
+int odp_shm_free(odp_shm_t shm)
+{
+       return _odp_ishm_free_by_index(from_handle(shm));
 }
 
 odp_shm_t odp_shm_lookup(const char *name)
 {
-       uint32_t i;
-       odp_shm_t hdl;
-
-       odp_spinlock_lock(&odp_shm_tbl->lock);
-
-       if (find_block(name, &i) == 0) {
-               odp_spinlock_unlock(&odp_shm_tbl->lock);
-               return ODP_SHM_INVALID;
-       }
-
-       hdl = odp_shm_tbl->block[i].hdl;
-       odp_spinlock_unlock(&odp_shm_tbl->lock);
-
-       return hdl;
+       return to_handle(_odp_ishm_lookup_by_name(name));
 }
 
-
 void *odp_shm_addr(odp_shm_t shm)
 {
-       uint32_t i;
-
-       i = from_handle(shm);
-
-       if (i > (ODP_CONFIG_SHM_BLOCKS - 1))
-               return NULL;
-
-       return odp_shm_tbl->block[i].addr;
+       return _odp_ishm_address(from_handle(shm));
 }
 
-
 int odp_shm_info(odp_shm_t shm, odp_shm_info_t *info)
 {
-       odp_shm_block_t *block;
-       uint32_t i;
+       _odp_ishm_info_t ishm_info;
 
-       i = from_handle(shm);
-
-       if (i > (ODP_CONFIG_SHM_BLOCKS - 1))
+       if (_odp_ishm_info(from_handle(shm), &ishm_info))
                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;
+       info->name = ishm_info.name;
+       info->addr = ishm_info.addr;
+       info->size = ishm_info.size;
+       info->page_size = ishm_info.page_size;
+       info->flags = ishm_info.user_flags;
 
        return 0;
 }
 
-
 void odp_shm_print_all(void)
 {
-       int i;
-
-       ODP_PRINT("\nShared memory\n");
-       ODP_PRINT("--------------\n");
-       ODP_PRINT("  page size:      %"PRIu64" kB\n",
-                 odp_sys_page_size() / 1024);
-       ODP_PRINT("  huge page size: %"PRIu64" kB\n",
-                 odp_sys_huge_page_size() / 1024);
-       ODP_PRINT("\n");
-
-       ODP_PRINT("  id name                       kB align huge addr\n");
-
-       for (i = 0; i < ODP_CONFIG_SHM_BLOCKS; i++) {
-               odp_shm_block_t *block;
-
-               block = &odp_shm_tbl->block[i];
-
-               if (block->addr) {
-                       ODP_PRINT("  %2i %-24s %4"PRIu64"  %4"PRIu64
-                                 " %2c   %p\n",
-                                 i,
-                                 block->name,
-                                 block->size/1024,
-                                 block->align,
-                                 (block->huge ? '*' : ' '),
-                                 block->addr);
-               }
-       }
-
-       ODP_PRINT("\n");
+       _odp_ishm_status("Memory allocation status:");
 }
diff --git a/test/linux-generic/validation/api/shmem/shmem_linux.c 
b/test/linux-generic/validation/api/shmem/shmem_linux.c
index 212a6c1..7e2ff04 100644
--- a/test/linux-generic/validation/api/shmem/shmem_linux.c
+++ b/test/linux-generic/validation/api/shmem/shmem_linux.c
@@ -48,9 +48,9 @@
 #include "shmem_linux.h"
 #include "shmem_common.h"
 
-#define ODP_APP_NAME "shmem_odp" /* name of the odp program, in this dir */
-#define DEVNAME_FMT "odp-%d-%s"  /* shm device format: odp-<pid>-<name>  */
-#define MAX_FIFO_WAIT 30         /* Max time waiting for the fifo (sec)  */
+#define ODP_APP_NAME "shmem_odp" /* name of the odp program, in this dir     */
+#define DEVNAME_FMT "/tmp/odp-%d-shm-%s"  /* shm link: odp-<pid>-shm-<name>  */
+#define MAX_FIFO_WAIT 30         /* Max time waiting for the fifo (sec)      */
 
 void test_success(char *fifo_name, int fd, pid_t odp_app)
 {
@@ -134,23 +134,20 @@ int main(int argc __attribute__((unused)), char *argv[])
 
        /* O_CREAT flag not given => failure if shm_devname does not already
         * exist */
-       shm_fd = shm_open(shm_devname, O_RDONLY,
-                         S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+       shm_fd = open(shm_devname, O_RDONLY,
+                     S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
        if (shm_fd == -1)
                test_failure(fifo_name, shm_fd, odp_app);
 
-       /* we know that the linux generic ODP actually allocates the required
-        * size + alignment and aligns the returned address after.
-        * we must do the same here: */
-       size = sizeof(test_shared_linux_data_t) + ALIGN_SIZE;
+       /* linux ODP guarantees page size alignement. Larger alignment may
+        * fail as 2 different processes will have fully unrelated
+        * virtual spaces.
+        */
+       size = sizeof(test_shared_linux_data_t);
        addr = mmap(NULL, size, PROT_READ, MAP_SHARED, shm_fd, 0);
        if (addr == MAP_FAILED)
                test_failure(fifo_name, shm_fd, odp_app);
 
-       /* perform manual alignment */
-       addr = (test_shared_linux_data_t *)((((unsigned long int)addr +
-                                ALIGN_SIZE - 1) / ALIGN_SIZE) * ALIGN_SIZE);
-
        /* check that we see what the ODP application wrote in the memory */
        if ((addr->foo == TEST_SHARE_FOO) && (addr->bar == TEST_SHARE_BAR))
                test_success(fifo_name, fifo_fd, odp_app);
-- 
2.7.4

Reply via email to