This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "".
The branch, master has been updated
via 6c2c1bbf83a2a69b99d28baecfc8bd3421b651d6 (commit)
from 35525f70aa68e55dca6b05cf59a515c50e7dcba2 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 6c2c1bbf83a2a69b99d28baecfc8bd3421b651d6
Author: Maxim Uvarov <maxim.uvarov(a)linaro.org>
Date: Fri Nov 16 16:47:02 2018 +0300
travis: define compiler for clang test
without specifying compiler CC falls back to default gcc
after it was initialized to clang. Current change forces
test to use clang.
Signed-off-by: Maxim Uvarov <maxim.uvarov(a)linaro.org>
Reviewed-by: Petri Savolainen <petri.savolainen(a)linaro.org>
diff --git a/.travis.yml b/.travis.yml
index d06530ce..f2b87b7b 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -231,7 +231,8 @@ jobs:
-e CC="${CC}"
${DOCKER_NAMESPACE}/travis-odp-lng-ubuntu_16.04 /odp/scripts/ci/build_${ARCH}.sh
- stage: "build only"
- env: ARCH=x86_64 CC=clang
+ env: ARCH=x86_64
+ compiler: clang
install:
- true
script:
-----------------------------------------------------------------------
Summary of changes:
.travis.yml | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
hooks/post-receive
--
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "".
The branch, master has been updated
via 1c1118ee10c209bac716f9368bbbbd47a74b62ef (commit)
via 7c7194c3da746e435044829fcd1f38b8011e386d (commit)
via b181d885962969f439d9cd6f828fb66007ddedcb (commit)
via bc9a1f01b55da44053a233acd4110def04f208fe (commit)
via 41eff89ad670eb3bc889ba3b1d9b16d45cb4fdb3 (commit)
via 93f315dfdd3fa77bca5ceef2d487aec0dc55c92e (commit)
via 458120cb0507fd143db4f122a9adb3651468712d (commit)
via 661140b119ea0dfc516025869ffce5d215537745 (commit)
via 68578a2b61e2afdf4655b61ed8f5d023b16b4846 (commit)
from 0ce0f29c5cc10320eb7f0741788f551cdf2c6903 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 1c1118ee10c209bac716f9368bbbbd47a74b62ef
Author: Maxim Uvarov <maxim.uvarov(a)linaro.org>
Date: Tue Nov 13 12:17:47 2018 +0300
linux-gen: run without /proc mounted
Some systems may have /proc interface not mounted, let
odp linux generic run there with dummy values.
https://bugs.linaro.org/show_bug.cgi?id=3989
Signed-off-by: Maxim Uvarov <maxim.uvarov(a)linaro.org>
Dmitry Eremin-Solenikov <dmitry.ereminsolenikov(a)linaro.org>
diff --git a/platform/linux-generic/arch/aarch64/odp_sysinfo_parse.c b/platform/linux-generic/arch/aarch64/odp_sysinfo_parse.c
index 85aec6a6..bcdc2373 100644
--- a/platform/linux-generic/arch/aarch64/odp_sysinfo_parse.c
+++ b/platform/linux-generic/arch/aarch64/odp_sysinfo_parse.c
@@ -12,7 +12,6 @@
#include <odp_sysinfo_internal.h>
#include <odp_debug_internal.h>
-#define DUMMY_MAX_MHZ 1000
#define TMP_STR_LEN 64
static void aarch64_impl_str(char *str, int maxlen, int implementer)
diff --git a/platform/linux-generic/arch/default/odp_sysinfo_parse.c b/platform/linux-generic/arch/default/odp_sysinfo_parse.c
index b9378887..da3f2eb3 100644
--- a/platform/linux-generic/arch/default/odp_sysinfo_parse.c
+++ b/platform/linux-generic/arch/default/odp_sysinfo_parse.c
@@ -7,24 +7,10 @@
#include "config.h"
#include <odp_sysinfo_internal.h>
-#include <odp_debug_internal.h>
-#include <string.h>
-
-#define DUMMY_MAX_MHZ 1400
int cpuinfo_parser(FILE *file ODP_UNUSED, system_info_t *sysinfo)
{
- int i;
-
- ODP_DBG("Warning: use dummy values for freq and model string\n");
- for (i = 0; i < CONFIG_NUM_CPU; i++) {
- ODP_PRINT("WARN: cpu[%i] uses dummy max frequency %u MHz\n",
- i, DUMMY_MAX_MHZ);
- sysinfo->cpu_hz_max[i] = DUMMY_MAX_MHZ * 1000000;
- strcpy(sysinfo->model_str[i], "UNKNOWN");
- }
-
- return 0;
+ return _odp_dummy_cpuinfo(sysinfo);
}
void sys_info_print_arch(void)
diff --git a/platform/linux-generic/arch/x86/odp_sysinfo_parse.c b/platform/linux-generic/arch/x86/odp_sysinfo_parse.c
index 5084e6b5..7124e84f 100644
--- a/platform/linux-generic/arch/x86/odp_sysinfo_parse.c
+++ b/platform/linux-generic/arch/x86/odp_sysinfo_parse.c
@@ -83,6 +83,8 @@ uint64_t odp_cpu_arch_hz_current(int id)
double mhz = 0.0;
file = fopen("/proc/cpuinfo", "rt");
+ if (!file)
+ return 0;
/* find the correct processor instance */
while (fgets(str, sizeof(str), file) != NULL) {
diff --git a/platform/linux-generic/include/odp_sysinfo_internal.h b/platform/linux-generic/include/odp_sysinfo_internal.h
index 2f01d18e..49254230 100644
--- a/platform/linux-generic/include/odp_sysinfo_internal.h
+++ b/platform/linux-generic/include/odp_sysinfo_internal.h
@@ -12,12 +12,31 @@ extern "C" {
#endif
#include <odp_global_data.h>
+#include <odp_debug_internal.h>
+#include <string.h>
+
+#define DUMMY_MAX_MHZ 1400
int cpuinfo_parser(FILE *file, system_info_t *sysinfo);
uint64_t odp_cpu_hz_current(int id);
uint64_t odp_cpu_arch_hz_current(int id);
void sys_info_print_arch(void);
+static inline int _odp_dummy_cpuinfo(system_info_t *sysinfo)
+{
+ int i;
+
+ ODP_DBG("Warning: use dummy values for freq and model string\n");
+ for (i = 0; i < CONFIG_NUM_CPU; i++) {
+ ODP_PRINT("WARN: cpu[%i] uses dummy max frequency %u MHz\n",
+ i, DUMMY_MAX_MHZ);
+ sysinfo->cpu_hz_max[i] = DUMMY_MAX_MHZ * 1000000;
+ strcpy(sysinfo->model_str[i], "UNKNOWN");
+ }
+
+ return 0;
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/platform/linux-generic/odp_system_info.c b/platform/linux-generic/odp_system_info.c
index 733c3528..a7a78d27 100644
--- a/platform/linux-generic/odp_system_info.c
+++ b/platform/linux-generic/odp_system_info.c
@@ -96,6 +96,8 @@ static uint64_t default_huge_page_size(void)
FILE *file;
file = fopen("/proc/meminfo", "rt");
+ if (!file)
+ return 0;
while (fgets(str, sizeof(str), file) != NULL) {
if (sscanf(str, "Hugepagesize: %8lu kB", &sz) == 1) {
@@ -352,16 +354,15 @@ int odp_system_info_init(void)
}
file = fopen("/proc/cpuinfo", "rt");
- if (file == NULL) {
- ODP_ERR("Failed to open /proc/cpuinfo\n");
- return -1;
+ if (file != NULL) {
+ /* Read CPU model, and set max cpu frequency
+ * if not set from cpufreq. */
+ cpuinfo_parser(file, &odp_global_ro.system_info);
+ fclose(file);
+ } else {
+ _odp_dummy_cpuinfo(&odp_global_ro.system_info);
}
- /* Read CPU model, and set max cpu frequency if not set from cpufreq. */
- cpuinfo_parser(file, &odp_global_ro.system_info);
-
- fclose(file);
-
if (systemcpu(&odp_global_ro.system_info)) {
ODP_ERR("systemcpu failed\n");
return -1;
commit 7c7194c3da746e435044829fcd1f38b8011e386d
Author: Matias Elo <matias.elo(a)nokia.com>
Date: Wed Oct 24 09:12:20 2018 +0300
linux-gen: ishm: use pre-reserved single va memory
Reserve single VA memory in global init instead of only allocating the
address space. Allocating only the address space doesn't work if shm blocks
are reserved after ODP process has been forked.
Signed-off-by: Matias Elo <matias.elo(a)nokia.com>
Reviewed-by: Bill Fischofer <bill.fischofer(a)linaro.org>
Signed-off-by: Maxim Uvarov <maxim.uvarov(a)linaro.org>
diff --git a/.travis.yml b/.travis.yml
index 4e29102f..3510d380 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -214,7 +214,7 @@ jobs:
- true
script:
- if [ -z "${DOCKER_NAMESPACE}" ] ; then export DOCKER_NAMESPACE="opendataplane"; fi
- - docker run -i -t -v `pwd`:/odp
+ - docker run -i -t -v `pwd`:/odp --shm-size 8g
-e CC="${CC}"
${DOCKER_NAMESPACE}/travis-odp-lng-ubuntu_16.04 /odp/scripts/ci/build_${ARCH}.sh
- stage: "build only"
@@ -223,7 +223,7 @@ jobs:
- true
script:
- if [ -z "${DOCKER_NAMESPACE}" ] ; then export DOCKER_NAMESPACE="opendataplane"; fi
- - docker run -i -t -v `pwd`:/odp
+ - docker run -i -t -v `pwd`:/odp --shm-size 8g
-e CC="${CC}"
${DOCKER_NAMESPACE}/travis-odp-lng-ubuntu_16.04 /odp/scripts/ci/build_${ARCH}.sh
- stage: "build only"
@@ -232,7 +232,7 @@ jobs:
- true
script:
- if [ -z "${DOCKER_NAMESPACE}" ] ; then export DOCKER_NAMESPACE="opendataplane"; fi
- - docker run -i -t -v `pwd`:/odp
+ - docker run -i -t -v `pwd`:/odp
-e CC="${CC}"
${DOCKER_NAMESPACE}/travis-odp-lng-ubuntu_16.04 /odp/scripts/ci/build_${ARCH}.sh
- stage: "build only"
@@ -241,7 +241,7 @@ jobs:
- true
script:
- if [ -z "${DOCKER_NAMESPACE}" ] ; then export DOCKER_NAMESPACE="opendataplane"; fi
- - docker run -i -t -v `pwd`:/odp
+ - docker run -i -t -v `pwd`:/odp --shm-size 8g
-e CC="${CC}"
${DOCKER_NAMESPACE}/travis-odp-lng-ubuntu_16.04 /odp/scripts/ci/build_${ARCH}.sh
- stage: test
diff --git a/platform/linux-generic/include/odp_ishmphy_internal.h b/platform/linux-generic/include/odp_ishmphy_internal.h
index 05e3fcec..2bc9911c 100644
--- a/platform/linux-generic/include/odp_ishmphy_internal.h
+++ b/platform/linux-generic/include/odp_ishmphy_internal.h
@@ -13,9 +13,9 @@ extern "C" {
#include <stdint.h>
-void *_odp_ishmphy_book_va(uintptr_t len, intptr_t align);
-int _odp_ishmphy_unbook_va(void);
-void *_odp_ishmphy_map(int fd, void *start, uint64_t size, int flags);
+void *_odp_ishmphy_reserve_single_va(uint64_t len, int fd);
+int _odp_ishmphy_free_single_va(void);
+void *_odp_ishmphy_map(int fd, uint64_t size, uint64_t offset, int flags);
int _odp_ishmphy_unmap(void *start, uint64_t len, int flags);
#ifdef __cplusplus
diff --git a/platform/linux-generic/include/odp_shm_internal.h b/platform/linux-generic/include/odp_shm_internal.h
index 9da5082d..c98f07de 100644
--- a/platform/linux-generic/include/odp_shm_internal.h
+++ b/platform/linux-generic/include/odp_shm_internal.h
@@ -38,7 +38,7 @@ odp_shm_t _odp_shm_reserve(const char *name, uint64_t size, uint32_t align,
uint32_t flags, uint32_t extra_flags);
int _odp_ishm_reserve(const char *name, uint64_t size, int fd, uint32_t align,
- uint32_t flags, uint32_t user_flags);
+ uint64_t offset, uint32_t flags, uint32_t user_flags);
int _odp_ishm_free_by_index(int block_index);
int _odp_ishm_lookup_by_name(const char *name);
int _odp_ishm_find_exported(const char *remote_name,
diff --git a/platform/linux-generic/odp_ishm.c b/platform/linux-generic/odp_ishm.c
index f8af8f79..a66d9fab 100644
--- a/platform/linux-generic/odp_ishm.c
+++ b/platform/linux-generic/odp_ishm.c
@@ -14,32 +14,20 @@
* internal shared memory is guaranteed to always be located at the same virtual
* address, i.e. pointers to internal shared memory are fully shareable
* between odp threads (regardless of thread type or fork time) in that case.
- * Internal shared memory is mainly meant to be used internaly within ODP
+ * Internal shared memory is mainly meant to be used internally within ODP
* (hence its name), but may also be allocated by odp applications and drivers,
* in the future (through these interfaces).
* To guarantee this full pointer shareability (when reserved with the
- * _ODP_ISHM_SINGLE_VA flag) internal shared memory is handled as follows:
- * At global_init time, a huge virtual address space reservation is performed.
- * Note that this is just reserving virtual space, not physical memory.
+ * _ODP_ISHM_SINGLE_VA flag) the whole internal shared memory area is reserved
+ * at global_init time.
* Because all ODP threads (pthreads or processes) are descendants of the ODP
- * instantiation process, this VA space is inherited by all ODP threads.
- * When internal shmem reservation actually occurs, and
- * when reserved with the _ODP_ISHM_SINGLE_VA flag, physical memory is
- * allocated, and mapped (MAP_FIXED) to some part in the huge preallocated
- * address space area:
- * because this virtual address space is common to all ODP threads, we
- * know this mapping will succeed, and not clash with anything else.
- * Hence, an ODP threads which perform a lookup for the same ishm block
- * can map it at the same VA address.
- * When internal shared memory is released, the physical memory is released
- * and the corresponding virtual space returned to its "pool" of preallocated
- * virtual space (assuming it was allocated from there).
- * Note, though, that, if 2 linux processes share the same ishm block,
- * the virtual space is marked as released as soon as one of the processes
- * releases the ishm block, but the physical memory space is actually released
- * by the kernel once all processes have done a ishm operation (i,e. a sync).
- * This is due to the fact that linux does not contain any syscall to unmap
- * memory from a different process.
+ * instantiation process, this address space is inherited by all ODP threads.
+ * When internal shmem reservation actually occurs, and when reserved with the
+ * _ODP_ISHM_SINGLE_VA flag, memory is allocated from the pre-reserved single
+ * VA memory.
+ * When an internal shared memory block is released, the memory is returned to
+ * its "pool" of pre-reserved memory (assuming it was allocated from there). The
+ * memory is not returned back to kernel until odp_term_global().
*
* This file contains functions to handle the VA area (handling fragmentation
* and defragmentation resulting from different allocs/release) and also
@@ -145,6 +133,8 @@
#define EXPORT_FILE_LINE6_FMT "user_length: %" PRIu64
#define EXPORT_FILE_LINE7_FMT "user_flags: %" PRIu32
#define EXPORT_FILE_LINE8_FMT "align: %" PRIu32
+#define EXPORT_FILE_LINE9_FMT "offset: %" PRIu64
+
/*
* A fragment describes a piece of the shared virtual address space,
* and is allocated only when allocation is done with the _ODP_ISHM_SINGLE_VA
@@ -181,6 +171,7 @@ typedef struct ishm_block {
uint32_t flags; /* block creation flags. */
uint32_t external_fd:1; /* block FD was externally provided */
uint64_t user_len; /* length, as requested at reserve time. */
+ uint64_t offset; /* offset from beginning of the fd */
void *start; /* only valid if _ODP_ISHM_SINGLE_VA is set*/
uint64_t len; /* length. multiple of page size. 0 if free*/
ishm_fragment_t *fragment; /* used when _ODP_ISHM_SINGLE_VA is used */
@@ -201,6 +192,10 @@ typedef struct {
uint64_t dev_seq; /* used when creating device names */
uint32_t odpthread_cnt; /* number of running ODP threads */
ishm_block_t block[ISHM_MAX_NB_BLOCKS];
+ void *single_va_start; /* start of single VA memory */
+ int single_va_fd; /* single VA memory file descriptor */
+ odp_bool_t single_va_huge; /* single VA memory from huge pages */
+ char single_va_filename[ISHM_FILENAME_MAXLEN];
} ishm_table_t;
static ishm_table_t *ishm_tbl;
@@ -290,7 +285,7 @@ static int hp_create_file(uint64_t len, const char *filename)
}
/* commit huge page */
- addr = _odp_ishmphy_map(fd, NULL, len, 0);
+ addr = _odp_ishmphy_map(fd, len, 0, 0);
if (addr == NULL) {
/* no more pages available */
close(fd);
@@ -464,7 +459,8 @@ static void *alloc_fragment(uintptr_t size, int block_index, intptr_t align,
}
if (!(*best_fragmnt)) {
- ODP_ERR("unable to get virtual address for shmem block!\n.");
+ ODP_ERR("Out of single VA memory. Try increasing "
+ "'shm.single_va_size_kb' in ODP config.\n");
return NULL;
}
@@ -586,31 +582,84 @@ static void free_fragment(ishm_fragment_t *fragmnt)
}
}
+static char *create_seq_string(char *output, size_t size)
+{
+ snprintf(output, size, "%08" PRIu64, ishm_tbl->dev_seq++);
+
+ return output;
+}
+
+static int create_export_file(ishm_block_t *new_block, const char *name,
+ uint64_t len, uint32_t flags, uint32_t align,
+ odp_bool_t single_va, uint64_t offset)
+{
+ FILE *export_file;
+
+ snprintf(new_block->exptname, ISHM_FILENAME_MAXLEN,
+ ISHM_EXPTNAME_FORMAT,
+ odp_global_ro.shm_dir,
+ odp_global_ro.uid,
+ odp_global_ro.main_pid,
+ name);
+ export_file = fopen(new_block->exptname, "w");
+ if (export_file == NULL) {
+ ODP_ERR("open failed: err=%s.\n",
+ strerror(errno));
+ new_block->exptname[0] = 0;
+ return -1;
+ }
+
+ fprintf(export_file, EXPORT_FILE_LINE1_FMT "\n");
+ fprintf(export_file, EXPORT_FILE_LINE2_FMT "\n", new_block->name);
+ if (single_va)
+ fprintf(export_file, EXPORT_FILE_LINE3_FMT "\n",
+ ishm_tbl->single_va_filename);
+ else
+ fprintf(export_file, EXPORT_FILE_LINE3_FMT "\n",
+ new_block->filename);
+
+ fprintf(export_file, EXPORT_FILE_LINE4_FMT "\n", len);
+ fprintf(export_file, EXPORT_FILE_LINE5_FMT "\n", flags);
+ fprintf(export_file, EXPORT_FILE_LINE6_FMT "\n",
+ new_block->user_len);
+ fprintf(export_file, EXPORT_FILE_LINE7_FMT "\n",
+ new_block->user_flags);
+ fprintf(export_file, EXPORT_FILE_LINE8_FMT "\n", align);
+ fprintf(export_file, EXPORT_FILE_LINE9_FMT "\n", offset);
+
+ fclose(export_file);
+
+ return 0;
+}
+
/*
* Create file with size len. returns -1 on error
* Creates a file to /dev/shm/odp-<pid>-<sequence_or_name> (for normal pages)
- * or /mnt/huge/odp-<pid>-<sequence_or_name> (for huge pages)
+ * or /mnt/huge/odp-<pid>-<sequence_or_name> (for huge pages).
* Return the new file descriptor, or -1 on error.
*/
static int create_file(int block_index, huge_flag_t huge, uint64_t len,
- uint32_t flags, uint32_t align)
+ uint32_t flags, uint32_t align, odp_bool_t single_va)
{
char *name;
int fd;
- ishm_block_t *new_block; /* entry in the main block table */
+ ishm_block_t *new_block = NULL; /* entry in the main block table */
char seq_string[ISHM_FILENAME_MAXLEN]; /* used to construct filename*/
char filename[ISHM_FILENAME_MAXLEN]; /* filename in /dev/shm or
* /mnt/huge */
int oflag = O_RDWR | O_CREAT | O_TRUNC; /* flags for open */
- FILE *export_file;
char dir[ISHM_FILENAME_MAXLEN];
- new_block = &ishm_tbl->block[block_index];
- name = new_block->name;
-
- /* create the filename: */
- snprintf(seq_string, ISHM_FILENAME_MAXLEN, "%08" PRIu64,
- ishm_tbl->dev_seq++);
+ /* No ishm_block_t for the master single VA memory file */
+ if (single_va) {
+ name = (char *)(uintptr_t)"single_va";
+ } else {
+ new_block = &ishm_tbl->block[block_index];
+ name = new_block->name;
+ if (!name || !name[0])
+ name = create_seq_string(seq_string,
+ ISHM_FILENAME_MAXLEN);
+ }
/* huge dir must be known to create files there!: */
if ((huge == HUGE) &&
@@ -626,11 +675,8 @@ static int create_file(int block_index, huge_flag_t huge, uint64_t len,
odp_global_ro.shm_dir,
odp_global_ro.uid);
- snprintf(filename, ISHM_FILENAME_MAXLEN,
- ISHM_FILENAME_FORMAT,
- dir,
- odp_global_ro.main_pid,
- (name && name[0]) ? name : seq_string);
+ snprintf(filename, ISHM_FILENAME_MAXLEN, ISHM_FILENAME_FORMAT, dir,
+ odp_global_ro.main_pid, name);
mkdir(dir, 0744);
@@ -650,38 +696,21 @@ static int create_file(int block_index, huge_flag_t huge, uint64_t len,
return -1;
}
+ /* No export file is created since this is only for internal use.*/
+ if (single_va) {
+ snprintf(ishm_tbl->single_va_filename, ISHM_FILENAME_MAXLEN,
+ "%s", filename);
+ return fd;
+ }
/* if _ODP_ISHM_EXPORT is set, create a description file for
* external ref:
*/
if (flags & _ODP_ISHM_EXPORT) {
memcpy(new_block->filename, filename, ISHM_FILENAME_MAXLEN);
- snprintf(new_block->exptname, ISHM_FILENAME_MAXLEN,
- ISHM_EXPTNAME_FORMAT,
- odp_global_ro.shm_dir,
- odp_global_ro.uid,
- odp_global_ro.main_pid,
- (name && name[0]) ? name : seq_string);
- export_file = fopen(new_block->exptname, "w");
- if (export_file == NULL) {
- ODP_ERR("open failed: err=%s.\n",
- strerror(errno));
- new_block->exptname[0] = 0;
- } else {
- fprintf(export_file, EXPORT_FILE_LINE1_FMT "\n");
- fprintf(export_file, EXPORT_FILE_LINE2_FMT "\n", name);
- fprintf(export_file, EXPORT_FILE_LINE3_FMT "\n",
- new_block->filename);
- fprintf(export_file, EXPORT_FILE_LINE4_FMT "\n", len);
- fprintf(export_file, EXPORT_FILE_LINE5_FMT "\n", flags);
- fprintf(export_file, EXPORT_FILE_LINE6_FMT "\n",
- new_block->user_len);
- fprintf(export_file, EXPORT_FILE_LINE7_FMT "\n",
- new_block->user_flags);
- fprintf(export_file, EXPORT_FILE_LINE8_FMT "\n", align);
-
- fclose(export_file);
- }
+
+ create_export_file(new_block, name, len, flags, align, false,
+ 0);
} else {
new_block->exptname[0] = 0;
/* remove the file from the filesystem, keeping its fd open */
@@ -694,8 +723,9 @@ static int create_file(int block_index, huge_flag_t huge, uint64_t len,
/* delete the files related to a given ishm block: */
static void delete_file(ishm_block_t *block)
{
- /* remove the .../odp-* file, unless fd was external: */
- if (block->filename[0] != 0)
+ /* remove the .../odp-* file, unless fd was external or single va */
+ if (block->filename[0] != 0 &&
+ strcmp(block->filename, ishm_tbl->single_va_filename))
unlink(block->filename);
/* also remove possible description file (if block was exported): */
if (block->exptname[0] != 0)
@@ -703,20 +733,18 @@ static void delete_file(ishm_block_t *block)
}
/*
- * performs the mapping, possibly allocating a fragment of the pre-reserved
- * VA space if the _ODP_ISHM_SINGLE_VA flag was given.
- * Sets fd, and returns the mapping address.
- * This function will also set the _ODP_ISHM_SINGLE_VA flag if the alignment
- * requires it
+ * Performs the mapping.
+ * Sets fd, and returns the mapping address. Not to be used with
+ * _ODP_ISHM_SINGLE_VA blocks.
* Mutex must be assured by the caller.
*/
static void *do_map(int block_index, uint64_t len, uint32_t align,
- uint32_t flags, huge_flag_t huge, int *fd)
+ uint64_t offset, uint32_t flags, huge_flag_t huge, int *fd)
{
ishm_block_t *new_block; /* entry in the main block table */
- void *addr = NULL;
void *mapped_addr;
- ishm_fragment_t *fragment = NULL;
+
+ ODP_ASSERT(!(flags & _ODP_ISHM_SINGLE_VA));
new_block = &ishm_tbl->block[block_index];
@@ -726,33 +754,16 @@ static void *do_map(int block_index, uint64_t len, uint32_t align,
* unless a fd was already given
*/
if (*fd < 0) {
- *fd = create_file(block_index, huge, len, flags, align);
+ *fd = create_file(block_index, huge, len, flags, align, false);
if (*fd < 0)
return NULL;
} else {
new_block->filename[0] = 0;
}
- /* allocate an address range in the prebooked VA area if needed */
- if (flags & _ODP_ISHM_SINGLE_VA) {
- addr = alloc_fragment(len, block_index, align, &fragment);
- if (!addr) {
- ODP_ERR("alloc_fragment failed.\n");
- if (!new_block->external_fd) {
- close(*fd);
- *fd = -1;
- delete_file(new_block);
- }
- return NULL;
- }
- new_block->fragment = fragment;
- }
-
/* try to mmap: */
- mapped_addr = _odp_ishmphy_map(*fd, addr, len, flags);
+ mapped_addr = _odp_ishmphy_map(*fd, len, offset, flags);
if (mapped_addr == NULL) {
- if (flags & _ODP_ISHM_SINGLE_VA)
- free_fragment(fragment);
if (!new_block->external_fd) {
close(*fd);
*fd = -1;
@@ -764,37 +775,87 @@ static void *do_map(int block_index, uint64_t len, uint32_t align,
return mapped_addr;
}
+/*
+ * Allocate block from pre-reserved single VA memory
+ */
+static void *alloc_single_va(const char *name, int new_index, uint64_t size,
+ uint32_t align, uint32_t flags, int *fd,
+ uint64_t *len_out)
+{
+ uint64_t len;
+ uint64_t page_sz;
+ char *file_name = (char *)(uintptr_t)name;
+ void *addr;
+ ishm_block_t *new_block = &ishm_tbl->block[new_index];
+ ishm_fragment_t *fragment = NULL;
+ char seq_string[ISHM_FILENAME_MAXLEN];
+
+ if (!file_name || !file_name[0])
+ file_name = create_seq_string(seq_string, ISHM_FILENAME_MAXLEN);
+
+ /* Common fd for all single VA blocks */
+ *fd = ishm_tbl->single_va_fd;
+
+ if (ishm_tbl->single_va_huge) {
+ page_sz = odp_sys_huge_page_size();
+ new_block->huge = HUGE;
+ } else {
+ page_sz = odp_sys_page_size();
+ new_block->huge = NORMAL;
+ }
+ new_block->filename[0] = 0;
+
+ len = (size + (page_sz - 1)) & (-page_sz);
+
+ if (align < page_sz)
+ align = page_sz;
+
+ /* Allocate memory from the pre-reserved single VA space */
+ addr = alloc_fragment(len, new_index, align, &fragment);
+ if (!addr) {
+ ODP_ERR("alloc_fragment failed.\n");
+ return NULL;
+ }
+ new_block->fragment = fragment;
+
+ /* Create export info file */
+ if (flags & _ODP_ISHM_EXPORT) {
+ uint64_t offset = (uintptr_t)addr -
+ (uintptr_t)ishm_tbl->single_va_start;
+ memcpy(new_block->filename, ishm_tbl->single_va_filename,
+ ISHM_FILENAME_MAXLEN);
+
+ create_export_file(new_block, file_name, len, flags, align,
+ true, offset);
+ } else {
+ new_block->exptname[0] = 0;
+ }
+
+ *len_out = len;
+ return addr;
+}
+
/*
* Performs an extra mapping (for a process trying to see an existing block
- * i.e. performing a lookup).
+ * i.e. performing a lookup). Not to be used with _ODP_ISHM_SINGLE_VA blocks.
* Mutex must be assured by the caller.
*/
static void *do_remap(int block_index, int fd)
{
void *mapped_addr;
- ishm_fragment_t *fragment;
uint64_t len;
+ uint64_t offset;
uint32_t flags;
len = ishm_tbl->block[block_index].len;
+ offset = ishm_tbl->block[block_index].offset;
flags = ishm_tbl->block[block_index].flags;
- if (flags & _ODP_ISHM_SINGLE_VA) {
- fragment = ishm_tbl->block[block_index].fragment;
- if (!fragment) {
- ODP_ERR("invalid fragment failure.\n");
- return NULL;
- }
-
- /* try to mmap: */
- mapped_addr = _odp_ishmphy_map(fd, fragment->start, len, flags);
- if (mapped_addr == NULL)
- return NULL;
- return mapped_addr;
- }
+ ODP_ASSERT(!(flags & _ODP_ISHM_SINGLE_VA));
/* try to mmap: */
- mapped_addr = _odp_ishmphy_map(fd, NULL, len, flags);
+ mapped_addr = _odp_ishmphy_map(fd, len, offset, flags);
+
if (mapped_addr == NULL)
return NULL;
@@ -802,8 +863,8 @@ static void *do_remap(int block_index, int fd)
}
/*
- * Performs unmapping, possibly freeing a prereserved VA space fragment,
- * if the _ODP_ISHM_SINGLE_VA flag was set at alloc time
+ * Performs unmapping, possibly freeing a pre-reserved single VA memory
+ * fragment, if the _ODP_ISHM_SINGLE_VA flag was set at alloc time.
* Mutex must be assured by the caller.
*/
static int do_unmap(void *start, uint64_t size, uint32_t flags,
@@ -883,7 +944,9 @@ static void procsync(void)
block = &ishm_tbl->block[ishm_proctable->entry[i].block_index];
if (ishm_proctable->entry[i].seq != block->seq) {
/* obsolete entry: free memory and remove proc entry */
- close(ishm_proctable->entry[i].fd);
+ if (ishm_proctable->entry[i].fd !=
+ ishm_tbl->single_va_fd)
+ close(ishm_proctable->entry[i].fd);
_odp_ishmphy_unmap(ishm_proctable->entry[i].start,
ishm_proctable->entry[i].len,
ishm_proctable->entry[i].flags);
@@ -919,6 +982,8 @@ static int block_free_internal(int block_index, int close_fd, int deregister)
proc_index = procfind_block(block_index);
if (proc_index >= 0) {
+ int fd = ishm_proctable->entry[proc_index].fd;
+
/* remove the mapping and possible fragment */
do_unmap(ishm_proctable->entry[proc_index].start,
block->len,
@@ -926,9 +991,7 @@ static int block_free_internal(int block_index, int close_fd, int deregister)
block_index);
/* close the related fd */
- if (close_fd) {
- int fd = ishm_proctable->entry[proc_index].fd;
-
+ if (close_fd && (fd != ishm_tbl->single_va_fd)) {
if (block->huge == CACHED)
hp_put_cached(fd);
else
@@ -973,7 +1036,8 @@ static int block_free_internal(int block_index, int close_fd, int deregister)
* main block table (>=0) or -1 on error.
*/
int _odp_ishm_reserve(const char *name, uint64_t size, int fd,
- uint32_t align, uint32_t flags, uint32_t user_flags)
+ uint32_t align, uint64_t offset, uint32_t flags,
+ uint32_t user_flags)
{
int new_index; /* index in the main block table*/
ishm_block_t *new_block; /* entry in the main block table*/
@@ -983,7 +1047,6 @@ int _odp_ishm_reserve(const char *name, uint64_t size, int fd,
uint64_t len = 0; /* mapped length */
void *addr = NULL; /* mapping address */
int new_proc_entry;
- struct stat statbuf;
static int huge_error_printed; /* to avoid millions of error...*/
odp_spinlock_lock(&ishm_tbl->lock);
@@ -1018,24 +1081,20 @@ int _odp_ishm_reserve(const char *name, uint64_t size, int fd,
else
new_block->name[0] = 0;
+ new_block->offset = 0;
+
/* save user data: */
new_block->user_flags = user_flags;
new_block->user_len = size;
/* If a file descriptor is provided, get the real size and map: */
if (fd >= 0) {
- if (fstat(fd, &statbuf) < 0) {
- odp_spinlock_unlock(&ishm_tbl->lock);
- ODP_ERR("_ishm_reserve failed (fstat failed: %s).\n",
- strerror(errno));
- __odp_errno = errno;
- return -1;
- }
- len = statbuf.st_size;
new_block->external_fd = 1;
- /* note that the huge page flag is meningless here as huge
+ len = size;
+ /* note that the huge page flag is meaningless here as huge
* page is determined by the provided file descriptor: */
- addr = do_map(new_index, len, align, flags, EXTERNAL, &fd);
+ addr = do_map(new_index, len, align, offset, flags, EXTERNAL,
+ &fd);
if (addr == NULL) {
odp_spinlock_unlock(&ishm_tbl->lock);
ODP_ERR("_ishm_reserve failed.\n");
@@ -1061,28 +1120,30 @@ int _odp_ishm_reserve(const char *name, uint64_t size, int fd,
else
flags |= _ODP_ISHM_SINGLE_VA;
+ if (flags & _ODP_ISHM_SINGLE_VA)
+ goto use_single_va;
+
/* roundup to page size */
len = (size + (page_hp_size - 1)) & (-page_hp_size);
- if (!(flags & _ODP_ISHM_SINGLE_VA)) {
- /* try pre-allocated pages */
- fd = hp_get_cached(len);
- if (fd != -1) {
- /* do as if user provided a fd */
- new_block->external_fd = 1;
- addr = do_map(new_index, len, hp_align, flags,
- CACHED, &fd);
- if (addr == NULL) {
- ODP_ERR("Could not use cached hp %d\n",
- fd);
- hp_put_cached(fd);
- fd = -1;
- } else {
- new_block->huge = CACHED;
- }
+
+ /* try pre-allocated pages */
+ fd = hp_get_cached(len);
+ if (fd != -1) {
+ /* do as if user provided a fd */
+ new_block->external_fd = 1;
+ addr = do_map(new_index, len, hp_align, 0, flags,
+ CACHED, &fd);
+ if (addr == NULL) {
+ ODP_ERR("Could not use cached hp %d\n",
+ fd);
+ hp_put_cached(fd);
+ fd = -1;
+ } else {
+ new_block->huge = CACHED;
}
}
if (fd == -1) {
- addr = do_map(new_index, len, hp_align, flags, HUGE,
+ addr = do_map(new_index, len, hp_align, 0, flags, HUGE,
&fd);
if (addr == NULL) {
@@ -1110,18 +1171,27 @@ int _odp_ishm_reserve(const char *name, uint64_t size, int fd,
else
flags |= _ODP_ISHM_SINGLE_VA;
+ if (flags & _ODP_ISHM_SINGLE_VA)
+ goto use_single_va;
+
/* roundup to page size */
len = (size + (page_sz - 1)) & (-page_sz);
- addr = do_map(new_index, len, align, flags, NORMAL, &fd);
+ addr = do_map(new_index, len, align, 0, flags, NORMAL, &fd);
new_block->huge = NORMAL;
}
+use_single_va:
+ /* Reserve memory from single VA space */
+ if (fd < 0 && (flags & _ODP_ISHM_SINGLE_VA))
+ addr = alloc_single_va(name, new_index, size, align, flags, &fd,
+ &len);
+
/* if neither huge pages or normal pages works, we cannot proceed: */
if ((fd < 0) || (addr == NULL) || (len == 0)) {
if (new_block->external_fd) {
if (new_block->huge == CACHED)
hp_put_cached(fd);
- } else if (fd >= 0) {
+ } else if (fd >= 0 && (fd != ishm_tbl->single_va_fd)) {
close(fd);
}
delete_file(new_block);
@@ -1158,6 +1228,65 @@ int _odp_ishm_reserve(const char *name, uint64_t size, int fd,
return new_index;
}
+/*
+ * Pre-reserve all single VA memory. Called only in global init.
+ */
+static void *reserve_single_va(uint64_t size, int *fd_out)
+{
+ uint64_t page_sz; /* normal page size. usually 4K*/
+ uint64_t page_hp_size; /* huge page size */
+ uint64_t len; /* mapped length */
+ int fd = -1;
+ void *addr = NULL;
+
+ /* Get system page sizes: page_hp_size is 0 if no huge page available*/
+ page_sz = odp_sys_page_size();
+ page_hp_size = odp_sys_huge_page_size();
+
+ /* Try first huge pages when possible and needed: */
+ if (page_hp_size && (size > page_sz)) {
+ /* roundup to page size */
+ len = (size + (page_hp_size - 1)) & (-page_hp_size);
+ fd = create_file(-1, HUGE, len, 0, 0, true);
+ if (fd >= 0) {
+ addr = _odp_ishmphy_reserve_single_va(len, fd);
+ if (!addr) {
+ close(fd);
+ unlink(ishm_tbl->single_va_filename);
+ fd = -1;
+ }
+ }
+ if (fd < 0)
+ ODP_ERR("No huge pages, fall back to normal pages. "
+ "Check: /proc/sys/vm/nr_hugepages.\n");
+ ishm_tbl->single_va_huge = true;
+ }
+
+ /* Fall back to normal pages if necessary */
+ if (fd < 0) {
+ /* roundup to page size */
+ len = (size + (page_sz - 1)) & (-page_sz);
+
+ fd = create_file(-1, NORMAL, len, 0, 0, true);
+ if (fd >= 0)
+ addr = _odp_ishmphy_reserve_single_va(len, fd);
+ ishm_tbl->single_va_huge = false;
+ }
+
+ /* If neither huge pages or normal pages works, we cannot proceed: */
+ if ((fd < 0) || (len == 0) || !addr) {
+ if (fd >= 0) {
+ close(fd);
+ unlink(ishm_tbl->single_va_filename);
+ }
+ ODP_ERR("Reserving single VA memory failed.\n");
+ return NULL;
+ }
+
+ *fd_out = fd;
+ return addr;
+}
+
/*
* Try to map an memory block mapped by another ODP instance into the
* current ODP instance.
@@ -1173,6 +1302,7 @@ int _odp_ishm_find_exported(const char *remote_name, pid_t external_odp_pid,
uint64_t len;
uint32_t flags;
uint64_t user_len;
+ uint64_t offset;
uint32_t user_flags;
uint32_t align;
int fd;
@@ -1217,6 +1347,9 @@ int _odp_ishm_find_exported(const char *remote_name, pid_t external_odp_pid,
if (fscanf(export_file, EXPORT_FILE_LINE8_FMT " ", &align) != 1)
goto error_exp_file;
+ if (fscanf(export_file, EXPORT_FILE_LINE9_FMT " ", &offset) != 1)
+ goto error_exp_file;
+
fclose(export_file);
/* now open the filename given in the description file: */
@@ -1227,16 +1360,22 @@ int _odp_ishm_find_exported(const char *remote_name, pid_t external_odp_pid,
return -1;
}
- /* clear the _ODP_ISHM_EXPORT flag so we don't export that again*/
+ /* Clear the _ODP_ISHM_EXPORT flag so we don't export again. Single
+ * VA doesn't hold up after export. */
flags &= ~(uint32_t)_ODP_ISHM_EXPORT;
+ flags &= ~(uint32_t)_ODP_ISHM_SINGLE_VA;
/* reserve the memory, providing the opened file descriptor: */
- block_index = _odp_ishm_reserve(local_name, 0, fd, align, flags, 0);
+ block_index = _odp_ishm_reserve(local_name, len, fd, align, offset,
+ flags, 0);
if (block_index < 0) {
close(fd);
return block_index;
}
+ /* Offset is required to remap the block to other processes */
+ ishm_tbl->block[block_index].offset = offset;
+
/* set inherited info: */
ishm_tbl->block[block_index].user_flags = user_flags;
ishm_tbl->block[block_index].user_len = user_len;
@@ -1314,7 +1453,12 @@ static void *block_lookup(int block_index)
/* perform the mapping */
block = &ishm_tbl->block[block_index];
- mapped_addr = do_remap(block_index, fd);
+ /* No need to remap single VA */
+ if (block->flags & _ODP_ISHM_SINGLE_VA)
+ mapped_addr = block->start;
+ else
+ mapped_addr = do_remap(block_index, fd);
+
if (mapped_addr == NULL) {
ODP_ERR(" lookup: Could not map existing shared memory!\n");
return NULL;
@@ -1497,12 +1641,11 @@ int _odp_ishm_cleanup_files(const char *dirpath)
int _odp_ishm_init_global(const odp_init_t *init)
{
void *addr;
- void *spce_addr;
+ void *spce_addr = NULL;
int i;
int single_va_size_kb = 0;
uid_t uid;
char *hp_dir = odp_global_ro.hugepage_info.default_huge_page_dir;
- uint64_t align;
uint64_t max_memory;
uint64_t internal;
@@ -1549,11 +1692,9 @@ int _odp_ishm_init_global(const odp_init_t *init)
if (!hp_dir) {
ODP_DBG("NOTE: No support for huge pages\n");
- align = odp_sys_page_size();
} else {
ODP_DBG("Huge pages mount point is: %s\n", hp_dir);
_odp_ishm_cleanup_files(hp_dir);
- align = odp_sys_huge_page_size();
}
_odp_ishm_cleanup_files(odp_global_ro.shm_dir);
@@ -1581,14 +1722,16 @@ int _odp_ishm_init_global(const odp_init_t *init)
ishm_ftbl = addr;
memset(ishm_ftbl, 0, sizeof(ishm_ftable_t));
- /*
- *reserve the address space for _ODP_ISHM_SINGLE_VA reserved blocks,
- * only address space!
- */
- spce_addr = _odp_ishmphy_book_va(max_memory, align);
- if (!spce_addr) {
- ODP_ERR("unable to reserve virtual space\n.");
- goto init_glob_err3;
+ /* Reserve memory for _ODP_ISHM_SINGLE_VA reserved blocks */
+ ishm_tbl->single_va_fd = -1;
+ if (max_memory) {
+ spce_addr = reserve_single_va(max_memory,
+ &ishm_tbl->single_va_fd);
+ if (!spce_addr) {
+ ODP_ERR("unable to reserve single VA memory\n.");
+ goto init_glob_err3;
+ }
+ ishm_tbl->single_va_start = spce_addr;
}
/* use the first fragment descriptor to describe to whole VA space: */
@@ -1628,8 +1771,8 @@ int _odp_ishm_init_global(const odp_init_t *init)
return 0;
init_glob_err4:
- if (_odp_ishmphy_unbook_va())
- ODP_ERR("unable to unbook virtual space\n.");
+ if (_odp_ishmphy_free_single_va())
+ ODP_ERR("unable to free single VA memory\n.");
init_glob_err3:
if (munmap(ishm_ftbl, sizeof(ishm_ftable_t)) < 0)
ODP_ERR("unable to munmap main fragment table\n.");
@@ -1727,6 +1870,7 @@ int _odp_ishm_term_global(void)
{
int ret = 0;
int index;
+ int fd = ishm_tbl->single_va_fd;
ishm_block_t *block;
if ((getpid() != odp_global_ro.main_pid) ||
@@ -1748,6 +1892,9 @@ int _odp_ishm_term_global(void)
/* perform the last thread terminate which was postponed: */
ret = do_odp_ishm_term_local();
+ /* remove the file from the filesystem, keeping its fd open */
+ unlink(ishm_tbl->single_va_filename);
+
/* free the fragment table */
if (munmap(ishm_ftbl, sizeof(ishm_ftable_t)) < 0) {
ret |= -1;
@@ -1759,9 +1906,13 @@ int _odp_ishm_term_global(void)
ODP_ERR("unable to munmap main table\n.");
}
- /* free the reserved VA space */
- if (_odp_ishmphy_unbook_va())
+ /* free the reserved single VA memory */
+ if (_odp_ishmphy_free_single_va())
ret |= -1;
+ if ((fd >= 0) && close(fd)) {
+ ret |= -1;
+ ODP_ERR("unable to close single VA\n.");
+ }
if (!odp_global_ro.shm_dir_from_env)
free(odp_global_ro.shm_dir);
diff --git a/platform/linux-generic/odp_ishmphy.c b/platform/linux-generic/odp_ishmphy.c
index 556c8e14..65e0cc82 100644
--- a/platform/linux-generic/odp_ishmphy.c
+++ b/platform/linux-generic/odp_ishmphy.c
@@ -30,6 +30,7 @@
#include <fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>
+#include <inttypes.h>
#include <odp_ishmphy_internal.h>
static void *common_va_address;
@@ -39,112 +40,72 @@ static uint64_t common_va_len;
#define MAP_ANONYMOUS MAP_ANON
#endif
-/* Book some virtual address space
- * This function is called at odp_init_global() time to pre-book some
- * virtual address space inherited by all odpthreads (i.e. descendant
- * processes and threads) and later used to guarantee the unicity the
- * the mapping VA address when memory is reserver with the _ODP_ISHM_SINGLE_VA
- * flag.
+/* Reserve single VA memory
+ * This function is called at odp_init_global() time to pre-reserve some memory
+ * which is inherited by all odpthreads (i.e. descendant processes and threads).
+ * This memory block is later used when memory is reserved with
+ * _ODP_ISHM_SINGLE_VA flag.
* returns the address of the mapping or NULL on error.
*/
-void *_odp_ishmphy_book_va(uintptr_t len, intptr_t align)
+void *_odp_ishmphy_reserve_single_va(uint64_t len, int fd)
{
void *addr;
- addr = mmap(NULL, len + align, PROT_NONE,
- MAP_SHARED | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0);
+ addr = mmap(NULL, len, PROT_READ | PROT_WRITE,
+ MAP_SHARED | MAP_POPULATE, fd, 0);
if (addr == MAP_FAILED) {
- ODP_ERR("_ishmphy_book_va failure\n");
+ ODP_ERR("mmap failed: %s\n", strerror(errno));
return NULL;
}
- if (mprotect(addr, len, PROT_NONE))
- ODP_ERR("failure for protect\n");
+ if (mprotect(addr, len, PROT_READ | PROT_WRITE))
+ ODP_ERR("mprotect failed: %s\n", strerror(errno));
- ODP_DBG("VA Reserved: %p, len=%p\n", addr, len + align);
+ ODP_DBG("VA Reserved: %p, len=%" PRIu64 "\n", addr, len);
common_va_address = addr;
common_va_len = len;
- /* return the nearest aligned address: */
- return (void *)(((uintptr_t)addr + align - 1) & (-align));
+ return addr;
}
-/* Un-book some virtual address space
- * This function is called at odp_term_global() time to unbook
- * the virtual address space booked by _ishmphy_book_va()
+/* Free single VA memory
+ * This function is called at odp_term_global() time to free the memory reserved
+ * by _odp_ishmphy_reserve_single_va()
*/
-int _odp_ishmphy_unbook_va(void)
+int _odp_ishmphy_free_single_va(void)
{
int ret;
+ if (!common_va_address)
+ return 0;
+
ret = munmap(common_va_address, common_va_len);
if (ret)
- ODP_ERR("_unishmphy_book_va failure\n");
+ ODP_ERR("munmap failed: %s\n", strerror(errno));
return ret;
}
/*
* do a mapping:
* Performs a mapping of the provided file descriptor to the process VA
- * space. If the _ODP_ISHM_SINGLE_VA flag is set, 'start' is assumed to be
- * the VA address where the mapping is to be done.
- * If the flag is not set, a new VA address is taken.
+ * space. Not to be used with _ODP_ISHM_SINGLE_VA blocks.
* returns the address of the mapping or NULL on error.
*/
-void *_odp_ishmphy_map(int fd, void *start, uint64_t size,
- int flags)
+void *_odp_ishmphy_map(int fd, uint64_t size, uint64_t offset, int flags)
{
- void *mapped_addr_tmp, *mapped_addr;
+ void *mapped_addr;
int mmap_flags = MAP_POPULATE;
- if (flags & _ODP_ISHM_SINGLE_VA) {
- if (!start) {
- ODP_ERR("failure: missing address\n");
- return NULL;
- }
- /* maps over fragment of reserved VA: */
- /* first, try a normal map. If that works, remap it where it
- * should (on the prereverved space), and remove the initial
- * normal mapping:
- * This is because it turned out that if a mapping fails
- * on a the prereserved virtual address space, then
- * the prereserved address space which was tried to be mapped
- * on becomes available to the kernel again! This was not
- * according to expectations: the assumption was that if a
- * mapping fails, the system should remain unchanged, but this
- * is obvioulsy not true (at least for huge pages when
- * exhausted).
- * So the strategy is to first map at a non reserved place
- * (which can then be freed and returned to the kernel on
- * failure) and peform a new map to the prereserved space on
- * success (which is then guaranteed to work).
- * The initial free maping can then be removed.
- */
- mapped_addr = MAP_FAILED;
- mapped_addr_tmp = mmap(NULL, size, PROT_READ | PROT_WRITE,
- MAP_SHARED | mmap_flags, fd, 0);
- if (mapped_addr_tmp != MAP_FAILED) {
- /* If OK, do new map at right fixed location... */
- mapped_addr = mmap(start,
- size, PROT_READ | PROT_WRITE,
- MAP_SHARED | MAP_FIXED | mmap_flags,
- fd, 0);
- if (mapped_addr != start)
- ODP_ERR("new map failed:%s\n", strerror(errno));
- /* ... and remove initial mapping: */
- if (munmap(mapped_addr_tmp, size))
- ODP_ERR("munmap failed:%s\n", strerror(errno));
- }
- } else {
- /* just do a new mapping in the VA space: */
- mapped_addr = mmap(NULL, size, PROT_READ | PROT_WRITE,
- MAP_SHARED | mmap_flags, fd, 0);
- if ((mapped_addr >= common_va_address) &&
- ((char *)mapped_addr <
- (char *)common_va_address + common_va_len)) {
- ODP_ERR("VA SPACE OVERLAP!\n");
- }
+ ODP_ASSERT(!(flags & _ODP_ISHM_SINGLE_VA));
+
+ /* do a new mapping in the VA space: */
+ mapped_addr = mmap(NULL, size, PROT_READ | PROT_WRITE,
+ MAP_SHARED | mmap_flags, fd, offset);
+ if ((mapped_addr >= common_va_address) &&
+ ((char *)mapped_addr <
+ (char *)common_va_address + common_va_len)) {
+ ODP_ERR("VA SPACE OVERLAP!\n");
}
if (mapped_addr == MAP_FAILED)
@@ -153,9 +114,9 @@ void *_odp_ishmphy_map(int fd, void *start, uint64_t size,
/* if locking is requested, lock it...*/
if (flags & _ODP_ISHM_LOCK) {
if (mlock(mapped_addr, size)) {
+ ODP_ERR("mlock failed: %s\n", strerror(errno));
if (munmap(mapped_addr, size))
- ODP_ERR("munmap failed:%s\n", strerror(errno));
- ODP_ERR("mlock failed:%s\n", strerror(errno));
+ ODP_ERR("munmap failed: %s\n", strerror(errno));
return NULL;
}
}
@@ -163,44 +124,25 @@ void *_odp_ishmphy_map(int fd, void *start, uint64_t size,
}
/* free a mapping:
- * If the _ODP_ISHM_SINGLE_VA flag was given at creation time the virtual
- * address range must be returned to the preoallocated "pool". this is
- * done by mapping non accessibly memory there (hence blocking the VA but
- * releasing the physical memory).
- * If the _ODP_ISHM_SINGLE_VA flag was not given, both physical memory and
- * virtual address space are realeased by calling the normal munmap.
+ * _ODP_ISHM_SINGLE_VA memory is not returned back to linux until global
+ * terminate. If the _ODP_ISHM_SINGLE_VA flag was not given, both physical
+ * memory and virtual address space are released by calling the normal munmap.
* return 0 on success or -1 on error.
*/
int _odp_ishmphy_unmap(void *start, uint64_t len, int flags)
{
- void *addr;
int ret;
- int mmap_flgs;
-
- mmap_flgs = MAP_SHARED | MAP_FIXED | MAP_ANONYMOUS | MAP_NORESERVE;
/* if locking was requested, unlock...*/
if (flags & _ODP_ISHM_LOCK)
munlock(start, len);
- if (flags & _ODP_ISHM_SINGLE_VA) {
- /* map unnaccessible memory overwrites previous mapping
- * and free the physical memory, but guarantees to block
- * the VA range from other mappings
- */
- addr = mmap(start, len, PROT_NONE, mmap_flgs, -1, 0);
- if (addr == MAP_FAILED) {
- ODP_ERR("_ishmphy_free failure for ISHM_SINGLE_VA\n");
- return -1;
- }
- if (mprotect(start, len, PROT_NONE))
- ODP_ERR("_ishmphy_free failure for protect\n");
+ if (flags & _ODP_ISHM_SINGLE_VA)
return 0;
- }
/* just release the mapping */
ret = munmap(start, len);
if (ret)
- ODP_ERR("_ishmphy_free failure: %s\n", strerror(errno));
+ ODP_ERR("munmap failed: %s\n", strerror(errno));
return ret;
}
diff --git a/platform/linux-generic/odp_ishmpool.c b/platform/linux-generic/odp_ishmpool.c
index 56e59f33..9a4e08fa 100644
--- a/platform/linux-generic/odp_ishmpool.c
+++ b/platform/linux-generic/odp_ishmpool.c
@@ -223,7 +223,7 @@ static pool_t *_odp_ishmbud_pool_create(const char *pool_name, int store_idx,
/* allocate required memory: */
blk_idx = _odp_ishm_reserve(pool_name, total_sz, -1,
- ODP_CACHE_LINE_SIZE, flags, 0);
+ ODP_CACHE_LINE_SIZE, 0, flags, 0);
if (blk_idx < 0) {
ODP_ERR("_odp_ishm_reserve failed.");
return NULL;
@@ -558,7 +558,7 @@ static pool_t *_odp_ishmslab_pool_create(const char *pool_name, int store_idx,
/* allocate required memory: */
blk_idx = _odp_ishm_reserve(pool_name, total_sz, -1,
- ODP_CACHE_LINE_SIZE, flags, 0);
+ ODP_CACHE_LINE_SIZE, 0, flags, 0);
if (blk_idx < 0) {
ODP_ERR("_odp_ishm_reserve failed.");
return NULL;
diff --git a/platform/linux-generic/odp_shared_memory.c b/platform/linux-generic/odp_shared_memory.c
index 4e92c9f2..b1bbdeb7 100644
--- a/platform/linux-generic/odp_shared_memory.c
+++ b/platform/linux-generic/odp_shared_memory.c
@@ -53,7 +53,7 @@ odp_shm_t _odp_shm_reserve(const char *name, uint64_t size, uint32_t align,
flgs = get_ishm_flags(flags);
flgs |= extra_flags;
- block_index = _odp_ishm_reserve(name, size, -1, align, flgs, flags);
+ block_index = _odp_ishm_reserve(name, size, -1, align, 0, flgs, flags);
if (block_index >= 0)
return to_handle(block_index);
else
diff --git a/platform/linux-generic/test/validation/api/shmem/shmem_linux.c b/platform/linux-generic/test/validation/api/shmem/shmem_linux.c
index 2bc7f1bd..6b09c1de 100644
--- a/platform/linux-generic/test/validation/api/shmem/shmem_linux.c
+++ b/platform/linux-generic/test/validation/api/shmem/shmem_linux.c
@@ -110,7 +110,8 @@
static int read_shmem_attribues(uint64_t ext_odp_pid, const char *blockname,
char *filename, uint64_t *len,
uint32_t *flags, uint64_t *user_len,
- uint32_t *user_flags, uint32_t *align)
+ uint32_t *user_flags, uint32_t *align,
+ uint64_t *offset)
{
char shm_attr_filename[PATH_MAX];
FILE *export_file;
@@ -151,6 +152,9 @@ static int read_shmem_attribues(uint64_t ext_odp_pid, const char *blockname,
if (fscanf(export_file, "align: %" PRIu32 " ", align) != 1)
goto export_file_read_err;
+ if (fscanf(export_file, "offset: %" PRIu64 " ", offset) != 1)
+ goto export_file_read_err;
+
fclose(export_file);
return 0;
@@ -209,6 +213,7 @@ int main(int argc __attribute__((unused)), char *argv[])
int fifo_fd = -1;
char shm_filename[PATH_MAX];/* shared mem device name, under /dev/shm */
uint64_t len;
+ uint64_t offset;
uint32_t flags;
uint64_t user_len;
uint32_t user_flags;
@@ -260,8 +265,9 @@ int main(int argc __attribute__((unused)), char *argv[])
/* read the shared memory attributes (includes the shm filename): */
if (read_shmem_attribues(odp_app1, SHM_NAME,
shm_filename, &len, &flags,
- &user_len, &user_flags, &align) != 0) {
- printf("erorr read_shmem_attribues\n");
+ &user_len, &user_flags, &align,
+ &offset) != 0) {
+ printf("error read_shmem_attribues\n");
test_failure(fifo_name, fifo_fd, odp_app1);
}
@@ -281,9 +287,10 @@ int main(int argc __attribute__((unused)), char *argv[])
*/
size = sizeof(test_shared_linux_data_t);
- addr = mmap(NULL, size, PROT_READ, MAP_SHARED, shm_fd, 0);
+ addr = mmap(NULL, size, PROT_READ, MAP_SHARED, shm_fd, offset);
if (addr == MAP_FAILED) {
- fprintf(stderr, "shmem_linux: map failed!\n");
+ fprintf(stderr, "shmem_linux: mmap failed: %s\n",
+ strerror(errno));
test_failure(fifo_name, fifo_fd, odp_app1);
}
commit b181d885962969f439d9cd6f828fb66007ddedcb
Author: Matias Elo <matias.elo(a)nokia.com>
Date: Thu Nov 1 16:50:43 2018 +0200
linux-gen: ishm: read single va size from config
Simplify adjusting single VA memory size by moving the value to ODP config
(shm.single_va_size). The default size is dropped to 128MB to save memory.
Signed-off-by: Matias Elo <matias.elo(a)nokia.com>
Reviewed-by: Bill Fischofer <bill.fischofer(a)linaro.org>
Signed-off-by: Maxim Uvarov <maxim.uvarov(a)linaro.org>
diff --git a/config/odp-linux-generic.conf b/config/odp-linux-generic.conf
index 4585a896..33938289 100644
--- a/config/odp-linux-generic.conf
+++ b/config/odp-linux-generic.conf
@@ -16,7 +16,7 @@
# Mandatory fields
odp_implementation = "linux-generic"
-config_file_version = "0.1.3"
+config_file_version = "0.1.4"
# Shared memory options
shm: {
@@ -37,6 +37,9 @@ shm: {
# Allocate internal shared memory using a single virtual address space.
# Set to 1 to enable using process mode.
single_va = 0
+
+ # Amount of memory pre-reserved for ODP_SHM_SINGLE_VA usage in kilobytes
+ single_va_size_kb = 131072
}
# Pool options
diff --git a/platform/linux-generic/include/odp_config_internal.h b/platform/linux-generic/include/odp_config_internal.h
index 65f75197..642de685 100644
--- a/platform/linux-generic/include/odp_config_internal.h
+++ b/platform/linux-generic/include/odp_config_internal.h
@@ -128,16 +128,6 @@ extern "C" {
*/
#define ODP_CONFIG_SHM_BLOCKS (ODP_CONFIG_POOLS + 48)
-/*
- * Size of the virtual address space pre-reserver for ISHM
- *
- * This is just virtual space preallocation size, not memory allocation.
- * This address space is used by ISHM to map things at a common address in
- * all ODP threads (when the _ODP_ISHM_SINGLE_VA flag is used).
- * In bytes.
- */
-#define ODP_CONFIG_ISHM_VA_PREALLOC_SZ (1024 * 1024 * 1024L)
-
/*
* Maximum event burst size
*
diff --git a/platform/linux-generic/odp_ishm.c b/platform/linux-generic/odp_ishm.c
index da982e18..f8af8f79 100644
--- a/platform/linux-generic/odp_ishm.c
+++ b/platform/linux-generic/odp_ishm.c
@@ -1499,11 +1499,23 @@ int _odp_ishm_init_global(const odp_init_t *init)
void *addr;
void *spce_addr;
int i;
+ int single_va_size_kb = 0;
uid_t uid;
char *hp_dir = odp_global_ro.hugepage_info.default_huge_page_dir;
uint64_t align;
- uint64_t max_memory = ODP_CONFIG_ISHM_VA_PREALLOC_SZ;
- uint64_t internal = ODP_CONFIG_ISHM_VA_PREALLOC_SZ / 8;
+ uint64_t max_memory;
+ uint64_t internal;
+
+ if (!_odp_libconfig_lookup_ext_int("shm", NULL, "single_va_size_kb",
+ &single_va_size_kb)) {
+ ODP_ERR("Unable to read single VA size from config\n");
+ return -1;
+ }
+
+ ODP_DBG("Shm single VA size: %dkB\n", single_va_size_kb);
+
+ max_memory = single_va_size_kb * 1024;
+ internal = max_memory / 8;
/* user requested memory size + some extra for internal use */
if (init && init->shm.max_memory)
diff --git a/platform/linux-generic/test/process-mode.conf b/platform/linux-generic/test/process-mode.conf
index f631f54b..a86562f6 100644
--- a/platform/linux-generic/test/process-mode.conf
+++ b/platform/linux-generic/test/process-mode.conf
@@ -1,10 +1,13 @@
# Mandatory fields
odp_implementation = "linux-generic"
-config_file_version = "0.1.3"
+config_file_version = "0.1.4"
# Shared memory options
shm: {
# Override default option and allocate internal shms using single
# virtual address space.
single_va = 1
+
+ # Increase the amount of single VA memory
+ single_va_size_kb = 1048576
}
commit bc9a1f01b55da44053a233acd4110def04f208fe
Author: Matias Elo <matias.elo(a)nokia.com>
Date: Mon Nov 5 10:25:41 2018 +0200
validation: shmem: reduce the number of workers in single VA alloc test
Reduce the maximum number of threads in run_test_singleva_after_fork() test
to three (number of test cases). As each worker performs shm allocation the
test would fail eventually on high core count systems. The CU asserts are
changed to FATAL as the following check would cause segfault.
Signed-off-by: Matias Elo <matias.elo(a)nokia.com>
Reviewed-by: Bill Fischofer <bill.fischofer(a)linaro.org>
Signed-off-by: Maxim Uvarov <maxim.uvarov(a)linaro.org>
diff --git a/test/validation/api/shmem/shmem.c b/test/validation/api/shmem/shmem.c
index 5a262daf..91235851 100644
--- a/test/validation/api/shmem/shmem.c
+++ b/test/validation/api/shmem/shmem.c
@@ -468,7 +468,7 @@ static int run_test_singleva_after_fork(void *arg ODP_UNUSED)
size = sizeof(shared_test_data_small_t);
shm = odp_shm_reserve(glob_data->name[thr_index], size,
0, ODP_SHM_SINGLE_VA);
- CU_ASSERT(ODP_SHM_INVALID != shm);
+ CU_ASSERT_FATAL(ODP_SHM_INVALID != shm);
glob_data->shm[thr_index] = shm;
pattern_small = odp_shm_addr(shm);
CU_ASSERT_PTR_NOT_NULL(pattern_small);
@@ -480,7 +480,7 @@ static int run_test_singleva_after_fork(void *arg ODP_UNUSED)
size = sizeof(shared_test_data_medium_t);
shm = odp_shm_reserve(glob_data->name[thr_index], size,
0, ODP_SHM_SINGLE_VA);
- CU_ASSERT(ODP_SHM_INVALID != shm);
+ CU_ASSERT_FATAL(ODP_SHM_INVALID != shm);
glob_data->shm[thr_index] = shm;
pattern_medium = odp_shm_addr(shm);
CU_ASSERT_PTR_NOT_NULL(pattern_medium);
@@ -492,7 +492,7 @@ static int run_test_singleva_after_fork(void *arg ODP_UNUSED)
size = sizeof(shared_test_data_big_t);
shm = odp_shm_reserve(glob_data->name[thr_index], size,
0, ODP_SHM_SINGLE_VA);
- CU_ASSERT(ODP_SHM_INVALID != shm);
+ CU_ASSERT_FATAL(ODP_SHM_INVALID != shm);
glob_data->shm[thr_index] = shm;
pattern_big = odp_shm_addr(shm);
CU_ASSERT_PTR_NOT_NULL(pattern_big);
@@ -550,7 +550,7 @@ static void shmem_test_singleva_after_fork(void)
glob_data = odp_shm_addr(shm);
CU_ASSERT_PTR_NOT_NULL(glob_data);
- thrdarg.numthrds = odp_cpumask_default_worker(&unused, 0);
+ thrdarg.numthrds = odp_cpumask_default_worker(&unused, 3);
if (thrdarg.numthrds > MAX_WORKERS)
thrdarg.numthrds = MAX_WORKERS;
@@ -578,21 +578,21 @@ static void shmem_test_singleva_after_fork(void)
case 0:
pattern_small =
odp_shm_addr(glob_data->shm[thr_index]);
- CU_ASSERT_PTR_NOT_NULL(pattern_small);
+ CU_ASSERT_PTR_NOT_NULL_FATAL(pattern_small);
for (i = 0; i < SMALL_MEM; i++)
CU_ASSERT(pattern_small->data[i] == i);
break;
case 1:
pattern_medium =
odp_shm_addr(glob_data->shm[thr_index]);
- CU_ASSERT_PTR_NOT_NULL(pattern_medium);
+ CU_ASSERT_PTR_NOT_NULL_FATAL(pattern_medium);
for (i = 0; i < MEDIUM_MEM; i++)
CU_ASSERT(pattern_medium->data[i] == (i << 2));
break;
case 2:
pattern_big =
odp_shm_addr(glob_data->shm[thr_index]);
- CU_ASSERT_PTR_NOT_NULL(pattern_big);
+ CU_ASSERT_PTR_NOT_NULL_FATAL(pattern_big);
for (i = 0; i < BIG_MEM; i++)
CU_ASSERT(pattern_big->data[i] == (i >> 2));
break;
commit 41eff89ad670eb3bc889ba3b1d9b16d45cb4fdb3
Author: Matias Elo <matias.elo(a)nokia.com>
Date: Fri Oct 26 11:23:28 2018 +0300
validation: pool: add test for creating and using a pool after fork
Add a new test case where pool is created after a process has been already
forked. The created pool is shared amongst all test threads.
Signed-off-by: Matias Elo <matias.elo(a)nokia.com>
Reviewed-by: Bill Fischofer <bill.fischofer(a)linaro.org>
Signed-off-by: Maxim Uvarov <maxim.uvarov(a)linaro.org>
diff --git a/test/validation/api/pool/pool.c b/test/validation/api/pool/pool.c
index 71a1a284..0dbdd0dd 100644
--- a/test/validation/api/pool/pool.c
+++ b/test/validation/api/pool/pool.c
@@ -13,6 +13,15 @@
#define PKT_NUM 500
#define MAX_NUM_DEFAULT (10 * 1024 * 1024)
+typedef struct {
+ odp_barrier_t init_barrier;
+ odp_atomic_u32_t index;
+ uint32_t nb_threads;
+ odp_pool_t pool;
+} global_shared_mem_t;
+
+static global_shared_mem_t *global_mem;
+
static const int default_buffer_size = 1500;
static const int default_buffer_num = 1000;
@@ -424,6 +433,99 @@ static void pool_test_tmo_max_num(void)
CU_ASSERT(odp_pool_destroy(pool) == 0);
}
+static void buffer_alloc_loop(odp_pool_t pool, int num, int buffer_size)
+{
+ int allocs;
+
+ /* Allocate, modify, and free buffers */
+ for (allocs = 0; allocs < num;) {
+ odp_buffer_t buf;
+ uint8_t *data;
+ int i;
+
+ buf = odp_buffer_alloc(pool);
+ if (buf == ODP_BUFFER_INVALID)
+ continue;
+
+ data = odp_buffer_addr(buf);
+
+ for (i = 0; i < buffer_size; i++)
+ data[i] = i;
+
+ odp_buffer_free(buf);
+ allocs++;
+ }
+}
+
+static int run_pool_test_create_after_fork(void *arg ODP_UNUSED)
+{
+ int thr_index;
+
+ thr_index = odp_atomic_fetch_inc_u32(&global_mem->index);
+
+ /* Thread 0 allocates the shared pool */
+ if (thr_index == 0) {
+ odp_pool_t pool;
+ odp_pool_param_t param;
+
+ odp_pool_param_init(¶m);
+
+ param.type = ODP_POOL_BUFFER;
+ param.buf.size = default_buffer_size;
+ param.buf.align = ODP_CACHE_LINE_SIZE;
+ param.buf.num = default_buffer_num;
+
+ pool = odp_pool_create(NULL, ¶m);
+ CU_ASSERT_FATAL(pool != ODP_POOL_INVALID);
+ global_mem->pool = pool;
+ }
+
+ odp_barrier_wait(&global_mem->init_barrier);
+
+ buffer_alloc_loop(global_mem->pool, default_buffer_num,
+ default_buffer_size);
+
+ return CU_get_number_of_failures();
+}
+
+static void pool_test_create_after_fork(void)
+{
+ odp_shm_t shm;
+ odp_cpumask_t unused;
+ pthrd_arg thrdarg;
+
+ /* No single VA required since reserve is done before fork */
+ shm = odp_shm_reserve(NULL, sizeof(global_shared_mem_t), 0, 0);
+ CU_ASSERT_FATAL(shm != ODP_SHM_INVALID);
+ global_mem = odp_shm_addr(shm);
+ CU_ASSERT_PTR_NOT_NULL_FATAL(global_mem);
+
+ thrdarg.numthrds = odp_cpumask_default_worker(&unused, 0);
+ if (thrdarg.numthrds > MAX_WORKERS)
+ thrdarg.numthrds = MAX_WORKERS;
+
+ global_mem->nb_threads = thrdarg.numthrds;
+ global_mem->pool = ODP_POOL_INVALID;
+ odp_barrier_init(&global_mem->init_barrier, thrdarg.numthrds + 1);
+ odp_atomic_init_u32(&global_mem->index, 0);
+
+ /* Fork here */
+ odp_cunit_thread_create(run_pool_test_create_after_fork, &thrdarg);
+
+ /* Wait until thread 0 has created the test pool */
+ odp_barrier_wait(&global_mem->init_barrier);
+
+ buffer_alloc_loop(global_mem->pool, default_buffer_num,
+ default_buffer_size);
+
+ /* Wait for all thread endings */
+ CU_ASSERT(odp_cunit_thread_exit(&thrdarg) >= 0);
+
+ CU_ASSERT(!odp_pool_destroy(global_mem->pool));
+
+ CU_ASSERT(!odp_shm_free(shm));
+}
+
odp_testinfo_t pool_suite[] = {
ODP_TEST_INFO(pool_test_create_destroy_buffer),
ODP_TEST_INFO(pool_test_create_destroy_packet),
@@ -436,6 +538,7 @@ odp_testinfo_t pool_suite[] = {
ODP_TEST_INFO(pool_test_buf_max_num),
ODP_TEST_INFO(pool_test_pkt_max_num),
ODP_TEST_INFO(pool_test_tmo_max_num),
+ ODP_TEST_INFO(pool_test_create_after_fork),
ODP_TEST_INFO_NULL,
};
commit 93f315dfdd3fa77bca5ceef2d487aec0dc55c92e
Author: Matias Elo <matias.elo(a)nokia.com>
Date: Thu Oct 25 13:44:12 2018 +0300
linux-gen: ishm: move block memory mapping into _odp_ishm_address()
Move internal block memory mapping from odp_shm_lookup() to odp_shm_addr().
Calling odp_shm_addr() is mandatory when sharing shm blocks
(not ODP_SHM_SINGLE_VA) between ODP processes. Calling odp_shm_lookup() is
optional.
Signed-off-by: Matias Elo <matias.elo(a)nokia.com>
Reviewed-by: Bill Fischofer <bill.fischofer(a)linaro.org>
Signed-off-by: Maxim Uvarov <maxim.uvarov(a)linaro.org>
diff --git a/platform/linux-generic/odp_ishm.c b/platform/linux-generic/odp_ishm.c
index 9b6e19a8..da982e18 100644
--- a/platform/linux-generic/odp_ishm.c
+++ b/platform/linux-generic/odp_ishm.c
@@ -1335,9 +1335,8 @@ static void *block_lookup(int block_index)
/*
* Lookup for an ishm shared memory, identified by its block name.
- * Map this ishm area in the process VA (if not already present).
- * Return the block index, or -1 if the index
- * does not match any known ishm blocks.
+ * Return the block index, or -1 if the index does not match any known ishm
+ * blocks.
*/
int _odp_ishm_lookup_by_name(const char *name)
{
@@ -1348,42 +1347,25 @@ int _odp_ishm_lookup_by_name(const char *name)
/* search the block in main ishm table: return -1 if not found: */
block_index = find_block_by_name(name);
- if ((block_index < 0) || (!block_lookup(block_index))) {
- odp_spinlock_unlock(&ishm_tbl->lock);
- return -1;
- }
odp_spinlock_unlock(&ishm_tbl->lock);
return block_index;
}
/*
- * Returns the VA address of a given block (which has to be known in the current
- * process). Returns NULL if the block is unknown.
+ * Returns the VA address of a given block. Maps this ishm area in the process
+ * VA (if not already present).
+ * Returns NULL if the block is unknown.
*/
void *_odp_ishm_address(int block_index)
{
- int proc_index;
void *addr;
odp_spinlock_lock(&ishm_tbl->lock);
procsync();
- if ((block_index < 0) ||
- (block_index >= ISHM_MAX_NB_BLOCKS) ||
- (ishm_tbl->block[block_index].len == 0)) {
- ODP_ERR("Request for address on an invalid block\n");
- odp_spinlock_unlock(&ishm_tbl->lock);
- return NULL;
- }
-
- proc_index = procfind_block(block_index);
- if (proc_index < 0) {
- odp_spinlock_unlock(&ishm_tbl->lock);
- return NULL;
- }
+ addr = block_lookup(block_index);
- addr = ishm_proctable->entry[proc_index].start;
odp_spinlock_unlock(&ishm_tbl->lock);
return addr;
}
commit 458120cb0507fd143db4f122a9adb3651468712d
Author: Matias Elo <matias.elo(a)nokia.com>
Date: Fri Nov 2 09:57:39 2018 +0200
linux-gen: queue scalable: remove _ODP_ISHM_SINGLE_VA from pool create
ishm pool create is done during global init so no need to use
_ODP_ISHM_SINGLE_VA flag.
Signed-off-by: Matias Elo <matias.elo(a)nokia.com>
Reviewed-by: Bill Fischofer <bill.fischofer(a)linaro.org>
Signed-off-by: Maxim Uvarov <maxim.uvarov(a)linaro.org>
diff --git a/platform/linux-generic/odp_queue_scalable.c b/platform/linux-generic/odp_queue_scalable.c
index ea561a33..a3288456 100644
--- a/platform/linux-generic/odp_queue_scalable.c
+++ b/platform/linux-generic/odp_queue_scalable.c
@@ -225,8 +225,7 @@ static int queue_init_global(void)
max_alloc = CONFIG_SCAL_QUEUE_SIZE * sizeof(odp_buffer_hdr_t *);
queue_shm_pool = _odp_ishm_pool_create("queue_shm_pool",
pool_size,
- min_alloc, max_alloc,
- _ODP_ISHM_SINGLE_VA);
+ min_alloc, max_alloc, 0);
if (queue_shm_pool == NULL) {
ODP_ERR("Failed to allocate shared memory pool for"
" queues\n");
commit 661140b119ea0dfc516025869ffce5d215537745
Author: Matias Elo <matias.elo(a)nokia.com>
Date: Fri Oct 26 14:34:58 2018 +0300
linux-gen: ishm: remove unused internal functions
Ease code maintenance by removing the following unused functions:
find_block_by_address(void *addr)
_odp_ishm_free_by_name(const char *name)
_odp_ishm_free_by_address(void *addr)
_odp_ishm_lookup_by_index(int block_index)
_odp_ishm_lookup_by_address(void *addr)
Signed-off-by: Matias Elo <matias.elo(a)nokia.com>
Reviewed-by: Bill Fischofer <bill.fischofer(a)linaro.org>
Signed-off-by: Maxim Uvarov <maxim.uvarov(a)linaro.org>
diff --git a/platform/linux-generic/include/odp_shm_internal.h b/platform/linux-generic/include/odp_shm_internal.h
index a1bd2439..9da5082d 100644
--- a/platform/linux-generic/include/odp_shm_internal.h
+++ b/platform/linux-generic/include/odp_shm_internal.h
@@ -40,11 +40,7 @@ odp_shm_t _odp_shm_reserve(const char *name, uint64_t size, uint32_t align,
int _odp_ishm_reserve(const char *name, uint64_t size, int fd, uint32_t align,
uint32_t flags, uint32_t user_flags);
int _odp_ishm_free_by_index(int block_index);
-int _odp_ishm_free_by_name(const char *name);
-int _odp_ishm_free_by_address(void *addr);
-void *_odp_ishm_lookup_by_index(int block_index);
int _odp_ishm_lookup_by_name(const char *name);
-int _odp_ishm_lookup_by_address(void *addr);
int _odp_ishm_find_exported(const char *remote_name,
pid_t external_odp_pid,
const char *local_name);
diff --git a/platform/linux-generic/odp_ishm.c b/platform/linux-generic/odp_ishm.c
index 9bf40eb3..9b6e19a8 100644
--- a/platform/linux-generic/odp_ishm.c
+++ b/platform/linux-generic/odp_ishm.c
@@ -846,56 +846,6 @@ static int find_block_by_name(const char *name)
return -1;
}
-/*
- * Search for a block by address (only works when flag _ODP_ISHM_SINGLE_VA
- * was set at reserve() time, or if the block is already known by this
- * process).
- * Search is performed in the process table and in the global ishm table.
- * The provided address does not have to be at start: any address
- * within the fragment is OK.
- * Returns the index to the found block (if any) or -1 if none.
- * Mutex must be assured by the caller.
- */
-static int find_block_by_address(void *addr)
-{
- int block_index;
- int i;
- ishm_fragment_t *fragmnt;
-
- /*
- * first check if there is already a process known block for this
- * address
- */
- for (i = 0; i < ishm_proctable->nb_entries; i++) {
- block_index = ishm_proctable->entry[i].block_index;
- if ((addr > ishm_proctable->entry[i].start) &&
- ((char *)addr < ((char *)ishm_proctable->entry[i].start +
- ishm_tbl->block[block_index].len)))
- return block_index;
- }
-
- /*
- * then check if there is a existing single VA block known by some other
- * process and containing the given address
- */
- for (i = 0; i < ISHM_MAX_NB_BLOCKS; i++) {
- if ((!ishm_tbl->block[i].len) ||
- (!(ishm_tbl->block[i].flags & _ODP_ISHM_SINGLE_VA)))
- continue;
- fragmnt = ishm_tbl->block[i].fragment;
- if (!fragmnt) {
- ODP_ERR("find_fragment: invalid NULL fragment\n");
- return -1;
- }
- if ((addr >= fragmnt->start) &&
- ((char *)addr < ((char *)fragmnt->start + fragmnt->len)))
- return i;
- }
-
- /* address does not belong to any accessible block: */
- return -1;
-}
-
/*
* Search a given ishm block in the process local table. Return its index
* in the process table or -1 if not found (meaning that the ishm table
@@ -1327,59 +1277,6 @@ int _odp_ishm_free_by_index(int block_index)
return ret;
}
-/*
- * free and unmap internal shared memory, identified by its block name:
- * return -1 on error. 0 if OK.
- */
-int _odp_ishm_free_by_name(const char *name)
-{
- int block_index;
- int ret;
-
- odp_spinlock_lock(&ishm_tbl->lock);
- procsync();
-
- /* search the block in main ishm table */
- block_index = find_block_by_name(name);
- if (block_index < 0) {
- ODP_ERR("Request to free an non existing block..."
- " (double free?)\n");
- odp_spinlock_unlock(&ishm_tbl->lock);
- return -1;
- }
-
- ret = block_free(block_index);
- odp_spinlock_unlock(&ishm_tbl->lock);
- return ret;
-}
-
-/*
- * Free and unmap internal shared memory identified by address:
- * return -1 on error. 0 if OK.
- */
-int _odp_ishm_free_by_address(void *addr)
-{
- int block_index;
- int ret;
-
- odp_spinlock_lock(&ishm_tbl->lock);
- procsync();
-
- /* search the block in main ishm table */
- block_index = find_block_by_address(addr);
- if (block_index < 0) {
- ODP_ERR("Request to free an non existing block..."
- " (double free?)\n");
- odp_spinlock_unlock(&ishm_tbl->lock);
- return -1;
- }
-
- ret = block_free(block_index);
-
- odp_spinlock_unlock(&ishm_tbl->lock);
- return ret;
-}
-
/*
* Lookup for an ishm shared memory, identified by its block index
* in the main ishm block table.
@@ -1436,24 +1333,6 @@ static void *block_lookup(int block_index)
return mapped_addr;
}
-/*
- * Lookup for an ishm shared memory, identified by its block_index.
- * Maps this ishmem area in the process VA (if not already present).
- * Returns the block user address, or NULL if the index
- * does not match any known ishm blocks.
- */
-void *_odp_ishm_lookup_by_index(int block_index)
-{
- void *ret;
-
- odp_spinlock_lock(&ishm_tbl->lock);
- procsync();
-
- ret = block_lookup(block_index);
- odp_spinlock_unlock(&ishm_tbl->lock);
- return ret;
-}
-
/*
* Lookup for an ishm shared memory, identified by its block name.
* Map this ishm area in the process VA (if not already present).
@@ -1478,32 +1357,6 @@ int _odp_ishm_lookup_by_name(const char *name)
return block_index;
}
-/*
- * Lookup for an ishm shared memory block, identified by its VA address.
- * This works only if the block has already been looked-up (mapped) by the
- * current process or it it was created with the _ODP_ISHM_SINGLE_VA flag.
- * Map this ishm area in the process VA (if not already present).
- * Return the block index, or -1 if the address
- * does not match any known ishm blocks.
- */
-int _odp_ishm_lookup_by_address(void *addr)
-{
- int block_index;
-
- odp_spinlock_lock(&ishm_tbl->lock);
- procsync();
-
- /* search the block in main ishm table: return -1 if not found: */
- block_index = find_block_by_address(addr);
- if ((block_index < 0) || (!block_lookup(block_index))) {
- odp_spinlock_unlock(&ishm_tbl->lock);
- return -1;
- }
-
- odp_spinlock_unlock(&ishm_tbl->lock);
- return block_index;
-}
-
/*
* Returns the VA address of a given block (which has to be known in the current
* process). Returns NULL if the block is unknown.
commit 68578a2b61e2afdf4655b61ed8f5d023b16b4846
Author: Matias Elo <matias.elo(a)nokia.com>
Date: Fri Oct 26 13:11:12 2018 +0300
linux-gen: ishm: remove unnecessary _odp_ishm_pool_lookup() function
Ease code maintenance by removing unnecessary code.
Signed-off-by: Matias Elo <matias.elo(a)nokia.com>
Reviewed-by: Bill Fischofer <bill.fischofer(a)linaro.org>
Signed-off-by: Maxim Uvarov <maxim.uvarov(a)linaro.org>
diff --git a/platform/linux-generic/include/odp_ishmpool_internal.h b/platform/linux-generic/include/odp_ishmpool_internal.h
index 94bcddae..9db5a2b4 100644
--- a/platform/linux-generic/include/odp_ishmpool_internal.h
+++ b/platform/linux-generic/include/odp_ishmpool_internal.h
@@ -46,7 +46,6 @@ int _odp_ishm_pool_destroy(_odp_ishm_pool_t *pool);
void *_odp_ishm_pool_alloc(_odp_ishm_pool_t *pool, uint64_t size);
int _odp_ishm_pool_free(_odp_ishm_pool_t *pool, void *addr);
int _odp_ishm_pool_status(const char *title, _odp_ishm_pool_t *pool);
-_odp_ishm_pool_t *_odp_ishm_pool_lookup(const char *pool_name);
void _odp_ishm_pool_init(void);
#ifdef __cplusplus
diff --git a/platform/linux-generic/odp_ishmpool.c b/platform/linux-generic/odp_ishmpool.c
index a3a1c059..56e59f33 100644
--- a/platform/linux-generic/odp_ishmpool.c
+++ b/platform/linux-generic/odp_ishmpool.c
@@ -784,23 +784,3 @@ void _odp_ishm_pool_init(void)
for (i = 0; i < MAX_NB_POOL; i++)
pool_blk_idx[i] = -1;
}
-
-_odp_ishm_pool_t *_odp_ishm_pool_lookup(const char *pool_name)
-{
- int block_idx;
- int store_idx;
-
- /* search for a _ishm block with the given name */
- block_idx = _odp_ishm_lookup_by_name(pool_name);
- if (block_idx < 0)
- return NULL;
-
- /* a block with that name exists: make sure it is within
- * the registered pools */
- for (store_idx = 0; store_idx < MAX_NB_POOL; store_idx++) {
- if (pool_blk_idx[store_idx] == block_idx)
- return _odp_ishm_address(block_idx);
- }
-
- return NULL;
-}
diff --git a/platform/linux-generic/odp_queue_scalable.c b/platform/linux-generic/odp_queue_scalable.c
index a6d7e2ed..ea561a33 100644
--- a/platform/linux-generic/odp_queue_scalable.c
+++ b/platform/linux-generic/odp_queue_scalable.c
@@ -207,34 +207,30 @@ static int queue_init_global(void)
_odp_queue_inline_offset.context = offsetof(queue_entry_t,
s.param.context);
- /* Attach to the pool if it exists */
- queue_shm_pool = _odp_ishm_pool_lookup("queue_shm_pool");
+ /* Create shared memory pool to allocate shared memory for the
+ * queues. Use the default queue size.
+ */
+ /* Add size of the array holding the queues */
+ pool_size = sizeof(queue_table_t);
+ /* Add storage required for queues */
+ pool_size += (CONFIG_SCAL_QUEUE_SIZE *
+ sizeof(odp_buffer_hdr_t *)) * ODP_CONFIG_QUEUES;
+
+ /* Add the reorder window size */
+ pool_size += sizeof(reorder_window_t) * ODP_CONFIG_QUEUES;
+ /* Choose min_alloc and max_alloc such that buddy allocator is
+ * is selected.
+ */
+ min_alloc = 0;
+ max_alloc = CONFIG_SCAL_QUEUE_SIZE * sizeof(odp_buffer_hdr_t *);
+ queue_shm_pool = _odp_ishm_pool_create("queue_shm_pool",
+ pool_size,
+ min_alloc, max_alloc,
+ _ODP_ISHM_SINGLE_VA);
if (queue_shm_pool == NULL) {
- /* Create shared memory pool to allocate shared memory for the
- * queues. Use the default queue size.
- */
- /* Add size of the array holding the queues */
- pool_size = sizeof(queue_table_t);
- /* Add storage required for queues */
- pool_size += (CONFIG_SCAL_QUEUE_SIZE *
- sizeof(odp_buffer_hdr_t *)) * ODP_CONFIG_QUEUES;
-
- /* Add the reorder window size */
- pool_size += sizeof(reorder_window_t) * ODP_CONFIG_QUEUES;
- /* Choose min_alloc and max_alloc such that buddy allocator is
- * is selected.
- */
- min_alloc = 0;
- max_alloc = CONFIG_SCAL_QUEUE_SIZE * sizeof(odp_buffer_hdr_t *);
- queue_shm_pool = _odp_ishm_pool_create("queue_shm_pool",
- pool_size,
- min_alloc, max_alloc,
- _ODP_ISHM_SINGLE_VA);
- if (queue_shm_pool == NULL) {
- ODP_ERR("Failed to allocate shared memory pool for"
- " queues\n");
- goto queue_shm_pool_create_failed;
- }
+ ODP_ERR("Failed to allocate shared memory pool for"
+ " queues\n");
+ goto queue_shm_pool_create_failed;
}
queue_tbl = (queue_table_t *)
diff --git a/platform/linux-generic/odp_schedule_scalable.c b/platform/linux-generic/odp_schedule_scalable.c
index f3f43d4e..05c0fcaf 100644
--- a/platform/linux-generic/odp_schedule_scalable.c
+++ b/platform/linux-generic/odp_schedule_scalable.c
@@ -1770,6 +1770,7 @@ static int schedule_init_global(void)
odp_schedule_group_t tmp_wrkr;
odp_schedule_group_t tmp_ctrl;
odp_shm_t shm;
+ _odp_ishm_pool_t *pool;
uint32_t bits;
uint32_t pool_size;
uint64_t min_alloc;
@@ -1788,34 +1789,28 @@ static int schedule_init_global(void)
memset(global, 0, sizeof(sched_global_t));
global->shm = shm;
- /* Attach to the pool if it exists */
- global->sched_shm_pool = _odp_ishm_pool_lookup("sched_shm_pool");
- if (global->sched_shm_pool == NULL) {
- _odp_ishm_pool_t *pool;
-
- /* Add storage required for sched groups. Assume worst case
- * xfactor of MAXTHREADS.
- */
- pool_size = (sizeof(sched_group_t) +
- (ODP_SCHED_PRIO_NUM * MAXTHREADS - 1) *
- sizeof(sched_queue_t)) * MAX_SCHED_GROUP;
- /* Choose min_alloc and max_alloc such that slab allocator
- * is selected.
- */
- min_alloc = sizeof(sched_group_t) +
- (ODP_SCHED_PRIO_NUM * MAXTHREADS - 1) *
- sizeof(sched_queue_t);
- max_alloc = min_alloc;
- pool = _odp_ishm_pool_create("sched_shm_pool", pool_size,
- min_alloc, max_alloc,
- _ODP_ISHM_SINGLE_VA);
- if (pool == NULL) {
- ODP_ERR("Failed to allocate shared memory pool "
- "for sched\n");
- goto failed_sched_shm_pool_create;
- }
- global->sched_shm_pool = pool;
- }
+ /* Add storage required for sched groups. Assume worst case
+ * xfactor of MAXTHREADS.
+ */
+ pool_size = (sizeof(sched_group_t) +
+ (ODP_SCHED_PRIO_NUM * MAXTHREADS - 1) *
+ sizeof(sched_queue_t)) * MAX_SCHED_GROUP;
+ /* Choose min_alloc and max_alloc such that slab allocator
+ * is selected.
+ */
+ min_alloc = sizeof(sched_group_t) +
+ (ODP_SCHED_PRIO_NUM * MAXTHREADS - 1) *
+ sizeof(sched_queue_t);
+ max_alloc = min_alloc;
+ pool = _odp_ishm_pool_create("sched_shm_pool", pool_size,
+ min_alloc, max_alloc,
+ _ODP_ISHM_SINGLE_VA);
+ if (pool == NULL) {
+ ODP_ERR("Failed to allocate shared memory pool "
+ "for sched\n");
+ goto failed_sched_shm_pool_create;
+ }
+ global->sched_shm_pool = pool;
odp_spinlock_init(&global->sched_grp_lock);
-----------------------------------------------------------------------
Summary of changes:
.travis.yml | 8 +-
config/odp-linux-generic.conf | 5 +-
.../linux-generic/arch/aarch64/odp_sysinfo_parse.c | 1 -
.../linux-generic/arch/default/odp_sysinfo_parse.c | 16 +-
.../linux-generic/arch/x86/odp_sysinfo_parse.c | 2 +
.../linux-generic/include/odp_config_internal.h | 10 -
.../linux-generic/include/odp_ishmphy_internal.h | 6 +-
.../linux-generic/include/odp_ishmpool_internal.h | 1 -
platform/linux-generic/include/odp_shm_internal.h | 6 +-
.../linux-generic/include/odp_sysinfo_internal.h | 19 +
platform/linux-generic/odp_ishm.c | 676 ++++++++++-----------
platform/linux-generic/odp_ishmphy.c | 140 ++---
platform/linux-generic/odp_ishmpool.c | 24 +-
platform/linux-generic/odp_queue_scalable.c | 49 +-
platform/linux-generic/odp_schedule_scalable.c | 51 +-
platform/linux-generic/odp_shared_memory.c | 2 +-
platform/linux-generic/odp_system_info.c | 17 +-
platform/linux-generic/test/process-mode.conf | 5 +-
.../test/validation/api/shmem/shmem_linux.c | 17 +-
test/validation/api/pool/pool.c | 103 ++++
test/validation/api/shmem/shmem.c | 14 +-
21 files changed, 595 insertions(+), 577 deletions(-)
hooks/post-receive
--
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "".
The branch, master has been updated
via 2f1c802e45b2e860e641d84c15368cca6cc3454d (commit)
from 5d6ad599eb9f6b05d3890f2b0aae3746b8a2b73e (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 2f1c802e45b2e860e641d84c15368cca6cc3454d
Author: Petri Savolainen <petri.savolainen(a)linaro.org>
Date: Mon Nov 12 14:20:15 2018 +0200
test: queue_perf: fix lockfree support check
Exit application when -l/-w option is used, but lockfree/waitfree
queues are not supported.
Signed-off-by: Petri Savolainen <petri.savolainen(a)linaro.org>
Reviewed-by: Bill Fischofer <bill.fischofer(a)linaro.org>
Signed-off-by: Maxim Uvarov <maxim.uvarov(a)linaro.org>
diff --git a/test/performance/odp_queue_perf.c b/test/performance/odp_queue_perf.c
index 09c8592b..80d0f154 100644
--- a/test/performance/odp_queue_perf.c
+++ b/test/performance/odp_queue_perf.c
@@ -205,7 +205,7 @@ static int create_queues(test_global_t *global)
} else if (nonblock == ODP_NONBLOCKING_LF) {
if (queue_capa.plain.lockfree.max_num == 0) {
printf("Lockfree queues not supported\n");
- return 0;
+ return -1;
}
if (num_queue > queue_capa.plain.lockfree.max_num) {
@@ -223,7 +223,7 @@ static int create_queues(test_global_t *global)
} else if (nonblock == ODP_NONBLOCKING_WF) {
if (queue_capa.plain.waitfree.max_num == 0) {
printf("Waitfree queues not supported\n");
- return 0;
+ return -1;
}
if (num_queue > queue_capa.plain.waitfree.max_num) {
@@ -327,8 +327,7 @@ static int destroy_queues(test_global_t *global)
for (i = 0; i < num_queue; i++) {
if (queue[i] == ODP_QUEUE_INVALID) {
- printf("Error: Invalid queue handle %u.\n", i);
- ret = -1;
+ printf("Error: Invalid queue handle (i: %u).\n", i);
break;
}
@@ -346,7 +345,7 @@ static int destroy_queues(test_global_t *global)
}
}
- if (odp_pool_destroy(pool)) {
+ if (pool != ODP_POOL_INVALID && odp_pool_destroy(pool)) {
printf("Error: Pool destroy failed.\n");
ret = -1;
}
-----------------------------------------------------------------------
Summary of changes:
test/performance/odp_queue_perf.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
hooks/post-receive
--