@@ -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);
@@ -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;
@@ -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:");
}
@@ -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);
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.milard@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(-) -- 2.7.4