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, api-next has been updated via 8511e88c69f5bf7cd251875610370aa334878788 (commit) via 898d834f8c7164e4ee1a99fbe9115b3c7ca5bd67 (commit) via 42fd89a1ee51a2535192650a8cffc05c32b0da12 (commit) via c3a6bf82fa3b2cb742eb33ff66096f6f79be2c32 (commit) via a9402619bd06f1e1ac9ada694484a104fcfff7d5 (commit) via 6f9209f69f69ba8cfe51ff440f978b7d82d13245 (commit) via d24149493d8733fc898fabbd718492717ad0e498 (commit) via 5de83b54f16d8078b306f4e89e299154eb5972a2 (commit) via 7d46bfe20a88358546859078cb7d09a1ff49fb6f (commit) via 4a8039c26c7cc5aaa9b4485315879fba8fadacf7 (commit) via 51254145370423631b3ac778865e06be2e418141 (commit) via fa2fb9f553142adaa7526069ce3070814f915c32 (commit) via 64991d2a01c36513e8c1a9518da9a56cb9f32594 (commit) via efb3dc0e6524b32442dc50f5ced9ce1f1d6fd948 (commit) via 02b60f6739a3980cab9cd1afca5dcc1fedd84a1e (commit) via 406dc695c3fc756bac6ecef3c7d67348699e7a25 (commit) via 1bb388931c9101f38703142fda4f6b9e0bff52c4 (commit) via 6fd24dd1f81b2ca5442d19bd66ffd902de651934 (commit) via 833470a13c2068890bfacdbf99bacce55bed2db2 (commit) via 374301a2aa5ba6dfa81aa4c70fd24ed59141c012 (commit) via f913948f5daa4cb1f71467d872b5380974b04f2d (commit) via f703d49c196a6c6c9d29d3c7b04c02d727795a2c (commit) via 5eb5837adf64b14e795483a6cdf4e83124c56be8 (commit) via 4964f08fa748eb61949fff147e930be72555d233 (commit) via 263a5bb884c3e274174b1d1e4e0ae497143b1f81 (commit) via 3e007fea33316e1d7d66cd7ea19541a1653b501c (commit) via f8eda649cd915654175c9723aca75adaae88c3d3 (commit) via 96a177a6322a9d8fad99d43271d1b98ecd5d12a5 (commit) via 3529f3b8713021e45c7dbdd81f839d8b9049efcc (commit) via af055783f975e2b8b9e443565b3abdc9f7946ade (commit) via 8d9936c45c4a9f8db9142057d8acee41d54e0b51 (commit) via 2a6485f25dc9b0612cccf40a2360dc6d40becb78 (commit) via 91fee166b0dbf4949f1a1786e167a6948b1e8f52 (commit) via 01e4772d22537772001714318d5f501f082b6c5e (commit) via f8bbdfc98be5d86dea67cc34ee97a4b69c052d61 (commit) via 295bf070e27323060ba607805dd95ce0353a9461 (commit) via ae66a05708d04f332d85fb258196d9045ebc303c (commit) via eb3a816cb0fa6c5e76b25398a0ac280c769dcb49 (commit) from 1ee7da08721452033dd7b0537e62ec1191291120 (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 8511e88c69f5bf7cd251875610370aa334878788 Author: Maxim Uvarov maxim.uvarov@linaro.org Date: Tue Nov 27 18:01:38 2018 +0300
linux-gen: drop performance.m4
performance.m4 which provides --enable-test-perf-proc is not needed now because process mode is tested with standard tests.
Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org Reviewed-by: Bill Fischofer bill.fischofer@linaro.org
diff --git a/platform/linux-generic/m4/configure.m4 b/platform/linux-generic/m4/configure.m4 index c3aa7396..1dd14cd4 100644 --- a/platform/linux-generic/m4/configure.m4 +++ b/platform/linux-generic/m4/configure.m4 @@ -20,8 +20,6 @@ m4_include([platform/linux-generic/m4/odp_netmap.m4]) m4_include([platform/linux-generic/m4/odp_dpdk.m4]) ODP_SCHEDULER
-m4_include([platform/linux-generic/m4/performance.m4]) - AC_CONFIG_COMMANDS_PRE([dnl AM_CONDITIONAL([PLATFORM_IS_LINUX_GENERIC], [test "${with_platform}" = "linux-generic"]) diff --git a/platform/linux-generic/m4/performance.m4 b/platform/linux-generic/m4/performance.m4 deleted file mode 100644 index f2e7107c..00000000 --- a/platform/linux-generic/m4/performance.m4 +++ /dev/null @@ -1,10 +0,0 @@ -########################################################################## -# Enable/disable test-perf-proc -########################################################################## -AC_ARG_ENABLE([test-perf-proc], - [AS_HELP_STRING([--enable-test-perf-proc], [run test in test/performance in process mode])], - [test_perf_proc=$enableval], - [test_perf_proc=yes]) -AC_CONFIG_COMMANDS_PRE([dnl -AM_CONDITIONAL([test_perf_proc], [test x$test_perf_proc = xyes ]) -])
commit 898d834f8c7164e4ee1a99fbe9115b3c7ca5bd67 Author: Matias Elo matias.elo@nokia.com Date: Mon Nov 26 15:57:33 2018 +0200
example: generator: add signal handler for SIGINT
Free used resources after receiving SIGINT.
Signed-off-by: Matias Elo matias.elo@nokia.com Reviewed-by: Bill Fischofer bill.fischofer@linaro.org
diff --git a/example/generator/odp_generator.c b/example/generator/odp_generator.c index 98a89211..bd6af795 100644 --- a/example/generator/odp_generator.c +++ b/example/generator/odp_generator.c @@ -15,6 +15,7 @@ #include <unistd.h> #include <inttypes.h> #include <sys/time.h> +#include <signal.h>
#include <example_debug.h>
@@ -168,6 +169,14 @@ static void usage(char *progname); static int scan_ip(char *buf, unsigned int *paddr); static void print_global_stats(int num_workers);
+static void sig_handler(int signo ODP_UNUSED) +{ + int i; + + for (i = 0; i < args->thread_cnt; i++) + args->thread[i].stop = 1; +} + /** * Scan ip * Parse ip address. @@ -1105,6 +1114,10 @@ int main(int argc, char *argv[]) odp_init_t init_param; odph_odpthread_params_t thr_params;
+ /* Signal handler has to be registered before global init in case ODP + * implementation creates internal threads/processes. */ + signal(SIGINT, sig_handler); + /* Let helper collect its own arguments (e.g. --odph_proc) */ argc = odph_parse_options(argc, argv); if (odph_options(&helper_options)) { diff --git a/test/performance/odp_l2fwd_run.sh b/test/performance/odp_l2fwd_run.sh index 6166c8b2..5745d327 100755 --- a/test/performance/odp_l2fwd_run.sh +++ b/test/performance/odp_l2fwd_run.sh @@ -88,7 +88,7 @@ run_l2fwd() $STDBUF odp_l2fwd${EXEEXT} -i $IF1,$IF2 -m 0 -t 30 -c 2 | tee $LOG ret=$?
- kill ${GEN_PID} + kill -2 ${GEN_PID}
if [ ! -f $LOG ]; then echo "FAIL: $LOG not found" diff --git a/test/performance/odp_sched_pktio_run.sh b/test/performance/odp_sched_pktio_run.sh index db14fb59..1c8d2945 100755 --- a/test/performance/odp_sched_pktio_run.sh +++ b/test/performance/odp_sched_pktio_run.sh @@ -72,7 +72,7 @@ run_sched_pktio() # Run test for 5 sec sleep 5
- kill ${GEN_PID} + kill -2 ${GEN_PID} wait ${GEN_PID}
# Kill with SIGINT to output statistics
commit 42fd89a1ee51a2535192650a8cffc05c32b0da12 Author: Maxim Uvarov maxim.uvarov@linaro.org Date: Mon Nov 26 17:23:28 2018 +0300
text: perf odp_sched_pktio: try to terminate on failure
try to do clean up even if error was detected (try to remove openned files for mmap.)
Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org Reviewed-by: Bill Fischofer bill.fischofer@linaro.org
diff --git a/test/performance/odp_sched_pktio.c b/test/performance/odp_sched_pktio.c index 239e12e9..393ea352 100644 --- a/test/performance/odp_sched_pktio.c +++ b/test/performance/odp_sched_pktio.c @@ -1547,17 +1547,17 @@ quit:
if (odp_shm_free(shm)) { printf("Error: shm free failed.\n"); - return -1; + ret = -1; }
if (odp_term_local()) { printf("Error: term local failed.\n"); - return -1; + ret = -1; }
if (odp_term_global(instance)) { printf("Error: term global failed.\n"); - return -1; + ret = -1; }
return ret;
commit c3a6bf82fa3b2cb742eb33ff66096f6f79be2c32 Author: Maxim Uvarov maxim.uvarov@linaro.org Date: Mon Nov 26 17:21:00 2018 +0300
linux-gen: ishm: add missing cast to calculate max_memory
Fix integer overflow doing math for max_memory.
Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org Reviewed-by: Bill Fischofer bill.fischofer@linaro.org
diff --git a/platform/linux-generic/odp_ishm.c b/platform/linux-generic/odp_ishm.c index eceadd99..875f9f9d 100644 --- a/platform/linux-generic/odp_ishm.c +++ b/platform/linux-generic/odp_ishm.c @@ -1646,7 +1646,7 @@ int _odp_ishm_init_global(const odp_init_t *init)
ODP_DBG("Shm single VA size: %dkB\n", val_kb);
- max_memory = val_kb * 1024; + max_memory = (uint64_t)val_kb * 1024; internal = max_memory / 8;
if (!_odp_libconfig_lookup_ext_int("shm", NULL, "huge_page_limit_kb",
commit a9402619bd06f1e1ac9ada694484a104fcfff7d5 Author: Maxim Uvarov maxim.uvarov@linaro.org Date: Mon Nov 26 12:32:15 2018 +0300
linux-gen: remove performance test for process mode
process mode tests run when process mode config is specified. Here it has to be dropped.
Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org Reviewed-by: Bill Fischofer bill.fischofer@linaro.org
diff --git a/platform/linux-generic/m4/configure.m4 b/platform/linux-generic/m4/configure.m4 index f9e9c494..c3aa7396 100644 --- a/platform/linux-generic/m4/configure.m4 +++ b/platform/linux-generic/m4/configure.m4 @@ -33,6 +33,5 @@ AC_CONFIG_FILES([platform/linux-generic/Makefile platform/linux-generic/test/validation/api/pktio/Makefile platform/linux-generic/test/mmap_vlan_ins/Makefile platform/linux-generic/test/pktio_ipc/Makefile - platform/linux-generic/test/ring/Makefile - platform/linux-generic/test/performance/Makefile]) + platform/linux-generic/test/ring/Makefile]) ]) diff --git a/platform/linux-generic/test/Makefile.am b/platform/linux-generic/test/Makefile.am index 99934099..03a1474d 100644 --- a/platform/linux-generic/test/Makefile.am +++ b/platform/linux-generic/test/Makefile.am @@ -1,7 +1,7 @@ include $(top_srcdir)/test/Makefile.inc TESTS_ENVIRONMENT += TEST_DIR=${top_builddir}/test/validation
-SUBDIRS = performance +SUBDIRS =
if test_vald TESTS = validation/api/pktio/pktio_run.sh \ @@ -9,10 +9,10 @@ TESTS = validation/api/pktio/pktio_run.sh \ validation/api/shmem/shmem_linux$(EXEEXT)
SUBDIRS += validation/api/pktio\ - validation/api/shmem\ - mmap_vlan_ins\ - pktio_ipc\ - ring + validation/api/shmem\ + mmap_vlan_ins\ + pktio_ipc\ + ring
if HAVE_PCAP TESTS += validation/api/pktio/pktio_run_pcap.sh diff --git a/platform/linux-generic/test/performance/.gitignore b/platform/linux-generic/test/performance/.gitignore deleted file mode 100644 index 7e563b8b..00000000 --- a/platform/linux-generic/test/performance/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -*.log -*.trs diff --git a/platform/linux-generic/test/performance/Makefile.am b/platform/linux-generic/test/performance/Makefile.am deleted file mode 100644 index 0b5da671..00000000 --- a/platform/linux-generic/test/performance/Makefile.am +++ /dev/null @@ -1,13 +0,0 @@ -include $(top_srcdir)/test/Makefile.inc - -TESTS_ENVIRONMENT += TEST_DIR=${builddir} - -TESTSCRIPTS = odp_scheduling_run_proc.sh - -TEST_EXTENSIONS = .sh - -if test_perf_proc -TESTS = $(TESTSCRIPTS) -endif - -dist_check_SCRIPTS = $(TESTSCRIPTS) diff --git a/platform/linux-generic/test/performance/odp_scheduling_run_proc.sh b/platform/linux-generic/test/performance/odp_scheduling_run_proc.sh deleted file mode 100755 index c16bcb86..00000000 --- a/platform/linux-generic/test/performance/odp_scheduling_run_proc.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2016-2018, Linaro Limited -# All rights reserved. -# -# SPDX-License-Identifier: BSD-3-Clause -# -# Script that passes command line arguments to odp_scheduling test when -# launched by 'make check' - -TEST_DIR="${TEST_DIR:-$(dirname $0)}" -PERFORMANCE="$TEST_DIR/../../../../test/performance" -ret=0 -ALL=0 - -run() -{ - echo odp_scheduling_run starts requesting $1 worker threads - echo ===================================================== - - $PERFORMANCE/odp_scheduling${EXEEXT} --odph_proc -c $1 || ret=1 -} - -run 1 -run 5 -run 8 -run 11 -run $ALL - -exit $ret
commit 6f9209f69f69ba8cfe51ff440f978b7d82d13245 Author: Maxim Uvarov maxim.uvarov@linaro.org Date: Fri Nov 23 22:34:16 2018 +0300
travis: check.sh request huge pages at early start
Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org Reviewed-by: Bill Fischofer bill.fischofer@linaro.org
diff --git a/scripts/ci/check.sh b/scripts/ci/check.sh index 43168680..85cee498 100755 --- a/scripts/ci/check.sh +++ b/scripts/ci/check.sh @@ -1,14 +1,14 @@ #!/bin/bash set -e
-"`dirname "$0"`"/build_x86_64.sh - -cd "$(dirname "$0")"/../.. - echo 1000 | tee /proc/sys/vm/nr_hugepages mkdir -p /mnt/huge mount -t hugetlbfs nodev /mnt/huge
+"`dirname "$0"`"/build_x86_64.sh + +cd "$(dirname "$0")"/../.. + # Ignore possible failures there because these tests depends on measurements # and systems might differ in performance. export CI="true"
commit d24149493d8733fc898fabbd718492717ad0e498 Author: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Date: Fri Nov 16 16:32:19 2018 +0300
shippable: switch to using official Shippable image
Signed-off-by: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/.shippable.yml b/.shippable.yml index 5696be1e..0bf68f33 100644 --- a/.shippable.yml +++ b/.shippable.yml @@ -14,18 +14,9 @@ env: # - CROSS_ARCH="i386"
build: - pre_ci: - # use Dockerfile to install additional CI dependencies - - docker build -t=odp/dev ./scripts - - # use image built in 'pre_ci' for CI job - pre_ci_boot: - image_name: odp/dev - image_tag: latest - pull: false - options: - ci: + - apt-get update + - apt-get install --no-install-recommends -yy asciidoctor autoconf automake build-essential ccache clang doxygen gcc graphviz libconfig-dev libcunit1-dev libnuma-dev libpcap-dev libssl-dev libtool mscgen xsltproc - mkdir -p $HOME/odp-shmdir - export CI=true ODP_SHM_DIR=$HOME/odp-shmdir ODP_TEST_OUT_XML=yes - ./bootstrap diff --git a/scripts/Dockerfile b/scripts/Dockerfile deleted file mode 100644 index b4c03ca4..00000000 --- a/scripts/Dockerfile +++ /dev/null @@ -1,28 +0,0 @@ -FROM drydockaarch64/u16:v5.10.1 - -RUN if $(sudo update-alternatives --list gcc); \ - then sudo update-alternatives --remove-all gcc; \ - fi - -RUN sudo apt-get update && sudo apt-get install -yy \ - autoconf \ - automake \ - ccache \ - clang-4.0 \ - gcc-4.8 \ - graphviz \ - kmod \ - libconfig-dev \ - libcunit1-dev \ - libnuma-dev \ - libpcap-dev \ - libssl-dev \ - libtool \ - linux-headers-`uname -r` \ - mscgen \ - ruby-dev \ - xsltproc - -RUN sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 10 -RUN sudo ln -s /usr/bin/clang-4.0 /usr/bin/clang -RUN sudo ln -s /usr/bin/clang++-4.0 /usr/bin/clang++
commit 5de83b54f16d8078b306f4e89e299154eb5972a2 Author: Maxim Uvarov maxim.uvarov@linaro.org Date: Mon Nov 19 17:53:46 2018 +0300
configure: disable -march=native for clang
for clang we see strange optimizations for TM code which breaks code flow execution. There might be number of such places. For now it's better to disable march=native until we completely test and validate clang support for this.
Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org Reviewed-by: Petri Savolainen petri.savolainen@linaro.org
diff --git a/configure.ac b/configure.ac index 6715a7ef..2ce476a6 100644 --- a/configure.ac +++ b/configure.ac @@ -200,7 +200,12 @@ AC_ARG_ENABLE([abi-compat], abi_compat=no #if there is no ABI compatibility the .so numbers are meaningless ODP_LIBSO_VERSION=0:0:0 - ODP_CHECK_CFLAG([-march=native]) + # do not try -march=native for clang due to possible failures on + # clang optimizations + $CC --version | grep -q clang + if test $? -ne 0; then + ODP_CHECK_CFLAG([-march=native]) + fi fi]) AM_CONDITIONAL(ODP_ABI_COMPAT, [test "x$ODP_ABI_COMPAT" = "x1"])
commit 7d46bfe20a88358546859078cb7d09a1ff49fb6f Author: Maxim Uvarov maxim.uvarov@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@linaro.org Reviewed-by: Petri Savolainen petri.savolainen@linaro.org
diff --git a/.travis.yml b/.travis.yml index 848cfd61..85ab9ae4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -232,7 +232,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:
commit 4a8039c26c7cc5aaa9b4485315879fba8fadacf7 Author: Matias Elo matias.elo@nokia.com Date: Wed Nov 14 14:28:53 2018 +0200
linux-gen: ishm: add config option for selecting huge page usage limit
Add configuration option for selecting huge page usage limit in kilobytes. Memory reservations larger than this value are done using huge pages (if available), whereas smaller reservations are done using normal pages to conserve memory. The default value is still 64 kilobytes.
Signed-off-by: Matias Elo matias.elo@nokia.com Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/config/odp-linux-generic.conf b/config/odp-linux-generic.conf index 8f39ff7c..895f996b 100644 --- a/config/odp-linux-generic.conf +++ b/config/odp-linux-generic.conf @@ -34,6 +34,11 @@ shm: { # because the current implementation won't work properly otherwise. num_cached_hp = 0
+ # Huge page usage limit in kilobytes. Memory reservations larger than + # this value are done using huge pages (if available). Smaller + # reservations are done using normal pages to conserve memory. + huge_page_limit_kb = 64 + # Amount of memory pre-reserved for ODP_SHM_SINGLE_VA usage in kilobytes single_va_size_kb = 131072 } diff --git a/platform/linux-generic/odp_ishm.c b/platform/linux-generic/odp_ishm.c index eea527db..eceadd99 100644 --- a/platform/linux-generic/odp_ishm.c +++ b/platform/linux-generic/odp_ishm.c @@ -113,13 +113,6 @@ */ #define ISHM_NB_FRAGMNTS (ISHM_MAX_NB_BLOCKS * 2 + 1)
-/* - * Memory reservations larger than ISHM_HUGE_PAGE_LIMIT (bytes) are allocated - * using huge pages (if available). Smaller reservations are done using normal - * pages to conserve memory. - */ -#define ISHM_HUGE_PAGE_LIMIT (64 * 1024) - /* * when a memory block is to be exported outside its ODP instance, * an block 'attribute file' is created in /dev/shm/odp-<pid>-shm-<name>. @@ -190,6 +183,8 @@ typedef struct ishm_block { typedef struct { odp_spinlock_t lock; uint64_t dev_seq; /* used when creating device names */ + /* limit for reserving memory using huge pages */ + uint64_t huge_page_limit; 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 */ @@ -1101,7 +1096,7 @@ int _odp_ishm_reserve(const char *name, uint64_t size, int fd,
/* Otherwise, Try first huge pages when possible and needed: */ if ((fd < 0) && page_hp_size && ((flags & _ODP_ISHM_USE_HP) || - size > ISHM_HUGE_PAGE_LIMIT)) { + size > ishm_tbl->huge_page_limit)) { /* at least, alignment in VA should match page size, but user * can request more: If the user requirement exceeds the page * size then we have to make sure the block will be mapped at @@ -1636,23 +1631,33 @@ int _odp_ishm_init_global(const odp_init_t *init) void *addr; void *spce_addr = NULL; int i; - int single_va_size_kb = 0; + int val_kb; uid_t uid; char *hp_dir = odp_global_ro.hugepage_info.default_huge_page_dir; uint64_t max_memory; uint64_t internal; + uint64_t huge_page_limit;
if (!_odp_libconfig_lookup_ext_int("shm", NULL, "single_va_size_kb", - &single_va_size_kb)) { + &val_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); + ODP_DBG("Shm single VA size: %dkB\n", val_kb);
- max_memory = single_va_size_kb * 1024; + max_memory = val_kb * 1024; internal = max_memory / 8;
+ if (!_odp_libconfig_lookup_ext_int("shm", NULL, "huge_page_limit_kb", + &val_kb)) { + ODP_ERR("Unable to read huge page usage limit from config\n"); + return -1; + } + huge_page_limit = (uint64_t)val_kb * 1024; + + ODP_DBG("Shm huge page usage limit: %dkB\n", val_kb); + /* user requested memory size + some extra for internal use */ if (init && init->shm.max_memory) max_memory = init->shm.max_memory + internal; @@ -1703,6 +1708,7 @@ int _odp_ishm_init_global(const odp_init_t *init) memset(ishm_tbl, 0, sizeof(ishm_table_t)); ishm_tbl->dev_seq = 0; ishm_tbl->odpthread_cnt = 0; + ishm_tbl->huge_page_limit = huge_page_limit; odp_spinlock_init(&ishm_tbl->lock);
/* allocate space for the internal shared mem fragment table: */
commit 51254145370423631b3ac778865e06be2e418141 Author: Matias Elo matias.elo@nokia.com Date: Tue Nov 13 16:11:17 2018 +0200
linux-gen: timer: decrease inline timer polling interval under load
Decrease inline timer polling interval after receiving events to compansate for event processing delay.
Signed-off-by: Matias Elo matias.elo@nokia.com Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/platform/linux-generic/include/odp_timer_internal.h b/platform/linux-generic/include/odp_timer_internal.h index 1f612448..cd80778a 100644 --- a/platform/linux-generic/include/odp_timer_internal.h +++ b/platform/linux-generic/include/odp_timer_internal.h @@ -36,12 +36,14 @@ typedef struct { odp_timer_t timer; } odp_timeout_hdr_t;
-unsigned _timer_run(void); +/* A larger decrement value should be used after receiving events compared to + * an 'empty' call. */ +unsigned int _timer_run(int dec);
/* Static inline wrapper to minimize modification of schedulers. */ -static inline unsigned timer_run(void) +static inline unsigned int timer_run(int dec) { - return odp_global_rw->inline_timers ? _timer_run() : 0; + return odp_global_rw->inline_timers ? _timer_run(dec) : 0; }
#endif diff --git a/platform/linux-generic/odp_queue_basic.c b/platform/linux-generic/odp_queue_basic.c index c3654884..37a2fad1 100644 --- a/platform/linux-generic/odp_queue_basic.c +++ b/platform/linux-generic/odp_queue_basic.c @@ -984,27 +984,30 @@ static int queue_api_enq(odp_queue_t handle, odp_event_t ev) static int queue_api_deq_multi(odp_queue_t handle, odp_event_t ev[], int num) { queue_entry_t *queue = qentry_from_handle(handle); - - if (odp_global_rw->inline_timers && - odp_atomic_load_u64(&queue->s.num_timers)) - timer_run(); + int ret;
if (num > QUEUE_MULTI_MAX) num = QUEUE_MULTI_MAX;
- return queue->s.dequeue_multi(handle, - (odp_buffer_hdr_t **)ev, num); + ret = queue->s.dequeue_multi(handle, (odp_buffer_hdr_t **)ev, num); + + if (odp_global_rw->inline_timers && + odp_atomic_load_u64(&queue->s.num_timers)) + timer_run(ret ? 2 : 1); + + return ret; }
static odp_event_t queue_api_deq(odp_queue_t handle) { queue_entry_t *queue = qentry_from_handle(handle); + odp_event_t ev = (odp_event_t)queue->s.dequeue(handle);
if (odp_global_rw->inline_timers && odp_atomic_load_u64(&queue->s.num_timers)) - timer_run(); + timer_run(ev != ODP_EVENT_INVALID ? 2 : 1);
- return (odp_event_t)queue->s.dequeue(handle); + return ev; }
/* API functions */ diff --git a/platform/linux-generic/odp_queue_scalable.c b/platform/linux-generic/odp_queue_scalable.c index 2de4d52d..88abe8c7 100644 --- a/platform/linux-generic/odp_queue_scalable.c +++ b/platform/linux-generic/odp_queue_scalable.c @@ -850,30 +850,32 @@ static odp_buffer_hdr_t *_queue_deq(odp_queue_t handle) static int queue_deq_multi(odp_queue_t handle, odp_event_t ev[], int num) { queue_entry_t *queue; + int ret;
if (num > QUEUE_MULTI_MAX) num = QUEUE_MULTI_MAX;
queue = qentry_from_ext(handle);
+ ret = queue->s.dequeue_multi(handle, (odp_buffer_hdr_t **)ev, num); + if (odp_global_rw->inline_timers && odp_atomic_load_u64(&queue->s.num_timers)) - timer_run(); + timer_run(ret ? 2 : 1);
- return queue->s.dequeue_multi(handle, (odp_buffer_hdr_t **)ev, num); + return ret; }
static odp_event_t queue_deq(odp_queue_t handle) { - queue_entry_t *queue; - - queue = qentry_from_ext(handle); + queue_entry_t *queue = qentry_from_ext(handle); + odp_event_t ev = (odp_event_t)queue->s.dequeue(handle);
if (odp_global_rw->inline_timers && odp_atomic_load_u64(&queue->s.num_timers)) - timer_run(); + timer_run(ev != ODP_EVENT_INVALID ? 2 : 1);
- return (odp_event_t)queue->s.dequeue(handle); + return ev; }
static void queue_param_init(odp_queue_param_t *params) diff --git a/platform/linux-generic/odp_schedule_basic.c b/platform/linux-generic/odp_schedule_basic.c index cf566eb8..48f232e6 100644 --- a/platform/linux-generic/odp_schedule_basic.c +++ b/platform/linux-generic/odp_schedule_basic.c @@ -1181,7 +1181,7 @@ static inline int do_schedule(odp_queue_t *out_queue, odp_event_t out_ev[], static inline int schedule_run(odp_queue_t *out_queue, odp_event_t out_ev[], unsigned int max_num) { - timer_run(); + timer_run(1);
return do_schedule(out_queue, out_ev, max_num); } @@ -1194,10 +1194,13 @@ static inline int schedule_loop(odp_queue_t *out_queue, uint64_t wait, int ret;
while (1) { - ret = schedule_run(out_queue, out_ev, max_num);
- if (ret) + ret = do_schedule(out_queue, out_ev, max_num); + if (ret) { + timer_run(2); break; + } + timer_run(1);
if (wait == ODP_SCHED_WAIT) continue; diff --git a/platform/linux-generic/odp_schedule_scalable.c b/platform/linux-generic/odp_schedule_scalable.c index 5d83ed08..4e9dd771 100644 --- a/platform/linux-generic/odp_schedule_scalable.c +++ b/platform/linux-generic/odp_schedule_scalable.c @@ -883,7 +883,7 @@ static int _schedule(odp_queue_t *from, odp_event_t ev[], int num_evts) ts = sched_ts; atomq = ts->atomq;
- timer_run(); + timer_run(1);
/* Once an atomic queue has been scheduled to a thread, it will stay * on that thread until empty or 'rotated' by WRR diff --git a/platform/linux-generic/odp_schedule_sp.c b/platform/linux-generic/odp_schedule_sp.c index b8f805ac..eec88a60 100644 --- a/platform/linux-generic/odp_schedule_sp.c +++ b/platform/linux-generic/odp_schedule_sp.c @@ -571,8 +571,6 @@ static int schedule_multi(odp_queue_t *from, uint64_t wait, uint32_t qi; int num;
- timer_run(); - cmd = sched_cmd();
if (cmd && cmd->s.type == CMD_PKTIO) { @@ -612,6 +610,7 @@ static int schedule_multi(odp_queue_t *from, uint64_t wait, }
if (cmd == NULL) { + timer_run(1); /* All priority queues are empty */ if (wait == ODP_SCHED_NO_WAIT) return 0; @@ -636,6 +635,7 @@ static int schedule_multi(odp_queue_t *from, uint64_t wait, num = sched_queue_deq(qi, events, 1, 1);
if (num <= 0) { + timer_run(1); /* Destroyed or empty queue. Remove empty queue from * scheduling. A dequeue operation to on an already * empty queue moves it to NOTSCHED state and @@ -643,6 +643,8 @@ static int schedule_multi(odp_queue_t *from, uint64_t wait, continue; }
+ timer_run(2); + sched_local.cmd = cmd;
if (from) diff --git a/platform/linux-generic/odp_timer.c b/platform/linux-generic/odp_timer.c index d502c21f..6446b1c9 100644 --- a/platform/linux-generic/odp_timer.c +++ b/platform/linux-generic/odp_timer.c @@ -883,10 +883,10 @@ static unsigned process_timer_pools(void) return nexp; }
-unsigned _timer_run(void) +unsigned int _timer_run(int dec) { static __thread odp_time_t last_timer_run; - static __thread unsigned timer_run_cnt = 1; + static __thread int timer_run_cnt = 1; odp_time_t now;
if (timer_global->num_timer_pools == 0) @@ -895,7 +895,8 @@ unsigned _timer_run(void) /* Rate limit how often this thread checks the timer pools. */
if (timer_global->inline_poll_interval > 1) { - if (--timer_run_cnt) + timer_run_cnt -= dec; + if (timer_run_cnt > 0) return 0; timer_run_cnt = timer_global->inline_poll_interval; }
commit fa2fb9f553142adaa7526069ce3070814f915c32 Author: Matias Elo matias.elo@nokia.com Date: Tue Nov 13 15:08:02 2018 +0200
linux-gen: timer: add config option for inline timer poll frequency
Add configure option 'timer.inline_poll_interval' for adjusting inline timer polling frequency.
Signed-off-by: Matias Elo matias.elo@nokia.com Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/config/odp-linux-generic.conf b/config/odp-linux-generic.conf index 2ac6c44d..8f39ff7c 100644 --- a/config/odp-linux-generic.conf +++ b/config/odp-linux-generic.conf @@ -136,4 +136,11 @@ timer: { # # Set to 1 to enable inline = 0 + + # Inline timer poll interval + # + # When set to 1 inline timers are polled during every schedule round. + # Increasing the value reduces timer processing overhead while + # decreasing accuracy. Ignored when inline timer is not enabled. + inline_poll_interval = 10 } diff --git a/platform/linux-generic/include/odp_timer_internal.h b/platform/linux-generic/include/odp_timer_internal.h index 02ba92e0..1f612448 100644 --- a/platform/linux-generic/include/odp_timer_internal.h +++ b/platform/linux-generic/include/odp_timer_internal.h @@ -21,9 +21,6 @@ #include <odp/api/timer.h> #include <odp_global_data.h>
-/* Minimum number of scheduling rounds between checking timer pools. */ -#define CONFIG_TIMER_RUN_RATELIMIT_ROUNDS 1 - /** * Internal Timeout header */ diff --git a/platform/linux-generic/odp_timer.c b/platform/linux-generic/odp_timer.c index 35bb0482..d502c21f 100644 --- a/platform/linux-generic/odp_timer.c +++ b/platform/linux-generic/odp_timer.c @@ -219,6 +219,7 @@ typedef struct timer_global_t { _odp_atomic_flag_t ODP_ALIGNED_CACHE locks[NUM_LOCKS]; #endif odp_bool_t use_inline_timers; + int inline_poll_interval; } timer_global_t;
static timer_global_t *timer_global; @@ -885,8 +886,7 @@ static unsigned process_timer_pools(void) unsigned _timer_run(void) { static __thread odp_time_t last_timer_run; - static __thread unsigned timer_run_cnt = - CONFIG_TIMER_RUN_RATELIMIT_ROUNDS; + static __thread unsigned timer_run_cnt = 1; odp_time_t now;
if (timer_global->num_timer_pools == 0) @@ -894,10 +894,10 @@ unsigned _timer_run(void)
/* Rate limit how often this thread checks the timer pools. */
- if (CONFIG_TIMER_RUN_RATELIMIT_ROUNDS > 1) { + if (timer_global->inline_poll_interval > 1) { if (--timer_run_cnt) return 0; - timer_run_cnt = CONFIG_TIMER_RUN_RATELIMIT_ROUNDS; + timer_run_cnt = timer_global->inline_poll_interval; }
now = odp_time_global(); @@ -1381,6 +1381,14 @@ int odp_timer_init_global(const odp_init_t *params) } timer_global->use_inline_timers = val;
+ conf_str = "timer.inline_poll_interval"; + if (!_odp_libconfig_lookup_int(conf_str, &val)) { + ODP_ERR("Config option '%s' not found.\n", conf_str); + odp_shm_free(shm); + return -1; + } + timer_global->inline_poll_interval = val; + if (params && params->not_used.feat.timer) timer_global->use_inline_timers = false;
commit 64991d2a01c36513e8c1a9518da9a56cb9f32594 Author: Matias Elo matias.elo@nokia.com Date: Tue Nov 13 15:07:40 2018 +0200
travis: test inline timer implementation
Signed-off-by: Matias Elo matias.elo@nokia.com Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/.travis.yml b/.travis.yml index ec307645..848cfd61 100644 --- a/.travis.yml +++ b/.travis.yml @@ -154,6 +154,19 @@ jobs: -e ODP_CONFIG_FILE=/odp/platform/linux-generic/test/process-mode.conf -e ODPH_PROC_MODE=1 ${DOCKER_NAMESPACE}/travis-odp-lng-ubuntu_16.04 /odp/scripts/ci/check.sh + - stage: test + env: TEST=inline_timer + install: + - true + compiler: gcc + script: + - if [ -z "${DOCKER_NAMESPACE}" ] ; then export DOCKER_NAMESPACE="opendataplane"; fi + - docker run --privileged -i -t + -v `pwd`:/odp --shm-size 8g + -e CC="${CC}" + -e CONF="" + -e ODP_CONFIG_FILE=/odp/platform/linux-generic/test/inline-timer.conf + ${DOCKER_NAMESPACE}/travis-odp-lng-ubuntu_16.04 /odp/scripts/ci/check_inline_timer.sh - stage: test env: TEST=distcheck compiler: gcc diff --git a/platform/linux-generic/test/inline-timer.conf b/platform/linux-generic/test/inline-timer.conf new file mode 100644 index 00000000..cc9f2037 --- /dev/null +++ b/platform/linux-generic/test/inline-timer.conf @@ -0,0 +1,8 @@ +# Mandatory fields +odp_implementation = "linux-generic" +config_file_version = "0.1.5" + +timer: { + # Enable inline timer implementation + inline = 1 +} diff --git a/scripts/ci/check_inline_timer.sh b/scripts/ci/check_inline_timer.sh new file mode 100755 index 00000000..d2eff714 --- /dev/null +++ b/scripts/ci/check_inline_timer.sh @@ -0,0 +1,16 @@ +#!/bin/bash +set -e + +"`dirname "$0"`"/build_x86_64.sh + +cd "$(dirname "$0")"/../.. + +echo 1000 | tee /proc/sys/vm/nr_hugepages +mkdir -p /mnt/huge +mount -t hugetlbfs nodev /mnt/huge + +ODP_SCHEDULER=basic ./test/validation/api/timer/timer_main +ODP_SCHEDULER=sp ./test/validation/api/timer/timer_main +ODP_SCHEDULER=scalable ./test/validation/api/timer/timer_main + +umount /mnt/huge
commit efb3dc0e6524b32442dc50f5ced9ce1f1d6fd948 Author: Matias Elo matias.elo@nokia.com Date: Tue Nov 13 13:01:26 2018 +0200
linux-gen: timer: enable inline timer implementation using config file
Add configure option 'timer.inline' for enabling inline timer implementation.
Signed-off-by: Matias Elo matias.elo@nokia.com Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/config/odp-linux-generic.conf b/config/odp-linux-generic.conf index 2be1fee7..2ac6c44d 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.4" +config_file_version = "0.1.5"
# Shared memory options shm: { @@ -125,3 +125,15 @@ sched_basic: { control = 1 } } + +timer: { + # Use inline timer implementation + # + # By default, timer processing is done in background threads (thread per + # timer pool). With inline implementation timers are processed on worker + # cores instead. When using inline timers the application has to call + # odp_schedule() or odp_queue_deq() to actuate timer processing. + # + # Set to 1 to enable + inline = 0 +} diff --git a/platform/linux-generic/odp_timer.c b/platform/linux-generic/odp_timer.c index 49901ae0..35bb0482 100644 --- a/platform/linux-generic/odp_timer.c +++ b/platform/linux-generic/odp_timer.c @@ -55,6 +55,7 @@ #include <odp/api/time.h> #include <odp/api/plat/time_inlines.h> #include <odp/api/timer.h> +#include <odp_libconfig_internal.h> #include <odp_queue_if.h> #include <odp_timer_internal.h> #include <odp/api/plat/queue_inlines.h> @@ -217,7 +218,7 @@ typedef struct timer_global_t { /* Multiple locks per cache line! */ _odp_atomic_flag_t ODP_ALIGNED_CACHE locks[NUM_LOCKS]; #endif - + odp_bool_t use_inline_timers; } timer_global_t;
static timer_global_t *timer_global; @@ -351,22 +352,8 @@ static odp_timer_pool_t timer_pool_new(const char *name, odp_ticketlock_lock(&timer_global->lock); timer_global->timer_pool[tp_idx] = tp;
- if (timer_global->num_timer_pools == 1) { - odp_bool_t inline_tim; - - /* - * Whether to run timer pool processing 'inline' (on worker - * cores) or in background threads (thread-per-timerpool). - * - * If the application will use scheduler this flag is set to - * true, otherwise false. This application conveys this - * information via the 'not_used' bits in odp_init_t which are - * passed to odp_global_init(). - */ - inline_tim = !odp_global_ro.init_param.not_used.feat.schedule; - - odp_global_rw->inline_timers = inline_tim; - } + if (timer_global->num_timer_pools == 1) + odp_global_rw->inline_timers = timer_global->use_inline_timers;
odp_ticketlock_unlock(&timer_global->lock); if (!odp_global_rw->inline_timers) { @@ -1360,7 +1347,8 @@ void odp_timeout_free(odp_timeout_t tmo) int odp_timer_init_global(const odp_init_t *params) { odp_shm_t shm; - odp_bool_t inline_timers = false; + const char *conf_str; + int val = 0;
shm = odp_shm_reserve("_odp_timer", sizeof(timer_global_t), ODP_CACHE_LINE_SIZE, 0); @@ -1385,16 +1373,21 @@ int odp_timer_init_global(const odp_init_t *params) #else ODP_DBG("Using lock-less timer implementation\n"); #endif + conf_str = "timer.inline"; + if (!_odp_libconfig_lookup_int(conf_str, &val)) { + ODP_ERR("Config option '%s' not found.\n", conf_str); + odp_shm_free(shm); + return -1; + } + timer_global->use_inline_timers = val;
- if (params) - inline_timers = - !params->not_used.feat.schedule && - !params->not_used.feat.timer; + if (params && params->not_used.feat.timer) + timer_global->use_inline_timers = false;
timer_global->time_per_ratelimit_period = odp_time_global_from_ns(timer_global->min_res_ns / 2);
- if (!inline_timers) { + if (!timer_global->use_inline_timers) { timer_res_init(); block_sigalarm(); } diff --git a/platform/linux-generic/test/process-mode.conf b/platform/linux-generic/test/process-mode.conf index fffddcc5..a5ad3f96 100644 --- a/platform/linux-generic/test/process-mode.conf +++ b/platform/linux-generic/test/process-mode.conf @@ -1,6 +1,6 @@ # Mandatory fields odp_implementation = "linux-generic" -config_file_version = "0.1.4" +config_file_version = "0.1.5"
# Shared memory options shm: {
commit 02b60f6739a3980cab9cd1afca5dcc1fedd84a1e Author: Matias Elo matias.elo@nokia.com Date: Thu Nov 15 17:18:22 2018 +0200
linux-gen: timer: zero timer pool memory on reserve
Fixes timer thread failing due to uninitialized variables.
Signed-off-by: Matias Elo matias.elo@nokia.com Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/platform/linux-generic/odp_timer.c b/platform/linux-generic/odp_timer.c index 1e1eb019..49901ae0 100644 --- a/platform/linux-generic/odp_timer.c +++ b/platform/linux-generic/odp_timer.c @@ -270,6 +270,7 @@ static odp_timer_pool_t timer_pool_new(const char *name, { uint32_t i, tp_idx; size_t sz0, sz1, sz2; + uint64_t tp_size; uint32_t flags = ODP_SHM_SW_ONLY;
if (odp_global_ro.shm_single_va) @@ -299,12 +300,17 @@ static odp_timer_pool_t timer_pool_new(const char *name, sz1 = ROUNDUP_CACHE_LINE(sizeof(tick_buf_t) * param->num_timers); sz2 = ROUNDUP_CACHE_LINE(sizeof(_odp_timer_t) * param->num_timers); - odp_shm_t shm = odp_shm_reserve(name, sz0 + sz1 + sz2, - ODP_CACHE_LINE_SIZE, flags); + tp_size = sz0 + sz1 + sz2; + + odp_shm_t shm = odp_shm_reserve(name, tp_size, ODP_CACHE_LINE_SIZE, + flags); if (odp_unlikely(shm == ODP_SHM_INVALID)) ODP_ABORT("%s: timer pool shm-alloc(%zuKB) failed\n", name, (sz0 + sz1 + sz2) / 1024); timer_pool_t *tp = (timer_pool_t *)odp_shm_addr(shm); + + memset(tp, 0, tp_size); + tp->prev_scan = odp_time_global(); tp->time_per_tick = odp_time_global_from_ns(param->res_ns); odp_atomic_init_u64(&tp->cur_tick, 0);
commit 406dc695c3fc756bac6ecef3c7d67348699e7a25 Author: Matias Elo matias.elo@nokia.com Date: Fri Nov 16 10:18:09 2018 +0200
linux-gen: init: always initialize odp_global_ro.init_param
Signed-off-by: Matias Elo matias.elo@nokia.com Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/platform/linux-generic/odp_init.c b/platform/linux-generic/odp_init.c index 98b46fca..9e648075 100644 --- a/platform/linux-generic/odp_init.c +++ b/platform/linux-generic/odp_init.c @@ -267,6 +267,7 @@ int odp_init_global(odp_instance_t *instance, odp_global_ro.log_fn = odp_override_log; odp_global_ro.abort_fn = odp_override_abort;
+ odp_init_param_init(&odp_global_ro.init_param); if (params != NULL) { odp_global_ro.init_param = *params;
commit 1bb388931c9101f38703142fda4f6b9e0bff52c4 Author: Petri Savolainen petri.savolainen@linaro.org Date: Wed Nov 14 09:53:54 2018 +0200
linux-gen: build: enable CPU arch specific optimization
When not building in ABI compatible mode, enable compiler optimizations for the CPU architecture of the local machine.
Signed-off-by: Petri Savolainen petri.savolainen@linaro.org Reviewed-by: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/configure.ac b/configure.ac index 68da20df..6715a7ef 100644 --- a/configure.ac +++ b/configure.ac @@ -200,6 +200,7 @@ AC_ARG_ENABLE([abi-compat], abi_compat=no #if there is no ABI compatibility the .so numbers are meaningless ODP_LIBSO_VERSION=0:0:0 + ODP_CHECK_CFLAG([-march=native]) fi]) AM_CONDITIONAL(ODP_ABI_COMPAT, [test "x$ODP_ABI_COMPAT" = "x1"])
commit 6fd24dd1f81b2ca5442d19bd66ffd902de651934 Author: Petri Savolainen petri.savolainen@linaro.org Date: Wed Nov 14 14:39:21 2018 +0200
linux-gen: arm atomic: fix register numbering with casp
ARMv8.1 specific casp() function failed to build due to register numbering issues. CASP instructions require that the first register of a pair is even. Force register numbering to start from even numbers (x0 and x2).
Signed-off-by: Petri Savolainen petri.savolainen@linaro.org Reviewed-by: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/platform/linux-generic/arch/aarch64/odp_atomic.h b/platform/linux-generic/arch/aarch64/odp_atomic.h index 8b6c3aec..8a0e7ce2 100644 --- a/platform/linux-generic/arch/aarch64/odp_atomic.h +++ b/platform/linux-generic/arch/aarch64/odp_atomic.h @@ -108,32 +108,45 @@ static inline __int128 __lockfree_fetch_or_16(__int128 *var, __int128 mask,
#else
-static inline __int128 casp(__int128 *var, __int128 old, __int128 neu, int mo) +static inline __int128_t cas_u128(__int128_t *ptr, __int128_t old_val, + __int128_t new_val, int mo) { + /* CASP instructions require that the first register number is paired */ + register uint64_t old0 __asm__ ("x0"); + register uint64_t old1 __asm__ ("x1"); + register uint64_t new0 __asm__ ("x2"); + register uint64_t new1 __asm__ ("x3"); + + old0 = (uint64_t)old_val; + old1 = (uint64_t)(old_val >> 64); + new0 = (uint64_t)new_val; + new1 = (uint64_t)(new_val >> 64); + if (mo == __ATOMIC_RELAXED) { - __asm__ volatile("casp %0, %H0, %1, %H1, [%2]" - : "+r" (old) - : "r" (neu), "r" (var) + __asm__ volatile("casp %[old0], %[old1], %[new0], %[new1], [%[ptr]]" + : [old0] "+r" (old0), [old1] "+r" (old1) + : [new0] "r" (new0), [new1] "r" (new1), [ptr] "r" (ptr) : "memory"); } else if (mo == __ATOMIC_ACQUIRE) { - __asm__ volatile("caspa %0, %H0, %1, %H1, [%2]" - : "+r" (old) - : "r" (neu), "r" (var) + __asm__ volatile("caspa %[old0], %[old1], %[new0], %[new1], [%[ptr]]" + : [old0] "+r" (old0), [old1] "+r" (old1) + : [new0] "r" (new0), [new1] "r" (new1), [ptr] "r" (ptr) : "memory"); } else if (mo == __ATOMIC_ACQ_REL) { - __asm__ volatile("caspal %0, %H0, %1, %H1, [%2]" - : "+r" (old) - : "r" (neu), "r" (var) + __asm__ volatile("caspal %[old0], %[old1], %[new0], %[new1], [%[ptr]]" + : [old0] "+r" (old0), [old1] "+r" (old1) + : [new0] "r" (new0), [new1] "r" (new1), [ptr] "r" (ptr) : "memory"); } else if (mo == __ATOMIC_RELEASE) { - __asm__ volatile("caspl %0, %H0, %1, %H1, [%2]" - : "+r" (old) - : "r" (neu), "r" (var) + __asm__ volatile("caspl %[old0], %[old1], %[new0], %[new1], [%[ptr]]" + : [old0] "+r" (old0), [old1] "+r" (old1) + : [new0] "r" (new0), [new1] "r" (new1), [ptr] "r" (ptr) : "memory"); } else { abort(); } - return old; + + return ((__int128)old0) | (((__int128)old1) << 64); }
static inline bool @@ -147,7 +160,7 @@ __lockfree_compare_exchange_16(register __int128 *var, __int128 *exp, __int128 expected;
expected = *exp; - old = casp(var, expected, neu, mo_success); + old = cas_u128(var, expected, neu, mo_success); *exp = old; /* Always update, atomically read value */ return old == expected; } @@ -160,7 +173,7 @@ static inline __int128 __lockfree_exchange_16(__int128 *var, __int128 neu,
do { expected = *var; - old = casp(var, expected, neu, mo); + old = cas_u128(var, expected, neu, mo); } while (old != expected); return old; } @@ -173,7 +186,7 @@ static inline __int128 __lockfree_fetch_and_16(__int128 *var, __int128 mask,
do { expected = *var; - old = casp(var, expected, expected & mask, mo); + old = cas_u128(var, expected, expected & mask, mo); } while (old != expected); return old; } @@ -186,7 +199,7 @@ static inline __int128 __lockfree_fetch_or_16(__int128 *var, __int128 mask,
do { expected = *var; - old = casp(var, expected, expected | mask, mo); + old = cas_u128(var, expected, expected | mask, mo); } while (old != expected); return old; }
commit 833470a13c2068890bfacdbf99bacce55bed2db2 Author: Petri Savolainen petri.savolainen@linaro.org Date: Tue Nov 13 16:44:07 2018 +0200
linux-gen: sysinfo: print out ARM build time features
Print out feature flags that were used in build time. The output may be used to check e.g. if binary was built with ARMv8.0 or >= ARMv8.1 instructions.
Signed-off-by: Petri Savolainen petri.savolainen@linaro.org Reviewed-by: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@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 bcdc2373..3a1486dd 100644 --- a/platform/linux-generic/arch/aarch64/odp_sysinfo_parse.c +++ b/platform/linux-generic/arch/aarch64/odp_sysinfo_parse.c @@ -201,6 +201,76 @@ int cpuinfo_parser(FILE *file, system_info_t *sysinfo)
void sys_info_print_arch(void) { + const char *ndef = "n/a"; + + /* Avoid compiler warning about unused variable */ + (void)ndef; + + /* See ARM C Language Extensions documentation for details */ + printf("ARM FEATURES:\n"); + + printf(" __ARM_ARCH "); +#ifdef __ARM_ARCH + printf("%i\n", __ARM_ARCH); +#else + printf("%s\n", ndef); +#endif + + printf(" __ARM_ARCH_ISA_A64 "); +#ifdef __ARM_ARCH_ISA_A64 + printf("%i\n", __ARM_ARCH_ISA_A64); +#else + printf("%s\n", ndef); +#endif + +#if defined(__ARM_ARCH) && __ARM_ARCH >= 8 + /* Actually, this checks for new NEON instructions in + * v8.1, but is currently the only way to distinguish + * v8.0 and >=v8.1. */ + printf(" ARMv8 ISA version "); +#ifdef __ARM_FEATURE_QRDMX + printf("v8.1 or higher\n"); +#else + printf("v8.0\n"); +#endif +#endif + +#ifdef __ARM_FEATURE_QRDMX + /* Actually, this checks for new NEON instructions in + * v8.1, but is currently the only way to distinguish + * v8.0 and >=v8.1. */ + printf(" ARMv8.1 instructions\n"); +#endif + + printf(" __ARM_NEON "); +#ifdef __ARM_NEON + printf("%i\n", __ARM_NEON); +#else + printf("%s\n", ndef); +#endif + + printf(" __ARM_FEATURE_IDIV "); +#ifdef __ARM_FEATURE_IDIV + printf("%i\n", __ARM_FEATURE_IDIV); +#else + printf("%s\n", ndef); +#endif + + printf(" __ARM_FEATURE_CRYPTO "); +#ifdef __ARM_FEATURE_CRYPTO + printf("%i\n", __ARM_FEATURE_CRYPTO); +#else + printf("%s\n", ndef); +#endif + + printf(" __ARM_FEATURE_CRC32 "); +#ifdef __ARM_FEATURE_CRC32 + printf("%i\n", __ARM_FEATURE_CRC32); +#else + printf("%s\n", ndef); +#endif + + printf("\n"); }
uint64_t odp_cpu_arch_hz_current(int id)
commit 374301a2aa5ba6dfa81aa4c70fd24ed59141c012 Author: Maxim Uvarov maxim.uvarov@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@linaro.org Dmitry Eremin-Solenikov dmitry.ereminsolenikov@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 f913948f5daa4cb1f71467d872b5380974b04f2d Author: Matias Elo matias.elo@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@nokia.com Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/.travis.yml b/.travis.yml index 5d958cb4..ec307645 100644 --- a/.travis.yml +++ b/.travis.yml @@ -215,7 +215,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" @@ -224,7 +224,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" @@ -233,7 +233,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" @@ -242,7 +242,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 816f5fb0..eea527db 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); @@ -457,7 +452,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; }
@@ -579,31 +575,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) && @@ -619,11 +668,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);
@@ -643,38 +689,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 */ @@ -687,8 +716,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) @@ -696,20 +726,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];
@@ -719,33 +747,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; @@ -757,37 +768,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;
@@ -795,8 +856,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, @@ -876,7 +937,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); @@ -912,6 +975,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, @@ -919,9 +984,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 @@ -966,7 +1029,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*/ @@ -976,7 +1040,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); @@ -1011,24 +1074,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"); @@ -1054,28 +1113,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) { @@ -1103,18 +1164,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); @@ -1151,6 +1221,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. @@ -1166,6 +1295,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; @@ -1210,6 +1340,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: */ @@ -1220,16 +1353,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; @@ -1307,7 +1446,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; @@ -1490,12 +1634,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;
@@ -1542,11 +1685,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); @@ -1574,14 +1715,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: */ @@ -1621,8 +1764,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."); @@ -1720,6 +1863,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) || @@ -1741,6 +1885,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; @@ -1752,9 +1899,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 f703d49c196a6c6c9d29d3c7b04c02d727795a2c Author: Matias Elo matias.elo@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@nokia.com Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/config/odp-linux-generic.conf b/config/odp-linux-generic.conf index bca123bc..2be1fee7 100644 --- a/config/odp-linux-generic.conf +++ b/config/odp-linux-generic.conf @@ -33,6 +33,9 @@ shm: { # When using process mode threads, this value should be set to 0 # because the current implementation won't work properly otherwise. num_cached_hp = 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 ae6426ef..b6c4329a 100644 --- a/platform/linux-generic/include/odp_config_internal.h +++ b/platform/linux-generic/include/odp_config_internal.h @@ -133,16 +133,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 78f1b183..816f5fb0 100644 --- a/platform/linux-generic/odp_ishm.c +++ b/platform/linux-generic/odp_ishm.c @@ -1492,11 +1492,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 4bda6933..fffddcc5 100644 --- a/platform/linux-generic/test/process-mode.conf +++ b/platform/linux-generic/test/process-mode.conf @@ -4,4 +4,6 @@ config_file_version = "0.1.4"
# Shared memory options shm: { + # Increase the amount of single VA memory + single_va_size_kb = 1048576 }
commit 5eb5837adf64b14e795483a6cdf4e83124c56be8 Author: Matias Elo matias.elo@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@nokia.com Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@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 4964f08fa748eb61949fff147e930be72555d233 Author: Matias Elo matias.elo@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@nokia.com Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@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 263a5bb884c3e274174b1d1e4e0ae497143b1f81 Author: Matias Elo matias.elo@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@nokia.com Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/platform/linux-generic/odp_ishm.c b/platform/linux-generic/odp_ishm.c index f73aea37..78f1b183 100644 --- a/platform/linux-generic/odp_ishm.c +++ b/platform/linux-generic/odp_ishm.c @@ -1328,9 +1328,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) { @@ -1341,42 +1340,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 3e007fea33316e1d7d66cd7ea19541a1653b501c Author: Matias Elo matias.elo@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@nokia.com Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/platform/linux-generic/odp_queue_scalable.c b/platform/linux-generic/odp_queue_scalable.c index 4f5d8b21..2de4d52d 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 f8eda649cd915654175c9723aca75adaae88c3d3 Author: Matias Elo matias.elo@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@nokia.com Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@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 d89f0930..f73aea37 100644 --- a/platform/linux-generic/odp_ishm.c +++ b/platform/linux-generic/odp_ishm.c @@ -839,56 +839,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 @@ -1320,59 +1270,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. @@ -1429,24 +1326,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). @@ -1471,32 +1350,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 96a177a6322a9d8fad99d43271d1b98ecd5d12a5 Author: Matias Elo matias.elo@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@nokia.com Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@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 1fa0ce4f..4f5d8b21 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 83a2a41b..5d83ed08 100644 --- a/platform/linux-generic/odp_schedule_scalable.c +++ b/platform/linux-generic/odp_schedule_scalable.c @@ -1790,6 +1790,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; @@ -1808,34 +1809,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);
commit 3529f3b8713021e45c7dbdd81f839d8b9049efcc Author: Petri Savolainen petri.savolainen@linaro.org Date: Fri Nov 9 15:05:56 2018 +0200
linux-gen: cls: simplify shm usage
Combine three shm reservations into one reservation. This simplifies shm usage and results less ODP internally allocated SHM blocks. Also one combined block is more memory efficient than multiple (saves memory and page mappings).
Signed-off-by: Petri Savolainen petri.savolainen@linaro.org Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/platform/linux-generic/odp_classification.c b/platform/linux-generic/odp_classification.c index fd20e3e0..e6d75cb6 100644 --- a/platform/linux-generic/odp_classification.c +++ b/platform/linux-generic/odp_classification.c @@ -35,6 +35,16 @@ static cos_tbl_t *cos_tbl; static pmr_tbl_t *pmr_tbl; static _cls_queue_grp_tbl_t *queue_grp_tbl;
+typedef struct cls_global_t { + cos_tbl_t cos_tbl; + pmr_tbl_t pmr_tbl; + _cls_queue_grp_tbl_t queue_grp_tbl; + odp_shm_t shm; + +} cls_global_t; + +static cls_global_t *cls_global; + static const rss_key default_rss = { .u8 = { 0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2, @@ -79,102 +89,45 @@ pmr_t *get_pmr_entry_internal(odp_pmr_t pmr)
int odp_classification_init_global(void) { - odp_shm_t cos_shm; - odp_shm_t pmr_shm; - odp_shm_t queue_grp_shm; + odp_shm_t shm; int i;
- cos_shm = odp_shm_reserve("_odp_shm_odp_cos_tbl", - sizeof(cos_tbl_t), - sizeof(cos_t), - 0); + shm = odp_shm_reserve("_odp_cls_global", sizeof(cls_global_t), + ODP_CACHE_LINE_SIZE, 0); + if (shm == ODP_SHM_INVALID) + return -1;
- if (cos_shm == ODP_SHM_INVALID) { - ODP_ERR("shm allocation failed for shm_odp_cos_tbl"); - goto error; - } + cls_global = odp_shm_addr(shm); + memset(cls_global, 0, sizeof(cls_global_t));
- cos_tbl = odp_shm_addr(cos_shm); - if (cos_tbl == NULL) - goto error_cos; + cls_global->shm = shm; + cos_tbl = &cls_global->cos_tbl; + pmr_tbl = &cls_global->pmr_tbl; + queue_grp_tbl = &cls_global->queue_grp_tbl;
- memset(cos_tbl, 0, sizeof(cos_tbl_t)); for (i = 0; i < CLS_COS_MAX_ENTRY; i++) { /* init locks */ cos_t *cos = get_cos_entry_internal(_odp_cos_from_ndx(i)); LOCK_INIT(&cos->s.lock); }
- pmr_shm = odp_shm_reserve("_odp_shm_odp_pmr_tbl", - sizeof(pmr_tbl_t), - sizeof(pmr_t), - 0); - - if (pmr_shm == ODP_SHM_INVALID) { - ODP_ERR("shm allocation failed for shm_odp_pmr_tbl"); - goto error_cos; - } - - pmr_tbl = odp_shm_addr(pmr_shm); - if (pmr_tbl == NULL) - goto error_pmr; - - memset(pmr_tbl, 0, sizeof(pmr_tbl_t)); for (i = 0; i < CLS_PMR_MAX_ENTRY; i++) { /* init locks */ pmr_t *pmr = get_pmr_entry_internal(_odp_pmr_from_ndx(i)); LOCK_INIT(&pmr->s.lock); }
- queue_grp_shm = odp_shm_reserve("_odp_shm_cls_queue_grp_tbl", - sizeof(_cls_queue_grp_tbl_t), - sizeof(queue_entry_t *), - 0); - - if (queue_grp_shm == ODP_SHM_INVALID) { - ODP_ERR("shm allocation failed for queue_grp_tbl"); - goto error_queue_grp; - } - - queue_grp_tbl = odp_shm_addr(queue_grp_shm); - memset(queue_grp_tbl, 0, sizeof(_cls_queue_grp_tbl_t)); - return 0; - -error_queue_grp: - odp_shm_free(queue_grp_shm); -error_pmr: - odp_shm_free(pmr_shm); -error_cos: - odp_shm_free(cos_shm); -error: - return -1; }
int odp_classification_term_global(void) { - int ret = 0; - int rc = 0; - - ret = odp_shm_free(odp_shm_lookup("_odp_shm_odp_cos_tbl")); - if (ret < 0) { - ODP_ERR("shm free failed for shm_odp_cos_tbl"); - rc = -1; - } - - ret = odp_shm_free(odp_shm_lookup("_odp_shm_odp_pmr_tbl")); - if (ret < 0) { - ODP_ERR("shm free failed for shm_odp_pmr_tbl"); - rc = -1; - } - - ret = odp_shm_free(odp_shm_lookup("_odp_shm_cls_queue_grp_tbl")); - if (ret < 0) { - ODP_ERR("shm free failed for shm_odp_cls_queue_grp_tbl"); - rc = -1; + if (cls_global && odp_shm_free(cls_global->shm)) { + ODP_ERR("shm free failed"); + return -1; }
- return rc; + return 0; }
void odp_cls_cos_param_init(odp_cls_cos_param_t *param)
commit af055783f975e2b8b9e443565b3abdc9f7946ade Author: Petri Savolainen petri.savolainen@linaro.org Date: Fri Nov 9 14:35:53 2018 +0200
linux-gen: shm: modify shm print header string
Highlight that printed values are from ODP SHM only, i.e. it's not generic memory allocation status of the entire system.
Signed-off-by: Petri Savolainen petri.savolainen@linaro.org Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/platform/linux-generic/odp_shared_memory.c b/platform/linux-generic/odp_shared_memory.c index d2f31458..4e92c9f2 100644 --- a/platform/linux-generic/odp_shared_memory.c +++ b/platform/linux-generic/odp_shared_memory.c @@ -122,7 +122,7 @@ int odp_shm_info(odp_shm_t shm, odp_shm_info_t *info)
void odp_shm_print_all(void) { - _odp_ishm_status("Memory allocation status:"); + _odp_ishm_status("ODP shared memory allocation status:"); }
void odp_shm_print(odp_shm_t shm)
commit 8d9936c45c4a9f8db9142057d8acee41d54e0b51 Author: Petri Savolainen petri.savolainen@linaro.org Date: Fri Nov 9 14:31:14 2018 +0200
example: sysinfo: print shm blocks
It's useful to see how many shm blocks and which kind of memory (huge or normal pages, etc) ODP implementation itself allocates.
Signed-off-by: Petri Savolainen petri.savolainen@linaro.org Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/example/sysinfo/odp_sysinfo.c b/example/sysinfo/odp_sysinfo.c index 9f55872b..709f25d9 100644 --- a/example/sysinfo/odp_sysinfo.c +++ b/example/sysinfo/odp_sysinfo.c @@ -432,6 +432,10 @@ int main(void) print_auth_algos(crypto_capa.auths); printf("\n"); print_auth_caps(crypto_capa.auths); + printf("\n"); + + printf(" SHM MEMORY BLOCKS:\n"); + odp_shm_print_all();
printf("\n"); printf("***********************************************************\n");
commit 2a6485f25dc9b0612cccf40a2360dc6d40becb78 Author: Matias Elo matias.elo@nokia.com Date: Fri Nov 9 12:17:28 2018 +0200
linux-gen: ishm: allocate small shm blocks using normal pages
Only memory reservations larger than ISHM_HUGE_PAGE_LIMIT (64kB) are allocated using huge pages (if available). Smaller reservations are done using normal pages to conserve memory.
Signed-off-by: Matias Elo matias.elo@nokia.com Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/platform/linux-generic/odp_ishm.c b/platform/linux-generic/odp_ishm.c index 57b2d417..d89f0930 100644 --- a/platform/linux-generic/odp_ishm.c +++ b/platform/linux-generic/odp_ishm.c @@ -125,6 +125,13 @@ */ #define ISHM_NB_FRAGMNTS (ISHM_MAX_NB_BLOCKS * 2 + 1)
+/* + * Memory reservations larger than ISHM_HUGE_PAGE_LIMIT (bytes) are allocated + * using huge pages (if available). Smaller reservations are done using normal + * pages to conserve memory. + */ +#define ISHM_HUGE_PAGE_LIMIT (64 * 1024) + /* * when a memory block is to be exported outside its ODP instance, * an block 'attribute file' is created in /dev/shm/odp-<pid>-shm-<name>. @@ -1085,7 +1092,7 @@ int _odp_ishm_reserve(const char *name, uint64_t size, int fd,
/* Otherwise, Try first huge pages when possible and needed: */ if ((fd < 0) && page_hp_size && ((flags & _ODP_ISHM_USE_HP) || - size > page_sz)) { + size > ISHM_HUGE_PAGE_LIMIT)) { /* at least, alignment in VA should match page size, but user * can request more: If the user requirement exceeds the page * size then we have to make sure the block will be mapped at
commit 91fee166b0dbf4949f1a1786e167a6948b1e8f52 Author: Matias Elo matias.elo@nokia.com Date: Mon Nov 12 14:51:28 2018 +0200
linux-gen: ishm: add internal _ODP_ISHM_USE_HP flag
Add internal shm flag for allocating shm memory always from huge pages. This is required by zero-copy dpdk packet pool. Internal _odp_shm_reserve() function is added for passing extra shm flags.
Signed-off-by: Matias Elo matias.elo@nokia.com Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/platform/linux-generic/include/odp_shm_internal.h b/platform/linux-generic/include/odp_shm_internal.h index 93146a51..a1bd2439 100644 --- a/platform/linux-generic/include/odp_shm_internal.h +++ b/platform/linux-generic/include/odp_shm_internal.h @@ -14,10 +14,13 @@ extern "C" { #include <sys/types.h> #include <inttypes.h>
+#include <odp/api/shared_memory.h> + /* flags available at ishm_reserve: */ #define _ODP_ISHM_SINGLE_VA 1 #define _ODP_ISHM_LOCK 2 -#define _ODP_ISHM_EXPORT 4 /*create export descr file in /tmp */ +#define _ODP_ISHM_EXPORT 4 /* create export descr file in /tmp */ +#define _ODP_ISHM_USE_HP 8 /* allocate memory from huge pages */
/** * Shared memory block info @@ -31,6 +34,9 @@ typedef struct _odp_ishm_info_t { uint32_t user_flags;/**< user specific flags */ } _odp_ishm_info_t;
+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); int _odp_ishm_free_by_index(int block_index); diff --git a/platform/linux-generic/odp_ishm.c b/platform/linux-generic/odp_ishm.c index 669377a0..57b2d417 100644 --- a/platform/linux-generic/odp_ishm.c +++ b/platform/linux-generic/odp_ishm.c @@ -1016,7 +1016,7 @@ int _odp_ishm_reserve(const char *name, uint64_t size, int fd, uint64_t page_sz; /* normal page size. usually 4K*/ uint64_t page_hp_size; /* huge page size */ uint32_t hp_align; - uint64_t len; /* mapped length */ + uint64_t len = 0; /* mapped length */ void *addr = NULL; /* mapping address */ int new_proc_entry; struct stat statbuf; @@ -1084,7 +1084,8 @@ int _odp_ishm_reserve(const char *name, uint64_t size, int fd, }
/* Otherwise, Try first huge pages when possible and needed: */ - if ((fd < 0) && page_hp_size && (size > page_sz)) { + if ((fd < 0) && page_hp_size && ((flags & _ODP_ISHM_USE_HP) || + size > page_sz)) { /* at least, alignment in VA should match page size, but user * can request more: If the user requirement exceeds the page * size then we have to make sure the block will be mapped at diff --git a/platform/linux-generic/odp_pool.c b/platform/linux-generic/odp_pool.c index 10382c4c..2262f355 100644 --- a/platform/linux-generic/odp_pool.c +++ b/platform/linux-generic/odp_pool.c @@ -22,6 +22,7 @@ #include <odp_ring_internal.h> #include <odp_global_data.h> #include <odp_libconfig_internal.h> +#include <odp_shm_internal.h>
#include <string.h> #include <stdio.h> @@ -378,6 +379,7 @@ static odp_pool_t pool_create(const char *name, odp_pool_param_t *params, uint32_t max_len; uint32_t ring_size; uint32_t num_extra = 0; + uint32_t extra_shm_flags = 0; int name_len; const char *postfix = "_uarea"; char uarea_name[ODP_POOL_NAME_LEN + sizeof(postfix)]; @@ -487,11 +489,16 @@ static odp_pool_t pool_create(const char *name, odp_pool_param_t *params, * headers. NOP if zero-copy is disabled. */ pool->block_offset = 0; if (params->type == ODP_POOL_PACKET) { - block_size = _odp_dpdk_pool_obj_size(pool, block_size); - if (!block_size) { + uint32_t dpdk_obj_size; + + dpdk_obj_size = _odp_dpdk_pool_obj_size(pool, block_size); + if (!dpdk_obj_size) { ODP_ERR("Calculating DPDK mempool obj size failed\n"); return ODP_POOL_INVALID; } + if (dpdk_obj_size != block_size) + extra_shm_flags |= _ODP_ISHM_USE_HP; + block_size = dpdk_obj_size; }
/* Allocate extra memory for skipping packet buffers which cross huge @@ -524,8 +531,8 @@ static odp_pool_t pool_create(const char *name, odp_pool_param_t *params, pool->ext_desc = NULL; pool->ext_destroy = NULL;
- shm = odp_shm_reserve(pool->name, pool->shm_size, - ODP_PAGE_SIZE, shmflags); + shm = _odp_shm_reserve(pool->name, pool->shm_size, + ODP_PAGE_SIZE, shmflags, extra_shm_flags);
pool->shm = shm;
diff --git a/platform/linux-generic/odp_shared_memory.c b/platform/linux-generic/odp_shared_memory.c index 7d405d13..d2f31458 100644 --- a/platform/linux-generic/odp_shared_memory.c +++ b/platform/linux-generic/odp_shared_memory.c @@ -44,6 +44,22 @@ static uint32_t get_ishm_flags(uint32_t flags) return f; }
+odp_shm_t _odp_shm_reserve(const char *name, uint64_t size, uint32_t align, + uint32_t flags, uint32_t extra_flags) +{ + int block_index; + uint32_t flgs = 0; /* internal ishm flags */ + + flgs = get_ishm_flags(flags); + flgs |= extra_flags; + + 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; +} + int odp_shm_capability(odp_shm_capability_t *capa) { memset(capa, 0, sizeof(odp_shm_capability_t)); @@ -58,16 +74,7 @@ int odp_shm_capability(odp_shm_capability_t *capa) odp_shm_t odp_shm_reserve(const char *name, uint64_t size, uint64_t align, uint32_t flags) { - int block_index; - uint32_t flgs = 0; /* internal ishm flags */ - - flgs = get_ishm_flags(flags); - - 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; + return _odp_shm_reserve(name, size, align, flags, 0); }
odp_shm_t odp_shm_import(const char *remote_name,
commit 01e4772d22537772001714318d5f501f082b6c5e Author: Matias Elo matias.elo@nokia.com Date: Mon Nov 12 13:36:27 2018 +0200
linux-gen: ishm: remove unused odp_shm_internal header
odp_shm_internal.h contents were not used so delete the file and rename odp_ishm_internal.h to odp_shm_internal.h.
Signed-off-by: Matias Elo matias.elo@nokia.com Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am index b973bc30..f21fbf70 100644 --- a/platform/linux-generic/Makefile.am +++ b/platform/linux-generic/Makefile.am @@ -99,7 +99,6 @@ noinst_HEADERS = \ include/odp_global_data.h \ include/odp_init_internal.h \ include/odp_ipsec_internal.h \ - include/odp_ishm_internal.h \ include/odp_ishmphy_internal.h \ include/odp_ishmpool_internal.h \ include/odp_libconfig_internal.h \ diff --git a/platform/linux-generic/include/odp_ishm_internal.h b/platform/linux-generic/include/odp_ishm_internal.h deleted file mode 100644 index 56c7f5a9..00000000 --- a/platform/linux-generic/include/odp_ishm_internal.h +++ /dev/null @@ -1,54 +0,0 @@ -/* Copyright (c) 2016-2018, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef ODP_ISHM_INTERNAL_H_ -#define ODP_ISHM_INTERNAL_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include <sys/types.h> - -/* flags available at ishm_reserve: */ -#define _ODP_ISHM_SINGLE_VA 1 -#define _ODP_ISHM_LOCK 2 -#define _ODP_ISHM_EXPORT 4 /*create export descr file in /tmp */ - -/** - * Shared memory block info - */ -typedef struct _odp_ishm_info_t { - const char *name; /**< Block name */ - void *addr; /**< Block address */ - uint64_t size; /**< Block size in bytes */ - uint64_t page_size; /**< Memory page size */ - uint32_t flags; /**< _ODP_ISHM_* flags */ - uint32_t user_flags;/**< user specific flags */ -} _odp_ishm_info_t; - -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); -void *_odp_ishm_address(int block_index); -int _odp_ishm_info(int block_index, _odp_ishm_info_t *info); -int _odp_ishm_status(const char *title); -int _odp_ishm_cleanup_files(const char *dirpath); -void _odp_ishm_print(int block_index); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/platform/linux-generic/include/odp_shm_internal.h b/platform/linux-generic/include/odp_shm_internal.h index ab58973b..93146a51 100644 --- a/platform/linux-generic/include/odp_shm_internal.h +++ b/platform/linux-generic/include/odp_shm_internal.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2018, Linaro Limited +/* Copyright (c) 2016-2018, Linaro Limited * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -11,13 +11,42 @@ extern "C" { #endif
-#include <odp/api/shared_memory.h> +#include <sys/types.h> +#include <inttypes.h>
-#define SHM_DEVNAME_MAXLEN (ODP_SHM_NAME_LEN + 16) -#define SHM_DEVNAME_FORMAT "/odp-%d-%s" /* /dev/shm/odp-<pid>-<name> */ +/* flags available at ishm_reserve: */ +#define _ODP_ISHM_SINGLE_VA 1 +#define _ODP_ISHM_LOCK 2 +#define _ODP_ISHM_EXPORT 4 /*create export descr file in /tmp */
-#define _ODP_SHM_PROC_NOCREAT (1 << 6) /**< Do not create shm if not exist */ -#define _ODP_SHM_O_EXCL (1 << 7) /**< Do not create shm if exist */ +/** + * Shared memory block info + */ +typedef struct _odp_ishm_info_t { + const char *name; /**< Block name */ + void *addr; /**< Block address */ + uint64_t size; /**< Block size in bytes */ + uint64_t page_size; /**< Memory page size */ + uint32_t flags; /**< _ODP_ISHM_* flags */ + uint32_t user_flags;/**< user specific flags */ +} _odp_ishm_info_t; + +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); +void *_odp_ishm_address(int block_index); +int _odp_ishm_info(int block_index, _odp_ishm_info_t *info); +int _odp_ishm_status(const char *title); +int _odp_ishm_cleanup_files(const char *dirpath); +void _odp_ishm_print(int block_index);
#ifdef __cplusplus } diff --git a/platform/linux-generic/odp_ishm.c b/platform/linux-generic/odp_ishm.c index 07cd2ecb..669377a0 100644 --- a/platform/linux-generic/odp_ishm.c +++ b/platform/linux-generic/odp_ishm.c @@ -60,7 +60,7 @@ #include <odp_debug_internal.h> #include <odp_align_internal.h> #include <odp_fdserver_internal.h> -#include <odp_ishm_internal.h> +#include <odp_shm_internal.h> #include <odp_ishmphy_internal.h> #include <odp_ishmpool_internal.h> #include <odp_libconfig_internal.h> diff --git a/platform/linux-generic/odp_ishmphy.c b/platform/linux-generic/odp_ishmphy.c index 94a20f8f..556c8e14 100644 --- a/platform/linux-generic/odp_ishmphy.c +++ b/platform/linux-generic/odp_ishmphy.c @@ -17,7 +17,7 @@ #include <odp/api/debug.h> #include <odp_debug_internal.h> #include <odp_align_internal.h> -#include <odp_ishm_internal.h> +#include <odp_shm_internal.h> #include <odp_ishmphy_internal.h>
#include <stdlib.h> diff --git a/platform/linux-generic/odp_ishmpool.c b/platform/linux-generic/odp_ishmpool.c index 46865371..a3a1c059 100644 --- a/platform/linux-generic/odp_ishmpool.c +++ b/platform/linux-generic/odp_ishmpool.c @@ -50,7 +50,7 @@ #include <odp_shm_internal.h> #include <odp_debug_internal.h> #include <odp_align_internal.h> -#include <odp_ishm_internal.h> +#include <odp_shm_internal.h> #include <odp_ishmpool_internal.h> #include <stdlib.h> #include <stdio.h> diff --git a/platform/linux-generic/odp_queue_scalable.c b/platform/linux-generic/odp_queue_scalable.c index 8b89a227..1fa0ce4f 100644 --- a/platform/linux-generic/odp_queue_scalable.c +++ b/platform/linux-generic/odp_queue_scalable.c @@ -25,7 +25,7 @@ #include <odp_queue_scalable_internal.h> #include <odp_schedule_if.h> #include <odp_timer_internal.h> -#include <odp_ishm_internal.h> +#include <odp_shm_internal.h> #include <odp_ishmpool_internal.h> #include <odp/api/plat/queue_inline_types.h> #include <odp_global_data.h> diff --git a/platform/linux-generic/odp_schedule_scalable.c b/platform/linux-generic/odp_schedule_scalable.c index fc82b65b..83a2a41b 100644 --- a/platform/linux-generic/odp_schedule_scalable.c +++ b/platform/linux-generic/odp_schedule_scalable.c @@ -22,7 +22,7 @@
#include <odp_config_internal.h> #include <odp_debug_internal.h> -#include <odp_ishm_internal.h> +#include <odp_shm_internal.h> #include <odp_ishmpool_internal.h>
#include <odp_align_internal.h> diff --git a/platform/linux-generic/odp_shared_memory.c b/platform/linux-generic/odp_shared_memory.c index 9c9139bb..7d405d13 100644 --- a/platform/linux-generic/odp_shared_memory.c +++ b/platform/linux-generic/odp_shared_memory.c @@ -11,7 +11,7 @@ #include <odp/api/std_types.h> #include <odp/api/shared_memory.h> #include <odp/api/plat/strong_types.h> -#include <odp_ishm_internal.h> +#include <odp_shm_internal.h> #include <odp_init_internal.h> #include <odp_global_data.h> #include <string.h> diff --git a/platform/linux-generic/pktio/ipc.c b/platform/linux-generic/pktio/ipc.c index fc565443..cd438ad3 100644 --- a/platform/linux-generic/pktio/ipc.c +++ b/platform/linux-generic/pktio/ipc.c @@ -11,7 +11,7 @@ #include <odp_packet_io_internal.h> #include <odp/api/system_info.h> #include <odp_shm_internal.h> -#include <odp_ishm_internal.h> +#include <odp_shm_internal.h>
#include <sys/mman.h> #include <sys/stat.h>
commit f8bbdfc98be5d86dea67cc34ee97a4b69c052d61 Author: Matias Elo matias.elo@nokia.com Date: Fri Nov 9 11:48:41 2018 +0200
linux-gen: ishm: remove _ODP_SHM_NO_HP flag
Reserving large shm blocks without huge pages increases page misses.
Signed-off-by: Matias Elo matias.elo@nokia.com Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/platform/linux-generic/include/odp_shm_internal.h b/platform/linux-generic/include/odp_shm_internal.h index 9827af75..ab58973b 100644 --- a/platform/linux-generic/include/odp_shm_internal.h +++ b/platform/linux-generic/include/odp_shm_internal.h @@ -18,7 +18,6 @@ extern "C" {
#define _ODP_SHM_PROC_NOCREAT (1 << 6) /**< Do not create shm if not exist */ #define _ODP_SHM_O_EXCL (1 << 7) /**< Do not create shm if exist */ -#define _ODP_SHM_NO_HP (1 << 8) /**< Do not use huge pages */
#ifdef __cplusplus } diff --git a/platform/linux-generic/odp_classification.c b/platform/linux-generic/odp_classification.c index 3310dc7f..fd20e3e0 100644 --- a/platform/linux-generic/odp_classification.c +++ b/platform/linux-generic/odp_classification.c @@ -11,7 +11,6 @@ #include <odp/api/queue.h> #include <odp/api/debug.h> #include <odp_init_internal.h> -#include <odp_shm_internal.h> #include <odp_debug_internal.h> #include <odp_packet_internal.h> #include <odp/api/packet_io.h> @@ -88,7 +87,7 @@ int odp_classification_init_global(void) cos_shm = odp_shm_reserve("_odp_shm_odp_cos_tbl", sizeof(cos_tbl_t), sizeof(cos_t), - _ODP_SHM_NO_HP); + 0);
if (cos_shm == ODP_SHM_INVALID) { ODP_ERR("shm allocation failed for shm_odp_cos_tbl"); @@ -109,7 +108,7 @@ int odp_classification_init_global(void) pmr_shm = odp_shm_reserve("_odp_shm_odp_pmr_tbl", sizeof(pmr_tbl_t), sizeof(pmr_t), - _ODP_SHM_NO_HP); + 0);
if (pmr_shm == ODP_SHM_INVALID) { ODP_ERR("shm allocation failed for shm_odp_pmr_tbl"); @@ -130,7 +129,7 @@ int odp_classification_init_global(void) queue_grp_shm = odp_shm_reserve("_odp_shm_cls_queue_grp_tbl", sizeof(_cls_queue_grp_tbl_t), sizeof(queue_entry_t *), - _ODP_SHM_NO_HP); + 0);
if (queue_grp_shm == ODP_SHM_INVALID) { ODP_ERR("shm allocation failed for queue_grp_tbl"); diff --git a/platform/linux-generic/odp_crypto_null.c b/platform/linux-generic/odp_crypto_null.c index 939b2fbb..4dd1f832 100644 --- a/platform/linux-generic/odp_crypto_null.c +++ b/platform/linux-generic/odp_crypto_null.c @@ -21,7 +21,6 @@ #include <odp/api/plat/thread_inlines.h> #include <odp_packet_internal.h> #include <odp/api/plat/queue_inlines.h> -#include <odp_shm_internal.h>
/* Inlined API functions */ #include <odp/api/plat/event_inlines.h> @@ -319,7 +318,7 @@ odp_crypto_init_global(void) /* Allocate our globally shared memory */ shm = odp_shm_reserve("_odp_crypto_pool_null", mem_size, ODP_CACHE_LINE_SIZE, - _ODP_SHM_NO_HP); + 0); if (ODP_SHM_INVALID == shm) { ODP_ERR("unable to allocate crypto pool\n"); return -1; diff --git a/platform/linux-generic/odp_crypto_openssl.c b/platform/linux-generic/odp_crypto_openssl.c index ec3e85bf..8feebefb 100644 --- a/platform/linux-generic/odp_crypto_openssl.c +++ b/platform/linux-generic/odp_crypto_openssl.c @@ -21,7 +21,6 @@ #include <odp/api/plat/thread_inlines.h> #include <odp_packet_internal.h> #include <odp/api/plat/queue_inlines.h> -#include <odp_shm_internal.h>
/* Inlined API functions */ #include <odp/api/plat/event_inlines.h> @@ -1859,7 +1858,7 @@ odp_crypto_init_global(void) /* Allocate our globally shared memory */ shm = odp_shm_reserve("_odp_crypto_pool_ssl", mem_size, ODP_CACHE_LINE_SIZE, - _ODP_SHM_NO_HP); + 0); if (ODP_SHM_INVALID == shm) { ODP_ERR("unable to allocate crypto pool\n"); return -1; diff --git a/platform/linux-generic/odp_ipsec_sad.c b/platform/linux-generic/odp_ipsec_sad.c index 17930092..6eb12f95 100644 --- a/platform/linux-generic/odp_ipsec_sad.c +++ b/platform/linux-generic/odp_ipsec_sad.c @@ -14,7 +14,6 @@ #include <odp_init_internal.h> #include <odp_debug_internal.h> #include <odp_ipsec_internal.h> -#include <odp_shm_internal.h> #include <odp_ring_mpmc_internal.h>
#include <odp/api/plat/atomic_inlines.h> @@ -141,7 +140,7 @@ int _odp_ipsec_sad_init_global(void) shm = odp_shm_reserve("_odp_ipsec_sa_table", sizeof(ipsec_sa_table_t), ODP_CACHE_LINE_SIZE, - _ODP_SHM_NO_HP); + 0); if (shm == ODP_SHM_INVALID) return -1;
diff --git a/platform/linux-generic/odp_ishm.c b/platform/linux-generic/odp_ishm.c index 4a481397..07cd2ecb 100644 --- a/platform/linux-generic/odp_ishm.c +++ b/platform/linux-generic/odp_ishm.c @@ -1029,8 +1029,7 @@ int _odp_ishm_reserve(const char *name, uint64_t size, int fd,
/* Get system page sizes: page_hp_size is 0 if no huge page available*/ page_sz = odp_sys_page_size(); - page_hp_size = user_flags & _ODP_SHM_NO_HP ? - 0 : odp_sys_huge_page_size(); + page_hp_size = odp_sys_huge_page_size();
/* grab a new entry: */ for (new_index = 0; new_index < ISHM_MAX_NB_BLOCKS; new_index++) { diff --git a/platform/linux-generic/odp_packet_io.c b/platform/linux-generic/odp_packet_io.c index c5efdc42..4954d5f0 100644 --- a/platform/linux-generic/odp_packet_io.c +++ b/platform/linux-generic/odp_packet_io.c @@ -29,7 +29,6 @@ #include <odp/api/plat/time_inlines.h> #include <odp_pcapng.h> #include <odp/api/plat/queue_inlines.h> -#include <odp_shm_internal.h>
#include <string.h> #include <inttypes.h> @@ -69,7 +68,7 @@ int odp_pktio_init_global(void) shm = odp_shm_reserve("_odp_pktio_entries", sizeof(pktio_table_t), sizeof(pktio_entry_t), - _ODP_SHM_NO_HP); + 0); if (shm == ODP_SHM_INVALID) return -1;
diff --git a/platform/linux-generic/odp_pool.c b/platform/linux-generic/odp_pool.c index d08be437..10382c4c 100644 --- a/platform/linux-generic/odp_pool.c +++ b/platform/linux-generic/odp_pool.c @@ -20,7 +20,6 @@ #include <odp_config_internal.h> #include <odp_debug_internal.h> #include <odp_ring_internal.h> -#include <odp_shm_internal.h> #include <odp_global_data.h> #include <odp_libconfig_internal.h>
@@ -119,7 +118,7 @@ int odp_pool_init_global(void) shm = odp_shm_reserve("_odp_pool_table", sizeof(pool_table_t), ODP_CACHE_LINE_SIZE, - _ODP_SHM_NO_HP); + 0);
pool_tbl = odp_shm_addr(shm);
diff --git a/platform/linux-generic/odp_queue_basic.c b/platform/linux-generic/odp_queue_basic.c index 0d50c764..c3654884 100644 --- a/platform/linux-generic/odp_queue_basic.c +++ b/platform/linux-generic/odp_queue_basic.c @@ -15,7 +15,6 @@ #include <odp_buffer_internal.h> #include <odp_pool_internal.h> #include <odp_init_internal.h> -#include <odp_shm_internal.h> #include <odp_timer_internal.h> #include <odp/api/shared_memory.h> #include <odp/api/schedule.h> @@ -138,7 +137,7 @@ static int queue_init_global(void) shm = odp_shm_reserve("_odp_queue_gbl", sizeof(queue_global_t), sizeof(queue_entry_t), - _ODP_SHM_NO_HP); + 0); if (shm == ODP_SHM_INVALID) return -1;
@@ -165,7 +164,7 @@ static int queue_init_global(void)
shm = odp_shm_reserve("_odp_queue_rings", mem_size, ODP_CACHE_LINE_SIZE, - _ODP_SHM_NO_HP); + 0);
if (shm == ODP_SHM_INVALID) { odp_shm_free(queue_glb->queue_gbl_shm); diff --git a/platform/linux-generic/odp_queue_lf.c b/platform/linux-generic/odp_queue_lf.c index ac8b4226..3e156a08 100644 --- a/platform/linux-generic/odp_queue_lf.c +++ b/platform/linux-generic/odp_queue_lf.c @@ -9,7 +9,6 @@ #include <odp/api/plat/atomic_inlines.h> #include <odp/api/shared_memory.h> #include <odp_queue_basic_internal.h> -#include <odp_shm_internal.h> #include <string.h> #include <stdio.h>
@@ -321,7 +320,7 @@ uint32_t queue_lf_init_global(uint32_t *queue_lf_size,
shm = odp_shm_reserve("_odp_queues_lf", sizeof(queue_lf_global_t), ODP_CACHE_LINE_SIZE, - _ODP_SHM_NO_HP); + 0); if (shm == ODP_SHM_INVALID) return 0;
diff --git a/platform/linux-generic/odp_schedule_basic.c b/platform/linux-generic/odp_schedule_basic.c index 9cf00acb..cf566eb8 100644 --- a/platform/linux-generic/odp_schedule_basic.c +++ b/platform/linux-generic/odp_schedule_basic.c @@ -29,7 +29,6 @@ #include <odp_queue_basic_internal.h> #include <odp_libconfig_internal.h> #include <odp/api/plat/queue_inlines.h> -#include <odp_shm_internal.h>
/* No synchronization context */ #define NO_SYNC_CONTEXT ODP_SCHED_SYNC_PARALLEL @@ -397,7 +396,7 @@ static int schedule_init_global(void) shm = odp_shm_reserve("_odp_scheduler", sizeof(sched_global_t), ODP_CACHE_LINE_SIZE, - _ODP_SHM_NO_HP); + 0); if (shm == ODP_SHM_INVALID) { ODP_ERR("Schedule init: Shm reserve failed.\n"); return -1; diff --git a/platform/linux-generic/odp_schedule_scalable.c b/platform/linux-generic/odp_schedule_scalable.c index 92a5c72b..fc82b65b 100644 --- a/platform/linux-generic/odp_schedule_scalable.c +++ b/platform/linux-generic/odp_schedule_scalable.c @@ -32,7 +32,6 @@ #include <odp_schedule_if.h> #include <odp_bitset.h> #include <odp_packet_io_internal.h> -#include <odp_shm_internal.h> #include <odp_timer_internal.h>
#include <limits.h> @@ -1798,7 +1797,7 @@ static int schedule_init_global(void)
shm = odp_shm_reserve("_odp_sched_scalable", sizeof(sched_global_t), - ODP_CACHE_LINE_SIZE, _ODP_SHM_NO_HP); + ODP_CACHE_LINE_SIZE, 0);
global = odp_shm_addr(shm); if (global == NULL) { diff --git a/platform/linux-generic/pktio/ring.c b/platform/linux-generic/pktio/ring.c index 6a354cb1..2cf0231c 100644 --- a/platform/linux-generic/pktio/ring.c +++ b/platform/linux-generic/pktio/ring.c @@ -80,7 +80,6 @@ #include <odp_packet_io_ring_internal.h> #include <odp_errno_define.h> #include <odp_global_data.h> -#include <odp_shm_internal.h>
#include <odp/api/plat/cpu_inlines.h>
@@ -164,7 +163,7 @@ int _ring_tailq_init(void)
/* Allocate globally shared memory */ shm = odp_shm_reserve("_odp_ring_global", sizeof(global_data_t), - ODP_CACHE_LINE_SIZE, _ODP_SHM_NO_HP); + ODP_CACHE_LINE_SIZE, 0); if (ODP_SHM_INVALID == shm) { ODP_ERR("Shm reserve failed for pktio ring\n"); return -1;
commit 295bf070e27323060ba607805dd95ce0353a9461 Author: Petri Savolainen petri.savolainen@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@linaro.org Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@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; }
commit ae66a05708d04f332d85fb258196d9045ebc303c Author: Maxim Uvarov maxim.uvarov@linaro.org Date: Sun Oct 28 10:14:20 2018 +0300
linuxgen: add dumpconfig utility
it might be useful to package small binary which prints platform default builtin config file.
Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org Reviewed-by: Bill Fischofer bill.fischofer@linaro.org
diff --git a/Makefile.am b/Makefile.am index e4dab7e3..f651e9ca 100644 --- a/Makefile.am +++ b/Makefile.am @@ -5,12 +5,14 @@ AM_DISTCHECK_CONFIGURE_FLAGS = --enable-user-guides \
if PLATFORM_IS_LINUX_GENERIC PLATFORM_DIR = platform/linux-generic +PLATFORM_DUMPCONF_DIR = platform/linux-generic/dumpconfig PLATFORM_TEST_DIR = platform/linux-generic/test endif
SUBDIRS = \ include \ $(PLATFORM_DIR) \ + $(PLATFORM_DUMPCONF_DIR) \ helper \ doc
diff --git a/platform/linux-generic/dumpconfig/.gitignore b/platform/linux-generic/dumpconfig/.gitignore new file mode 100644 index 00000000..44752b56 --- /dev/null +++ b/platform/linux-generic/dumpconfig/.gitignore @@ -0,0 +1 @@ +odp_linuxgen_dumpconfig diff --git a/platform/linux-generic/dumpconfig/Makefile.am b/platform/linux-generic/dumpconfig/Makefile.am new file mode 100644 index 00000000..933424f0 --- /dev/null +++ b/platform/linux-generic/dumpconfig/Makefile.am @@ -0,0 +1,10 @@ +include $(top_srcdir)/Makefile.inc + +AM_CPPFLAGS = -I$(top_builddir)/platform/$(with_platform)/include +AM_CPPFLAGS += -I$(top_srcdir)/platform/$(with_platform)/include + +bin_PROGRAMS = odp_linuxgen_dumpconfig + +odp_linuxgen_dumpconfig_SOURCES = dumpconfig.c + +TESTS = odp_linuxgen_dumpconfig diff --git a/platform/linux-generic/dumpconfig/dumpconfig.c b/platform/linux-generic/dumpconfig/dumpconfig.c new file mode 100644 index 00000000..a04f5c2d --- /dev/null +++ b/platform/linux-generic/dumpconfig/dumpconfig.c @@ -0,0 +1,43 @@ +/* Copyright (c) 2018, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <stdio.h> +#include <stdlib.h> +#include <odp_libconfig_config.h> + +int main(void) +{ + unsigned int i; + const char *filename; + FILE *f; + char c; + + printf("# Builtin platform config\n\n"); + for (i = 0; i < sizeof(config_builtin); i++) + printf("%c", config_builtin[i]); + + filename = getenv("ODP_CONFIG_FILE"); + if (filename == NULL) + return 0; + + printf("# Overridden section with ODP_CONFIG_FILE=%s\n\n", filename); + + f = fopen(filename, "r"); + if (f == NULL) { + fprintf(stderr, "Error: open file %s\n", filename); + return -1; + } + + while (1) { + c = fgetc(f); + if (feof(f)) + break; + printf("%c", c); + } + + fclose(f); + return 0; +} diff --git a/platform/linux-generic/m4/configure.m4 b/platform/linux-generic/m4/configure.m4 index e0fd099b..f9e9c494 100644 --- a/platform/linux-generic/m4/configure.m4 +++ b/platform/linux-generic/m4/configure.m4 @@ -27,6 +27,7 @@ AM_CONDITIONAL([PLATFORM_IS_LINUX_GENERIC], [test "${with_platform}" = "linux-generic"]) AC_CONFIG_FILES([platform/linux-generic/Makefile platform/linux-generic/libodp-linux.pc + platform/linux-generic/dumpconfig/Makefile platform/linux-generic/test/Makefile platform/linux-generic/test/validation/api/shmem/Makefile platform/linux-generic/test/validation/api/pktio/Makefile
commit eb3a816cb0fa6c5e76b25398a0ac280c769dcb49 Author: Petri Savolainen petri.savolainen@linaro.org Date: Wed Nov 7 10:44:00 2018 +0200
validation: crypto: capability call should not fail
Capability call should always succeed. It's possible that no algorithms are supported, but also then the call should succeed.
Signed-off-by: Petri Savolainen petri.savolainen@linaro.org Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Reviewed-by: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/test/validation/api/crypto/odp_crypto_test_inp.c b/test/validation/api/crypto/odp_crypto_test_inp.c index e8cc1547..b2f599ec 100644 --- a/test/validation/api/crypto/odp_crypto_test_inp.c +++ b/test/validation/api/crypto/odp_crypto_test_inp.c @@ -696,8 +696,11 @@ static int check_alg_support(odp_cipher_alg_t cipher, odp_auth_alg_t auth) { odp_crypto_capability_t capability;
- if (odp_crypto_capability(&capability)) + memset(&capability, 0, sizeof(odp_crypto_capability_t)); + if (odp_crypto_capability(&capability)) { + fprintf(stderr, "odp_crypto_capability() failed\n"); return ODP_TEST_INACTIVE; + }
if (suite_context.packet) { if (suite_context.op_mode == ODP_CRYPTO_SYNC && @@ -2030,6 +2033,7 @@ static int crypto_init(odp_instance_t *inst) odp_pool_t pool; odp_queue_t out_queue; odp_pool_capability_t pool_capa; + odp_crypto_capability_t crypto_capa; odp_init_t init_param; odph_helper_options_t helper_options;
@@ -2051,6 +2055,11 @@ static int crypto_init(odp_instance_t *inst) return -1; }
+ if (odp_crypto_capability(&crypto_capa)) { + fprintf(stderr, "error: odp_crypto_capability() failed.\n"); + return -1; + } + if (odp_pool_capability(&pool_capa) < 0) { fprintf(stderr, "error: odp_pool_capability() failed.\n"); return -1;
-----------------------------------------------------------------------
Summary of changes: .shippable.yml | 13 +- .travis.yml | 24 +- Makefile.am | 2 + config/odp-linux-generic.conf | 29 +- configure.ac | 6 + example/generator/odp_generator.c | 13 + example/sysinfo/odp_sysinfo.c | 4 + platform/linux-generic/Makefile.am | 1 - platform/linux-generic/arch/aarch64/odp_atomic.h | 49 +- .../linux-generic/arch/aarch64/odp_sysinfo_parse.c | 71 ++- .../linux-generic/arch/default/odp_sysinfo_parse.c | 16 +- .../linux-generic/arch/x86/odp_sysinfo_parse.c | 2 + platform/linux-generic/dumpconfig/.gitignore | 1 + platform/linux-generic/dumpconfig/Makefile.am | 10 + platform/linux-generic/dumpconfig/dumpconfig.c | 43 ++ .../linux-generic/include/odp_config_internal.h | 10 - platform/linux-generic/include/odp_ishm_internal.h | 54 -- .../linux-generic/include/odp_ishmphy_internal.h | 6 +- .../linux-generic/include/odp_ishmpool_internal.h | 1 - platform/linux-generic/include/odp_shm_internal.h | 42 +- .../linux-generic/include/odp_sysinfo_internal.h | 19 + .../linux-generic/include/odp_timer_internal.h | 11 +- platform/linux-generic/m4/configure.m4 | 6 +- platform/linux-generic/m4/performance.m4 | 10 - platform/linux-generic/odp_classification.c | 98 +-- platform/linux-generic/odp_crypto_null.c | 3 +- platform/linux-generic/odp_crypto_openssl.c | 3 +- platform/linux-generic/odp_init.c | 1 + platform/linux-generic/odp_ipsec_sad.c | 3 +- platform/linux-generic/odp_ishm.c | 699 +++++++++++---------- platform/linux-generic/odp_ishmphy.c | 142 ++--- platform/linux-generic/odp_ishmpool.c | 26 +- platform/linux-generic/odp_packet_io.c | 3 +- platform/linux-generic/odp_pool.c | 18 +- platform/linux-generic/odp_queue_basic.c | 24 +- platform/linux-generic/odp_queue_lf.c | 3 +- platform/linux-generic/odp_queue_scalable.c | 67 +- platform/linux-generic/odp_schedule_basic.c | 12 +- platform/linux-generic/odp_schedule_scalable.c | 58 +- platform/linux-generic/odp_schedule_sp.c | 6 +- platform/linux-generic/odp_shared_memory.c | 31 +- platform/linux-generic/odp_system_info.c | 17 +- platform/linux-generic/odp_timer.c | 70 ++- platform/linux-generic/pktio/ipc.c | 2 +- platform/linux-generic/pktio/ring.c | 3 +- platform/linux-generic/test/Makefile.am | 10 +- platform/linux-generic/test/inline-timer.conf | 8 + platform/linux-generic/test/performance/.gitignore | 2 - .../linux-generic/test/performance/Makefile.am | 13 - .../test/performance/odp_scheduling_run_proc.sh | 30 - platform/linux-generic/test/process-mode.conf | 4 +- .../test/validation/api/shmem/shmem_linux.c | 17 +- scripts/Dockerfile | 28 - scripts/ci/check.sh | 8 +- scripts/ci/{check.sh => check_inline_timer.sh} | 7 +- test/performance/odp_l2fwd_run.sh | 2 +- test/performance/odp_queue_perf.c | 9 +- test/performance/odp_sched_pktio.c | 6 +- test/performance/odp_sched_pktio_run.sh | 2 +- test/validation/api/crypto/odp_crypto_test_inp.c | 11 +- test/validation/api/pool/pool.c | 103 +++ test/validation/api/shmem/shmem.c | 14 +- 62 files changed, 1055 insertions(+), 951 deletions(-) create mode 100644 platform/linux-generic/dumpconfig/.gitignore create mode 100644 platform/linux-generic/dumpconfig/Makefile.am create mode 100644 platform/linux-generic/dumpconfig/dumpconfig.c delete mode 100644 platform/linux-generic/include/odp_ishm_internal.h delete mode 100644 platform/linux-generic/m4/performance.m4 create mode 100644 platform/linux-generic/test/inline-timer.conf delete mode 100644 platform/linux-generic/test/performance/.gitignore delete mode 100644 platform/linux-generic/test/performance/Makefile.am delete mode 100755 platform/linux-generic/test/performance/odp_scheduling_run_proc.sh delete mode 100644 scripts/Dockerfile copy scripts/ci/{check.sh => check_inline_timer.sh} (51%)
hooks/post-receive