From: David Marchand Date: Fri, 29 Jul 2016 12:28:36 +0000 (+0200) Subject: ivshmem: remove library and its EAL integration X-Git-Tag: spdx-start~6036 X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=c711ccb30987;p=dpdk.git ivshmem: remove library and its EAL integration Following discussions on the mailing list [1] and since nobody stood up to implement the necessary cleanups, here is the ivshmem integration removal. There is not much to say about this patch, a lot of code is being removed. The default configuration file for packet_ordering example is replaced with the "native" x86 file. The only tricky part is in eal_memory with the memseg index stuff. More cleanups can be done after this but will come in subsequent patchsets. [1]: http://dpdk.org/ml/archives/dev/2016-June/040844.html Signed-off-by: David Marchand Acked-by: Panu Matilainen Acked-by: Anatoly Burakov --- diff --git a/MAINTAINERS b/MAINTAINERS index 6536c6b1a6..5e3d8255e8 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -546,14 +546,6 @@ F: app/test/test_cmdline* F: examples/cmdline/ F: doc/guides/sample_app_ug/cmd_line.rst -Qemu IVSHMEM -M: Anatoly Burakov -F: lib/librte_ivshmem/ -F: lib/librte_eal/linuxapp/eal/eal_ivshmem.c -F: doc/guides/prog_guide/ivshmem_lib.rst -F: app/test/test_ivshmem.c -F: examples/l2fwd-ivshmem/ - Key/Value parsing M: Olivier Matz F: lib/librte_kvargs/ diff --git a/app/test/Makefile b/app/test/Makefile index 49ea195966..611d77a7d3 100644 --- a/app/test/Makefile +++ b/app/test/Makefile @@ -167,7 +167,6 @@ SRCS-$(CONFIG_RTE_LIBRTE_KNI) += test_kni.c SRCS-$(CONFIG_RTE_LIBRTE_POWER) += test_power.c test_power_acpi_cpufreq.c SRCS-$(CONFIG_RTE_LIBRTE_POWER) += test_power_kvm_vm.c SRCS-y += test_common.c -SRCS-$(CONFIG_RTE_LIBRTE_IVSHMEM) += test_ivshmem.c SRCS-$(CONFIG_RTE_LIBRTE_DISTRIBUTOR) += test_distributor.c SRCS-$(CONFIG_RTE_LIBRTE_DISTRIBUTOR) += test_distributor_perf.c diff --git a/app/test/autotest_data.py b/app/test/autotest_data.py index defd46e888..9e8fd946a0 100644 --- a/app/test/autotest_data.py +++ b/app/test/autotest_data.py @@ -173,12 +173,6 @@ parallel_test_group_list = [ "Func" : default_autotest, "Report" : None, }, - { - "Name" : "IVSHMEM autotest", - "Command" : "ivshmem_autotest", - "Func" : default_autotest, - "Report" : None, - }, { "Name" : "Memcpy autotest", "Command" : "memcpy_autotest", diff --git a/app/test/test.c b/app/test/test.c index ccad0e3008..cd0e784589 100644 --- a/app/test/test.c +++ b/app/test/test.c @@ -95,9 +95,6 @@ do_recursive_call(void) { "test_memory_flags", no_action }, { "test_file_prefix", no_action }, { "test_no_huge_flag", no_action }, -#ifdef RTE_LIBRTE_IVSHMEM - { "test_ivshmem", test_ivshmem }, -#endif }; if (recursive_call == NULL) diff --git a/app/test/test.h b/app/test/test.h index 74d60217cd..82831f4e6c 100644 --- a/app/test/test.h +++ b/app/test/test.h @@ -238,7 +238,6 @@ int test_pci_run; int test_mp_secondary(void); -int test_ivshmem(void); int test_set_rxtx_conf(cmdline_fixed_string_t mode); int test_set_rxtx_anchor(cmdline_fixed_string_t type); int test_set_rxtx_sc(cmdline_fixed_string_t type); diff --git a/app/test/test_ivshmem.c b/app/test/test_ivshmem.c deleted file mode 100644 index ae9fd6cccc..0000000000 --- a/app/test/test_ivshmem.c +++ /dev/null @@ -1,433 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "test.h" - -#include -#include -#include -#include "process.h" - -#define DUPLICATE_METADATA "duplicate" -#define METADATA_NAME "metadata" -#define NONEXISTENT_METADATA "nonexistent" -#define FIRST_TEST 'a' - -#define launch_proc(ARGV) process_dup(ARGV, \ - sizeof(ARGV)/(sizeof(ARGV[0])), "test_ivshmem") - -#define ASSERT(cond,msg) do { \ - if (!(cond)) { \ - printf("**** TEST %s() failed: %s\n", \ - __func__, msg); \ - return -1; \ - } \ -} while(0) - -static char* -get_current_prefix(char * prefix, int size) -{ - char path[PATH_MAX] = {0}; - char buf[PATH_MAX] = {0}; - - /* get file for config (fd is always 3) */ - snprintf(path, sizeof(path), "/proc/self/fd/%d", 3); - - /* return NULL on error */ - if (readlink(path, buf, sizeof(buf)) == -1) - return NULL; - - /* get the basename */ - snprintf(buf, sizeof(buf), "%s", basename(buf)); - - /* copy string all the way from second char up to start of _config */ - snprintf(prefix, size, "%.*s", - (int)(strnlen(buf, sizeof(buf)) - sizeof("_config")), - &buf[1]); - - return prefix; -} - -static struct rte_ivshmem_metadata* -mmap_metadata(const char *name) -{ - int fd; - char pathname[PATH_MAX]; - struct rte_ivshmem_metadata *metadata; - - snprintf(pathname, sizeof(pathname), - "/var/run/.dpdk_ivshmem_metadata_%s", name); - - fd = open(pathname, O_RDWR, 0660); - if (fd < 0) - return NULL; - - metadata = (struct rte_ivshmem_metadata*) mmap(NULL, - sizeof(struct rte_ivshmem_metadata), PROT_READ | PROT_WRITE, - MAP_SHARED, fd, 0); - - if (metadata == MAP_FAILED) - return NULL; - - close(fd); - - return metadata; -} - -static int -create_duplicate(void) -{ - /* create a metadata that another process will then try to overwrite */ - ASSERT (rte_ivshmem_metadata_create(DUPLICATE_METADATA) == 0, - "Creating metadata failed"); - return 0; -} - -static int -test_ivshmem_create_lots_of_memzones(void) -{ - int i; - char name[IVSHMEM_NAME_LEN]; - const struct rte_memzone *mz; - - ASSERT(rte_ivshmem_metadata_create(METADATA_NAME) == 0, - "Failed to create metadata"); - - for (i = 0; i < RTE_LIBRTE_IVSHMEM_MAX_ENTRIES; i++) { - snprintf(name, sizeof(name), "mz_%i", i); - - mz = rte_memzone_reserve(name, RTE_CACHE_LINE_SIZE, SOCKET_ID_ANY, 0); - ASSERT(mz != NULL, "Failed to reserve memzone"); - - ASSERT(rte_ivshmem_metadata_add_memzone(mz, METADATA_NAME) == 0, - "Failed to add memzone"); - } - mz = rte_memzone_reserve("one too many", RTE_CACHE_LINE_SIZE, SOCKET_ID_ANY, 0); - ASSERT(mz != NULL, "Failed to reserve memzone"); - - ASSERT(rte_ivshmem_metadata_add_memzone(mz, METADATA_NAME) < 0, - "Metadata should have been full"); - - return 0; -} - -static int -test_ivshmem_create_duplicate_memzone(void) -{ - const struct rte_memzone *mz; - - ASSERT(rte_ivshmem_metadata_create(METADATA_NAME) == 0, - "Failed to create metadata"); - - mz = rte_memzone_reserve("mz", RTE_CACHE_LINE_SIZE, SOCKET_ID_ANY, 0); - ASSERT(mz != NULL, "Failed to reserve memzone"); - - ASSERT(rte_ivshmem_metadata_add_memzone(mz, METADATA_NAME) == 0, - "Failed to add memzone"); - - ASSERT(rte_ivshmem_metadata_add_memzone(mz, METADATA_NAME) < 0, - "Added the same memzone twice"); - - return 0; -} - -static int -test_ivshmem_api_test(void) -{ - const struct rte_memzone * mz; - struct rte_mempool * mp; - struct rte_ring * r; - char buf[BUFSIZ]; - - memset(buf, 0, sizeof(buf)); - - r = rte_ring_create("ring", 1, SOCKET_ID_ANY, 0); - mp = rte_mempool_create("mempool", 1, 1, 1, 1, NULL, NULL, NULL, NULL, - SOCKET_ID_ANY, 0); - mz = rte_memzone_reserve("memzone", 64, SOCKET_ID_ANY, 0); - - ASSERT(r != NULL, "Failed to create ring"); - ASSERT(mp != NULL, "Failed to create mempool"); - ASSERT(mz != NULL, "Failed to reserve memzone"); - - /* try to create NULL metadata */ - ASSERT(rte_ivshmem_metadata_create(NULL) < 0, - "Created metadata with NULL name"); - - /* create valid metadata to do tests on */ - ASSERT(rte_ivshmem_metadata_create(METADATA_NAME) == 0, - "Failed to create metadata"); - - /* test adding memzone */ - ASSERT(rte_ivshmem_metadata_add_memzone(NULL, NULL) < 0, - "Added NULL memzone to NULL metadata"); - ASSERT(rte_ivshmem_metadata_add_memzone(NULL, METADATA_NAME) < 0, - "Added NULL memzone"); - ASSERT(rte_ivshmem_metadata_add_memzone(mz, NULL) < 0, - "Added memzone to NULL metadata"); - ASSERT(rte_ivshmem_metadata_add_memzone(mz, NONEXISTENT_METADATA) < 0, - "Added memzone to nonexistent metadata"); - - /* test adding ring */ - ASSERT(rte_ivshmem_metadata_add_ring(NULL, NULL) < 0, - "Added NULL ring to NULL metadata"); - ASSERT(rte_ivshmem_metadata_add_ring(NULL, METADATA_NAME) < 0, - "Added NULL ring"); - ASSERT(rte_ivshmem_metadata_add_ring(r, NULL) < 0, - "Added ring to NULL metadata"); - ASSERT(rte_ivshmem_metadata_add_ring(r, NONEXISTENT_METADATA) < 0, - "Added ring to nonexistent metadata"); - - /* test adding mempool */ - ASSERT(rte_ivshmem_metadata_add_mempool(NULL, NULL) < 0, - "Added NULL mempool to NULL metadata"); - ASSERT(rte_ivshmem_metadata_add_mempool(NULL, METADATA_NAME) < 0, - "Added NULL mempool"); - ASSERT(rte_ivshmem_metadata_add_mempool(mp, NULL) < 0, - "Added mempool to NULL metadata"); - ASSERT(rte_ivshmem_metadata_add_mempool(mp, NONEXISTENT_METADATA) < 0, - "Added mempool to nonexistent metadata"); - - /* test creating command line */ - ASSERT(rte_ivshmem_metadata_cmdline_generate(NULL, sizeof(buf), METADATA_NAME) < 0, - "Written command line into NULL buffer"); - ASSERT(strnlen(buf, sizeof(buf)) == 0, "Buffer is not empty"); - - ASSERT(rte_ivshmem_metadata_cmdline_generate(buf, 0, METADATA_NAME) < 0, - "Written command line into small buffer"); - ASSERT(strnlen(buf, sizeof(buf)) == 0, "Buffer is not empty"); - - ASSERT(rte_ivshmem_metadata_cmdline_generate(buf, sizeof(buf), NULL) < 0, - "Written command line for NULL metadata"); - ASSERT(strnlen(buf, sizeof(buf)) == 0, "Buffer is not empty"); - - ASSERT(rte_ivshmem_metadata_cmdline_generate(buf, sizeof(buf), - NONEXISTENT_METADATA) < 0, - "Writen command line for nonexistent metadata"); - ASSERT(strnlen(buf, sizeof(buf)) == 0, "Buffer is not empty"); - - /* add stuff to config */ - ASSERT(rte_ivshmem_metadata_add_memzone(mz, METADATA_NAME) == 0, - "Failed to add memzone to valid config"); - ASSERT(rte_ivshmem_metadata_add_ring(r, METADATA_NAME) == 0, - "Failed to add ring to valid config"); - ASSERT(rte_ivshmem_metadata_add_mempool(mp, METADATA_NAME) == 0, - "Failed to add mempool to valid config"); - - /* create config */ - ASSERT(rte_ivshmem_metadata_cmdline_generate(buf, sizeof(buf), - METADATA_NAME) == 0, "Failed to write command-line"); - - /* check if something was written */ - ASSERT(strnlen(buf, sizeof(buf)) != 0, "Buffer is empty"); - - /* make sure we don't segfault */ - rte_ivshmem_metadata_dump(stdout, NULL); - - /* dump our metadata */ - rte_ivshmem_metadata_dump(stdout, METADATA_NAME); - - return 0; -} - -static int -test_ivshmem_create_duplicate_metadata(void) -{ - ASSERT(rte_ivshmem_metadata_create(DUPLICATE_METADATA) < 0, - "Creating duplicate metadata should have failed"); - - return 0; -} - -static int -test_ivshmem_create_metadata_config(void) -{ - struct rte_ivshmem_metadata *metadata; - - rte_ivshmem_metadata_create(METADATA_NAME); - - metadata = mmap_metadata(METADATA_NAME); - - ASSERT(metadata != MAP_FAILED, "Metadata mmaping failed"); - - ASSERT(metadata->magic_number == IVSHMEM_MAGIC, - "Magic number is not that magic"); - - ASSERT(strncmp(metadata->name, METADATA_NAME, sizeof(metadata->name)) == 0, - "Name has not been set up"); - - ASSERT(metadata->entry[0].offset == 0, "Offest is not initialized"); - ASSERT(metadata->entry[0].mz.addr == 0, "mz.addr is not initialized"); - ASSERT(metadata->entry[0].mz.len == 0, "mz.len is not initialized"); - - return 0; -} - -static int -test_ivshmem_create_multiple_metadata_configs(void) -{ - int i; - char name[IVSHMEM_NAME_LEN]; - struct rte_ivshmem_metadata *metadata; - - for (i = 0; i < RTE_LIBRTE_IVSHMEM_MAX_METADATA_FILES / 2; i++) { - snprintf(name, sizeof(name), "test_%d", i); - rte_ivshmem_metadata_create(name); - metadata = mmap_metadata(name); - - ASSERT(metadata->magic_number == IVSHMEM_MAGIC, - "Magic number is not that magic"); - - ASSERT(strncmp(metadata->name, name, sizeof(metadata->name)) == 0, - "Name has not been set up"); - } - - return 0; -} - -static int -test_ivshmem_create_too_many_metadata_configs(void) -{ - int i; - char name[IVSHMEM_NAME_LEN]; - - for (i = 0; i < RTE_LIBRTE_IVSHMEM_MAX_METADATA_FILES; i++) { - snprintf(name, sizeof(name), "test_%d", i); - ASSERT(rte_ivshmem_metadata_create(name) == 0, - "Create config file failed"); - } - - ASSERT(rte_ivshmem_metadata_create(name) < 0, - "Create config file didn't fail"); - - return 0; -} - -enum rte_ivshmem_tests { - _test_ivshmem_api_test = 0, - _test_ivshmem_create_metadata_config, - _test_ivshmem_create_multiple_metadata_configs, - _test_ivshmem_create_too_many_metadata_configs, - _test_ivshmem_create_duplicate_metadata, - _test_ivshmem_create_lots_of_memzones, - _test_ivshmem_create_duplicate_memzone, - _last_test, -}; - -#define RTE_IVSHMEM_TEST_ID "RTE_IVSHMEM_TEST_ID" - -static int -launch_all_tests_on_secondary_processes(void) -{ - int ret = 0; - char id; - char testid; - char tmp[PATH_MAX] = {0}; - char prefix[PATH_MAX] = {0}; - - get_current_prefix(tmp, sizeof(tmp)); - - snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp); - - const char *argv[] = { prgname, "-c", "1", "-n", "3", - "--proc-type=secondary", prefix }; - - for (id = 0; id < _last_test; id++) { - testid = (char)(FIRST_TEST + id); - setenv(RTE_IVSHMEM_TEST_ID, &testid, 1); - if (launch_proc(argv) != 0) - return -1; - } - return ret; -} - -int -test_ivshmem(void) -{ - int testid; - - /* We want to have a clean execution for every test without exposing - * private global data structures in rte_ivshmem so we launch each test - * on a different secondary process. */ - if (rte_eal_process_type() == RTE_PROC_PRIMARY) { - - /* first, create metadata */ - ASSERT(create_duplicate() == 0, "Creating metadata failed"); - - return launch_all_tests_on_secondary_processes(); - } - - testid = *(getenv(RTE_IVSHMEM_TEST_ID)) - FIRST_TEST; - - printf("Secondary process running test %d \n", testid); - - switch (testid) { - case _test_ivshmem_api_test: - return test_ivshmem_api_test(); - - case _test_ivshmem_create_metadata_config: - return test_ivshmem_create_metadata_config(); - - case _test_ivshmem_create_multiple_metadata_configs: - return test_ivshmem_create_multiple_metadata_configs(); - - case _test_ivshmem_create_too_many_metadata_configs: - return test_ivshmem_create_too_many_metadata_configs(); - - case _test_ivshmem_create_duplicate_metadata: - return test_ivshmem_create_duplicate_metadata(); - - case _test_ivshmem_create_lots_of_memzones: - return test_ivshmem_create_lots_of_memzones(); - - case _test_ivshmem_create_duplicate_memzone: - return test_ivshmem_create_duplicate_memzone(); - - default: - break; - } - - return -1; -} - -REGISTER_TEST_COMMAND(ivshmem_autotest, test_ivshmem); diff --git a/config/defconfig_arm64-armv8a-linuxapp-gcc b/config/defconfig_arm64-armv8a-linuxapp-gcc index 1a1712665f..73f4733429 100644 --- a/config/defconfig_arm64-armv8a-linuxapp-gcc +++ b/config/defconfig_arm64-armv8a-linuxapp-gcc @@ -44,7 +44,6 @@ CONFIG_RTE_TOOLCHAIN_GCC=y CONFIG_RTE_EAL_IGB_UIO=n -CONFIG_RTE_LIBRTE_IVSHMEM=n CONFIG_RTE_LIBRTE_FM10K_PMD=n CONFIG_RTE_LIBRTE_I40E_PMD=n diff --git a/config/defconfig_x86_64-ivshmem-linuxapp-gcc b/config/defconfig_x86_64-ivshmem-linuxapp-gcc deleted file mode 100644 index 41ac5c31d6..0000000000 --- a/config/defconfig_x86_64-ivshmem-linuxapp-gcc +++ /dev/null @@ -1,49 +0,0 @@ -# BSD LICENSE -# -# Copyright(c) 2010-2014 Intel Corporation. All rights reserved. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Intel Corporation nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# - -# -# use default config -# - -#include "defconfig_x86_64-native-linuxapp-gcc" - -# -# Compile IVSHMEM library -# -CONFIG_RTE_LIBRTE_IVSHMEM=y -CONFIG_RTE_LIBRTE_IVSHMEM_DEBUG=n -CONFIG_RTE_LIBRTE_IVSHMEM_MAX_PCI_DEVS=4 -CONFIG_RTE_LIBRTE_IVSHMEM_MAX_ENTRIES=128 -CONFIG_RTE_LIBRTE_IVSHMEM_MAX_METADATA_FILES=32 - -# Set EAL to single file segments -CONFIG_RTE_EAL_SINGLE_FILE_SEGMENTS=y \ No newline at end of file diff --git a/config/defconfig_x86_64-ivshmem-linuxapp-icc b/config/defconfig_x86_64-ivshmem-linuxapp-icc deleted file mode 100644 index 77fec939a8..0000000000 --- a/config/defconfig_x86_64-ivshmem-linuxapp-icc +++ /dev/null @@ -1,49 +0,0 @@ -# BSD LICENSE -# -# Copyright(c) 2010-2014 Intel Corporation. All rights reserved. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Intel Corporation nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# - -# -# use default config -# - -#include "defconfig_x86_64-native-linuxapp-icc" - -# -# Compile IVSHMEM library -# -CONFIG_RTE_LIBRTE_IVSHMEM=y -CONFIG_RTE_LIBRTE_IVSHMEM_DEBUG=n -CONFIG_RTE_LIBRTE_IVSHMEM_MAX_PCI_DEVS=4 -CONFIG_RTE_LIBRTE_IVSHMEM_MAX_ENTRIES=128 -CONFIG_RTE_LIBRTE_IVSHMEM_MAX_METADATA_FILES=32 - -# Set EAL to single file segments -CONFIG_RTE_EAL_SINGLE_FILE_SEGMENTS=y diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md index 2284a53b0c..6675f96527 100644 --- a/doc/api/doxy-api-index.md +++ b/doc/api/doxy-api-index.md @@ -108,7 +108,6 @@ There are many libraries, so their headers may be grouped by topics: [reorder] (@ref rte_reorder.h), [tailq] (@ref rte_tailq.h), [bitmap] (@ref rte_bitmap.h), - [ivshmem] (@ref rte_ivshmem.h) - **packet framework**: * [port] (@ref rte_port.h): diff --git a/doc/api/doxy-api.conf b/doc/api/doxy-api.conf index af5d6dd41b..9dc7ae5c8a 100644 --- a/doc/api/doxy-api.conf +++ b/doc/api/doxy-api.conf @@ -43,7 +43,6 @@ INPUT = doc/api/doxy-api-index.md \ lib/librte_ether \ lib/librte_hash \ lib/librte_ip_frag \ - lib/librte_ivshmem \ lib/librte_jobstats \ lib/librte_kni \ lib/librte_kvargs \ diff --git a/doc/api/examples.dox b/doc/api/examples.dox index 200af0b07d..1626852cc8 100644 --- a/doc/api/examples.dox +++ b/doc/api/examples.dox @@ -40,8 +40,6 @@ @example ipv4_multicast/main.c @example kni/main.c @example l2fwd-crypto/main.c -@example l2fwd-ivshmem/guest/guest.c -@example l2fwd-ivshmem/host/host.c @example l2fwd-jobstats/main.c @example l2fwd-keepalive/main.c @example l2fwd/main.c diff --git a/doc/guides/linux_gsg/build_dpdk.rst b/doc/guides/linux_gsg/build_dpdk.rst index f8007b317b..474598a039 100644 --- a/doc/guides/linux_gsg/build_dpdk.rst +++ b/doc/guides/linux_gsg/build_dpdk.rst @@ -75,7 +75,7 @@ where: * ``ARCH`` can be: ``i686``, ``x86_64``, ``ppc_64`` -* ``MACHINE`` can be: ``native``, ``ivshmem``, ``power8`` +* ``MACHINE`` can be: ``native``, ``power8`` * ``EXECENV`` can be: ``linuxapp``, ``bsdapp`` diff --git a/doc/guides/linux_gsg/quick_start.rst b/doc/guides/linux_gsg/quick_start.rst index 8789b58884..6e858c2a77 100644 --- a/doc/guides/linux_gsg/quick_start.rst +++ b/doc/guides/linux_gsg/quick_start.rst @@ -126,19 +126,15 @@ Some options in the script prompt the user for further data before proceeding. [3] ppc_64-power8-linuxapp-gcc - [4] x86_64-ivshmem-linuxapp-gcc + [4] x86_64-native-bsdapp-clang - [5] x86_64-ivshmem-linuxapp-icc + [5] x86_64-native-bsdapp-gcc - [6] x86_64-native-bsdapp-clang + [6] x86_64-native-linuxapp-clang - [7] x86_64-native-bsdapp-gcc + [7] x86_64-native-linuxapp-gcc - [8] x86_64-native-linuxapp-clang - - [9] x86_64-native-linuxapp-gcc - - [10] x86_64-native-linuxapp-icc + [8] x86_64-native-linuxapp-icc ------------------------------------------------------------------------ diff --git a/doc/guides/prog_guide/img/ivshmem.png b/doc/guides/prog_guide/img/ivshmem.png deleted file mode 100644 index 2b34a2cfdf..0000000000 Binary files a/doc/guides/prog_guide/img/ivshmem.png and /dev/null differ diff --git a/doc/guides/prog_guide/index.rst b/doc/guides/prog_guide/index.rst index 07a4d354d5..e5a50a8823 100644 --- a/doc/guides/prog_guide/index.rst +++ b/doc/guides/prog_guide/index.rst @@ -43,7 +43,6 @@ Programmer's Guide mbuf_lib poll_mode_drv cryptodev_lib - ivshmem_lib link_bonding_poll_mode_drv_lib timer_lib hash_lib diff --git a/doc/guides/prog_guide/ivshmem_lib.rst b/doc/guides/prog_guide/ivshmem_lib.rst deleted file mode 100644 index b8a32e4c6c..0000000000 --- a/doc/guides/prog_guide/ivshmem_lib.rst +++ /dev/null @@ -1,160 +0,0 @@ -.. BSD LICENSE - Copyright(c) 2010-2014 Intel Corporation. All rights reserved. - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of Intel Corporation nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -IVSHMEM Library -=============== - -The DPDK IVSHMEM library facilitates fast zero-copy data sharing among virtual machines -(host-to-guest or guest-to-guest) by means of QEMU's IVSHMEM mechanism. - -The library works by providing a command line for QEMU to map several hugepages into a single IVSHMEM device. -For the guest to know what is inside any given IVSHMEM device -(and to distinguish between DPDK and non-DPDK IVSHMEM devices), -a metadata file is also mapped into the IVSHMEM segment. -No work needs to be done by the guest application to map IVSHMEM devices into memory; -they are automatically recognized by the DPDK Environment Abstraction Layer (EAL). - -A typical DPDK IVSHMEM use case looks like the following. - - -.. figure:: img/ivshmem.* - - Typical Ivshmem use case - - -The same could work with several virtual machines, providing host-to-VM or VM-to-VM communication. -The maximum number of metadata files is 32 (by default) and each metadata file can contain different (or even the same) hugepages. -The only constraint is that each VM has to have access to the memory it is sharing with other entities (be it host or another VM). -For example, if the user wants to share the same memzone across two VMs, each VM must have that memzone in its metadata file. - -IVHSHMEM Library API Overview ------------------------------ - -The following is a simple guide to using the IVSHMEM Library API: - -* Call rte_ivshmem_metadata_create() to create a new metadata file. - The metadata name is used to distinguish between multiple metadata files. - -* Populate each metadata file with DPDK data structures. - This can be done using the following API calls: - - * rte_ivhshmem_metadata_add_memzone() to add rte_memzone to metadata file - - * rte_ivshmem_metadata_add_ring() to add rte_ring to metadata file - - * rte_ivshmem_metadata_add_mempool() to add rte_mempool to metadata file - -* Finally, call rte_ivshmem_metadata_cmdline_generate() to generate the command line for QEMU. - Multiple metadata files (and thus multiple command lines) can be supplied to a single VM. - -.. note:: - - Only data structures fully residing in DPDK hugepage memory work correctly. - Supported data structures created by malloc(), mmap() - or otherwise using non-DPDK memory cause undefined behavior and even a segmentation fault. - Specifically, because the memzone field in an rte_ring refers to a memzone structure residing in local memory, - accessing the memzone field in a shared rte_ring will cause an immediate segmentation fault. - -IVSHMEM Environment Configuration ---------------------------------- - -The steps needed to successfully run IVSHMEM applications are the following: - -* Compile a special version of QEMU from sources. - - The source code can be found on the QEMU website (currently, version 1.4.x is supported, but version 1.5.x is known to work also), - however, the source code will need to be patched to support using regular files as the IVSHMEM memory backend. - The patch is not included in the DPDK package, - but is available on the `Intel®DPDK-vswitch project webpage `_ - (either separately or in a DPDK vSwitch package). - -* Enable IVSHMEM library in the DPDK build configuration. - - In the default configuration, IVSHMEM library is not compiled. To compile the IVSHMEM library, - one has to either use one of the provided IVSHMEM targets - (for example, x86_64-ivshmem-linuxapp-gcc), - or set CONFIG_RTE_LIBRTE_IVSHMEM to "y" in the build configuration. - -* Set up hugepage memory on the virtual machine. - - The guest applications run as regular DPDK (primary) processes and thus need their own hugepage memory set up inside the VM. - The process is identical to the one described in the *DPDK Getting Started Guide*. - -Best Practices for Writing IVSHMEM Applications ------------------------------------------------ - -When considering the use of IVSHMEM for sharing memory, security implications need to be carefully evaluated. -IVSHMEM is not suitable for untrusted guests, as IVSHMEM is essentially a window into the host process memory. -This also has implications for the multiple VM scenarios. -While the IVSHMEM library tries to share as little memory as possible, -it is quite probable that data designated for one VM might also be present in an IVSMHMEM device designated for another VM. -Consequently, any shared memory corruption will affect both host and all VMs sharing that particular memory. - -IVSHMEM applications essentially behave like multi-process applications, -so it is important to implement access serialization to data and thread safety. -DPDK ring structures are already thread-safe, however, -any custom data structures that the user might need would have to be thread-safe also. - -Similar to regular DPDK multi-process applications, -it is not recommended to use function pointers as functions might have different memory addresses in different processes. - -It is best to avoid freeing the rte_mbuf structure on a different machine from where it was allocated, -that is, if the mbuf was allocated on the host, the host should free it. -Consequently, any packet transmission and reception should also happen on the same machine (whether virtual or physical). -Failing to do so may lead to data corruption in the mempool cache. - -Despite the IVSHMEM mechanism being zero-copy and having good performance, -it is still desirable to do processing in batches and follow other procedures described in -:ref:`Performance Optimization `. - -Best Practices for Running IVSHMEM Applications ------------------------------------------------ - -For performance reasons, -it is best to pin host processes and QEMU processes to different cores so that they do not interfere with each other. -If NUMA support is enabled, it is also desirable to keep host process' hugepage memory and QEMU process on the same NUMA node. - -For the best performance across all NUMA nodes, each QEMU core should be pinned to host CPU core on the appropriate NUMA node. -QEMU's virtual NUMA nodes should also be set up to correspond to physical NUMA nodes. -More on how to set up DPDK and QEMU NUMA support can be found in *DPDK Getting Started Guide* and -`QEMU documentation `_ respectively. -A script called cpu_layout.py is provided with the DPDK package (in the tools directory) -that can be used to identify which CPU cores correspond to which NUMA node. - -The QEMU IVSHMEM command line creation should be considered the last step before starting the virtual machine. -Currently, there is no hot plug support for QEMU IVSHMEM devices, -so one cannot add additional memory to an IVSHMEM device once it has been created. -Therefore, the correct sequence to run an IVSHMEM application is to run host application first, -obtain the command lines for each IVSHMEM device and then run all QEMU instances with guest applications afterwards. - -It is important to note that once QEMU is started, it holds on to the hugepages it uses for IVSHMEM devices. -As a result, if the user wishes to shut down or restart the IVSHMEM host application, -it is not enough to simply shut the application down. -The virtual machine must also be shut down (if not, it will hold onto outdated host data). diff --git a/doc/guides/prog_guide/source_org.rst b/doc/guides/prog_guide/source_org.rst index 0c06d47bb4..d9c140f704 100644 --- a/doc/guides/prog_guide/source_org.rst +++ b/doc/guides/prog_guide/source_org.rst @@ -70,7 +70,6 @@ The lib directory contains:: +-- librte_ether # Generic interface to poll mode driver +-- librte_hash # Hash library +-- librte_ip_frag # IP fragmentation library - +-- librte_ivshmem # QEMU IVSHMEM library +-- librte_kni # Kernel NIC interface +-- librte_kvargs # Argument parsing library +-- librte_lpm # Longest prefix match library diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst index 96db66158a..845d2aa188 100644 --- a/doc/guides/rel_notes/deprecation.rst +++ b/doc/guides/rel_notes/deprecation.rst @@ -50,9 +50,6 @@ Deprecation Notices and will be removed in 17.02. It is replaced by ``rte_mempool_generic_get/put`` functions. -* The ``rte_ivshmem`` feature (including library and EAL code) will be removed - in 16.11 because it has some design issues which are not planned to be fixed. - * The vhost-cuse will be removed in 16.11. Since v2.1, a large majority of development effort has gone to vhost-user, such as multiple-queue, live migration, reconnect etc. Therefore, vhost-user should be used instead. diff --git a/doc/guides/rel_notes/release_16_11.rst b/doc/guides/rel_notes/release_16_11.rst index 0b9022dfd9..66916afd07 100644 --- a/doc/guides/rel_notes/release_16_11.rst +++ b/doc/guides/rel_notes/release_16_11.rst @@ -96,6 +96,9 @@ API Changes * The log history is removed. +* The ``rte_ivshmem`` feature (including library and EAL code) has been removed + in 16.11 because it had some design issues which were not planned to be fixed. + ABI Changes ----------- @@ -136,7 +139,6 @@ The libraries prepended with a plus sign were incremented in this version. + librte_eal.so.3 librte_hash.so.2 librte_ip_frag.so.1 - librte_ivshmem.so.1 librte_jobstats.so.1 librte_kni.so.2 librte_kvargs.so.1 diff --git a/examples/Makefile b/examples/Makefile index 18b41b90ed..d49c7f29a0 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -61,7 +61,6 @@ ifneq ($(PQOS_INSTALL_PATH),) DIRS-y += l2fwd-cat endif DIRS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += l2fwd-crypto -DIRS-$(CONFIG_RTE_LIBRTE_IVSHMEM) += l2fwd-ivshmem DIRS-$(CONFIG_RTE_LIBRTE_JOBSTATS) += l2fwd-jobstats DIRS-y += l2fwd-keepalive DIRS-y += l2fwd-keepalive/ka-agent diff --git a/examples/l2fwd-ivshmem/Makefile b/examples/l2fwd-ivshmem/Makefile deleted file mode 100644 index 5f1d172892..0000000000 --- a/examples/l2fwd-ivshmem/Makefile +++ /dev/null @@ -1,43 +0,0 @@ -# BSD LICENSE -# -# Copyright(c) 2010-2014 Intel Corporation. All rights reserved. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Intel Corporation nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -ifeq ($(RTE_SDK),) -$(error "Please define RTE_SDK environment variable") -endif - -# Default target, can be overriden by command line or environment -RTE_TARGET ?= x86_64-ivshmem-linuxapp-gcc - -include $(RTE_SDK)/mk/rte.vars.mk - -DIRS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += host guest - -include $(RTE_SDK)/mk/rte.extsubdir.mk diff --git a/examples/l2fwd-ivshmem/guest/Makefile b/examples/l2fwd-ivshmem/guest/Makefile deleted file mode 100644 index 3ca73b432a..0000000000 --- a/examples/l2fwd-ivshmem/guest/Makefile +++ /dev/null @@ -1,50 +0,0 @@ -# BSD LICENSE -# -# Copyright(c) 2010-2014 Intel Corporation. All rights reserved. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Intel Corporation nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -ifeq ($(RTE_SDK),) -$(error "Please define RTE_SDK environment variable") -endif - -# Default target, can be overriden by command line or environment -RTE_TARGET ?= x86_64-ivshmem-linuxapp-gcc - -include $(RTE_SDK)/mk/rte.vars.mk - -# binary name -APP = guest - -# all source are stored in SRCS-y -SRCS-y := guest.c - -CFLAGS += -O3 -CFLAGS += $(WERROR_FLAGS) - -include $(RTE_SDK)/mk/rte.extapp.mk diff --git a/examples/l2fwd-ivshmem/guest/guest.c b/examples/l2fwd-ivshmem/guest/guest.c deleted file mode 100644 index 7c49521b2b..0000000000 --- a/examples/l2fwd-ivshmem/guest/guest.c +++ /dev/null @@ -1,452 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "../include/common.h" - -#define MAX_RX_QUEUE_PER_LCORE 16 -#define MAX_TX_QUEUE_PER_PORT 16 -struct lcore_queue_conf { - unsigned n_rx_port; - unsigned rx_port_list[MAX_RX_QUEUE_PER_LCORE]; - struct mbuf_table rx_mbufs[RTE_MAX_ETHPORTS]; - struct vm_port_param * port_param[MAX_RX_QUEUE_PER_LCORE]; -} __rte_cache_aligned; -static struct lcore_queue_conf lcore_queue_conf[RTE_MAX_LCORE]; - -/* Print out statistics on packets dropped */ -static void -print_stats(void) -{ - uint64_t total_packets_dropped, total_packets_tx, total_packets_rx; - unsigned portid; - - total_packets_dropped = 0; - total_packets_tx = 0; - total_packets_rx = 0; - - const char clr[] = { 27, '[', '2', 'J', '\0' }; - const char topLeft[] = { 27, '[', '1', ';', '1', 'H','\0' }; - - /* Clear screen and move to top left */ - printf("%s%s", clr, topLeft); - - printf("\nPort statistics ===================================="); - - for (portid = 0; portid < ctrl->nb_ports; portid++) { - /* skip ports that are not enabled */ - printf("\nStatistics for port %u ------------------------------" - "\nPackets sent: %24"PRIu64 - "\nPackets received: %20"PRIu64 - "\nPackets dropped: %21"PRIu64, - portid, - ctrl->vm_ports[portid].stats.tx, - ctrl->vm_ports[portid].stats.rx, - ctrl->vm_ports[portid].stats.dropped); - - total_packets_dropped += ctrl->vm_ports[portid].stats.dropped; - total_packets_tx += ctrl->vm_ports[portid].stats.tx; - total_packets_rx += ctrl->vm_ports[portid].stats.rx; - } - printf("\nAggregate statistics ===============================" - "\nTotal packets sent: %18"PRIu64 - "\nTotal packets received: %14"PRIu64 - "\nTotal packets dropped: %15"PRIu64, - total_packets_tx, - total_packets_rx, - total_packets_dropped); - printf("\n====================================================\n"); -} - -/* display usage */ -static void -l2fwd_ivshmem_usage(const char *prgname) -{ - printf("%s [EAL options] -- [-q NQ -T PERIOD]\n" - " -q NQ: number of queue (=ports) per lcore (default is 1)\n" - " -T PERIOD: statistics will be refreshed each PERIOD seconds (0 to disable, 10 default, 86400 maximum)\n", - prgname); -} - -static unsigned int -l2fwd_ivshmem_parse_nqueue(const char *q_arg) -{ - char *end = NULL; - unsigned long n; - - /* parse hexadecimal string */ - n = strtoul(q_arg, &end, 10); - if ((q_arg[0] == '\0') || (end == NULL) || (*end != '\0')) - return 0; - if (n == 0) - return 0; - if (n >= MAX_RX_QUEUE_PER_LCORE) - return 0; - - return n; -} - -static int -l2fwd_ivshmem_parse_timer_period(const char *q_arg) -{ - char *end = NULL; - int n; - - /* parse number string */ - n = strtol(q_arg, &end, 10); - if ((q_arg[0] == '\0') || (end == NULL) || (*end != '\0')) - return -1; - if (n >= MAX_TIMER_PERIOD) - return -1; - - return n; -} - -/* Parse the argument given in the command line of the application */ -static int -l2fwd_ivshmem_parse_args(int argc, char **argv) -{ - int opt, ret; - char **argvopt; - int option_index; - char *prgname = argv[0]; - static struct option lgopts[] = { - {NULL, 0, 0, 0} - }; - - argvopt = argv; - - while ((opt = getopt_long(argc, argvopt, "q:p:T:", - lgopts, &option_index)) != EOF) { - - switch (opt) { - - /* nqueue */ - case 'q': - l2fwd_ivshmem_rx_queue_per_lcore = l2fwd_ivshmem_parse_nqueue(optarg); - if (l2fwd_ivshmem_rx_queue_per_lcore == 0) { - printf("invalid queue number\n"); - l2fwd_ivshmem_usage(prgname); - return -1; - } - break; - - /* timer period */ - case 'T': - timer_period = l2fwd_ivshmem_parse_timer_period(optarg) * 1000 * TIMER_MILLISECOND; - if (timer_period < 0) { - printf("invalid timer period\n"); - l2fwd_ivshmem_usage(prgname); - return -1; - } - break; - - /* long options */ - case 0: - l2fwd_ivshmem_usage(prgname); - return -1; - - default: - l2fwd_ivshmem_usage(prgname); - return -1; - } - } - - if (optind >= 0) - argv[optind-1] = prgname; - - ret = optind-1; - optind = 0; /* reset getopt lib */ - return ret; -} - -/* - * this loop is getting packets from RX rings of each port, and puts them - * into TX rings of destination ports. - */ -static void -fwd_loop(void) -{ - - struct rte_mbuf *pkts_burst[MAX_PKT_BURST]; - struct rte_mbuf **m_table; - struct rte_mbuf *m; - struct rte_ring *rx, *tx; - unsigned lcore_id, len; - uint64_t prev_tsc, diff_tsc, cur_tsc, timer_tsc; - unsigned i, j, portid, nb_rx; - struct lcore_queue_conf *qconf; - struct ether_hdr *eth; - void *tmp; - - prev_tsc = 0; - timer_tsc = 0; - - lcore_id = rte_lcore_id(); - qconf = &lcore_queue_conf[lcore_id]; - - if (qconf->n_rx_port == 0) { - RTE_LOG(INFO, L2FWD_IVSHMEM, "lcore %u has nothing to do\n", lcore_id); - return; - } - - RTE_LOG(INFO, L2FWD_IVSHMEM, "entering main loop on lcore %u\n", lcore_id); - - for (i = 0; i < qconf->n_rx_port; i++) { - portid = qconf->rx_port_list[i]; - RTE_LOG(INFO, L2FWD_IVSHMEM, " -- lcoreid=%u portid=%u\n", lcore_id, - portid); - } - - while (ctrl->state == STATE_FWD) { - cur_tsc = rte_rdtsc(); - - diff_tsc = cur_tsc - prev_tsc; - - /* - * Read packet from RX queues and send it to TX queues - */ - for (i = 0; i < qconf->n_rx_port; i++) { - - portid = qconf->rx_port_list[i]; - - len = qconf->rx_mbufs[portid].len; - - rx = ctrl->vm_ports[portid].rx_ring; - tx = ctrl->vm_ports[portid].dst->tx_ring; - - m_table = qconf->rx_mbufs[portid].m_table; - - /* if we have something in the queue, try and transmit it down */ - if (len != 0) { - - /* if we succeed in sending the packets down, mark queue as free */ - if (rte_ring_enqueue_bulk(tx, (void**) m_table, len) == 0) { - ctrl->vm_ports[portid].stats.tx += len; - qconf->rx_mbufs[portid].len = 0; - len = 0; - } - } - - nb_rx = rte_ring_count(rx); - - nb_rx = RTE_MIN(nb_rx, (unsigned) MAX_PKT_BURST); - - if (nb_rx == 0) - continue; - - /* if we can get packets into the m_table */ - if (nb_rx < (RTE_DIM(qconf->rx_mbufs[portid].m_table) - len)) { - - /* this situation cannot exist, so if we fail to dequeue, that - * means something went horribly wrong, hence the failure. */ - if (rte_ring_dequeue_bulk(rx, (void**) pkts_burst, nb_rx) < 0) { - ctrl->state = STATE_FAIL; - return; - } - - ctrl->vm_ports[portid].stats.rx += nb_rx; - - /* put packets into the queue */ - for (j = 0; j < nb_rx; j++) { - m = pkts_burst[j]; - - rte_prefetch0(rte_pktmbuf_mtod(m, void *)); - - m_table[len + j] = m; - - eth = rte_pktmbuf_mtod(m, struct ether_hdr *); - - /* 02:00:00:00:00:xx */ - tmp = ð->d_addr.addr_bytes[0]; - *((uint64_t *)tmp) = 0x000000000002 + ((uint64_t)portid << 40); - - /* src addr */ - ether_addr_copy(&ctrl->vm_ports[portid].dst->ethaddr, - ð->s_addr); - } - qconf->rx_mbufs[portid].len += nb_rx; - - } - - } - - /* if timer is enabled */ - if (timer_period > 0) { - - /* advance the timer */ - timer_tsc += diff_tsc; - - /* if timer has reached its timeout */ - if (unlikely(timer_tsc >= (uint64_t) timer_period)) { - - /* do this only on master core */ - if (lcore_id == rte_get_master_lcore()) { - print_stats(); - /* reset the timer */ - timer_tsc = 0; - } - } - } - - prev_tsc = cur_tsc; - } -} - -static int -l2fwd_ivshmem_launch_one_lcore(__attribute__((unused)) void *dummy) -{ - fwd_loop(); - return 0; -} - -int -main(int argc, char **argv) -{ - struct lcore_queue_conf *qconf; - const struct rte_memzone * mz; - int ret; - uint8_t portid; - unsigned rx_lcore_id, lcore_id; - - /* init EAL */ - ret = rte_eal_init(argc, argv); - if (ret < 0) - rte_exit(EXIT_FAILURE, "Invalid EAL arguments\n"); - argc -= ret; - argv += ret; - - /* parse application arguments (after the EAL ones) */ - ret = l2fwd_ivshmem_parse_args(argc, argv); - if (ret < 0) - rte_exit(EXIT_FAILURE, "Invalid l2fwd-ivshmem arguments\n"); - - /* find control structure */ - mz = rte_memzone_lookup(CTRL_MZ_NAME); - if (mz == NULL) - rte_exit(EXIT_FAILURE, "Cannot find control memzone\n"); - - ctrl = (struct ivshmem_ctrl*) mz->addr; - - /* lock the ctrl so that we don't have conflicts with anything else */ - rte_spinlock_lock(&ctrl->lock); - - if (ctrl->state == STATE_FWD) - rte_exit(EXIT_FAILURE, "Forwarding already started!\n"); - - rx_lcore_id = 0; - qconf = NULL; - - /* Initialize the port/queue configuration of each logical core */ - for (portid = 0; portid < ctrl->nb_ports; portid++) { - - /* get the lcore_id for this port */ - while (rte_lcore_is_enabled(rx_lcore_id) == 0 || - lcore_queue_conf[rx_lcore_id].n_rx_port == - l2fwd_ivshmem_rx_queue_per_lcore) { - rx_lcore_id++; - if (rx_lcore_id >= RTE_MAX_LCORE) - rte_exit(EXIT_FAILURE, "Not enough cores\n"); - } - - if (qconf != &lcore_queue_conf[rx_lcore_id]) - /* Assigned a new logical core in the loop above. */ - qconf = &lcore_queue_conf[rx_lcore_id]; - - qconf->rx_port_list[qconf->n_rx_port] = portid; - qconf->port_param[qconf->n_rx_port] = &ctrl->vm_ports[portid]; - qconf->n_rx_port++; - - printf("Lcore %u: RX port %u\n", rx_lcore_id, (unsigned) portid); - } - - sigsetup(); - - /* indicate that we are ready to forward */ - ctrl->state = STATE_FWD; - - /* unlock */ - rte_spinlock_unlock(&ctrl->lock); - - /* launch per-lcore init on every lcore */ - rte_eal_mp_remote_launch(l2fwd_ivshmem_launch_one_lcore, NULL, CALL_MASTER); - RTE_LCORE_FOREACH_SLAVE(lcore_id) { - if (rte_eal_wait_lcore(lcore_id) < 0) - return -1; - } - - return 0; -} diff --git a/examples/l2fwd-ivshmem/host/Makefile b/examples/l2fwd-ivshmem/host/Makefile deleted file mode 100644 index f91419e984..0000000000 --- a/examples/l2fwd-ivshmem/host/Makefile +++ /dev/null @@ -1,50 +0,0 @@ -# BSD LICENSE -# -# Copyright(c) 2010-2014 Intel Corporation. All rights reserved. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Intel Corporation nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -ifeq ($(RTE_SDK),) -$(error "Please define RTE_SDK environment variable") -endif - -# Default target, can be overriden by command line or environment -RTE_TARGET ?= x86_64-ivshmem-linuxapp-gcc - -include $(RTE_SDK)/mk/rte.vars.mk - -# binary name -APP = host - -# all source are stored in SRCS-y -SRCS-y := host.c - -CFLAGS += -O3 -CFLAGS += $(WERROR_FLAGS) - -include $(RTE_SDK)/mk/rte.extapp.mk diff --git a/examples/l2fwd-ivshmem/host/host.c b/examples/l2fwd-ivshmem/host/host.c deleted file mode 100644 index da7b00d9fc..0000000000 --- a/examples/l2fwd-ivshmem/host/host.c +++ /dev/null @@ -1,895 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "../include/common.h" - -/* - * Configurable number of RX/TX ring descriptors - */ -#define RTE_TEST_RX_DESC_DEFAULT 128 -#define RTE_TEST_TX_DESC_DEFAULT 512 -static uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT; -static uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT; - -#define BURST_TX_DRAIN_US 100 /* TX drain every ~100us */ - -/* mask of enabled ports */ -static uint32_t l2fwd_ivshmem_enabled_port_mask = 0; - -static struct ether_addr l2fwd_ivshmem_ports_eth_addr[RTE_MAX_ETHPORTS]; - -#define NB_MBUF 8192 - -#define MAX_RX_QUEUE_PER_LCORE 16 -#define MAX_TX_QUEUE_PER_PORT 16 -struct lcore_queue_conf { - unsigned n_rx_port; - unsigned rx_port_list[MAX_RX_QUEUE_PER_LCORE]; - struct vm_port_param * port_param[MAX_RX_QUEUE_PER_LCORE]; - struct mbuf_table tx_mbufs[RTE_MAX_ETHPORTS]; - struct mbuf_table rx_mbufs[RTE_MAX_ETHPORTS]; -} __rte_cache_aligned; -static struct lcore_queue_conf lcore_queue_conf[RTE_MAX_LCORE]; - -static const struct rte_eth_conf port_conf = { - .rxmode = { - .split_hdr_size = 0, - .header_split = 0, /**< Header Split disabled */ - .hw_ip_checksum = 0, /**< IP checksum offload disabled */ - .hw_vlan_filter = 0, /**< VLAN filtering disabled */ - .jumbo_frame = 0, /**< Jumbo Frame Support disabled */ - .hw_strip_crc = 0, /**< CRC stripped by hardware */ - }, - .txmode = { - .mq_mode = ETH_MQ_TX_NONE, - }, -}; - -#define METADATA_NAME "l2fwd_ivshmem" -#define CMDLINE_OPT_FWD_CONF "fwd-conf" - -#define QEMU_CMD_FMT "/tmp/ivshmem_qemu_cmdline_%s" - -struct port_statistics port_statistics[RTE_MAX_ETHPORTS]; - -struct rte_mempool * l2fwd_ivshmem_pktmbuf_pool = NULL; - -/* Print out statistics on packets dropped */ -static void -print_stats(void) -{ - uint64_t total_packets_dropped, total_packets_tx, total_packets_rx; - uint64_t total_vm_packets_dropped = 0; - uint64_t total_vm_packets_tx, total_vm_packets_rx; - unsigned portid; - - total_packets_dropped = 0; - total_packets_tx = 0; - total_packets_rx = 0; - total_vm_packets_tx = 0; - total_vm_packets_rx = 0; - - const char clr[] = { 27, '[', '2', 'J', '\0' }; - const char topLeft[] = { 27, '[', '1', ';', '1', 'H','\0' }; - - /* Clear screen and move to top left */ - printf("%s%s", clr, topLeft); - - printf("\nPort statistics ===================================="); - - for (portid = 0; portid < RTE_MAX_ETHPORTS; portid++) { - /* skip disabled ports */ - if ((l2fwd_ivshmem_enabled_port_mask & (1 << portid)) == 0) - continue; - printf("\nStatistics for port %u ------------------------------" - "\nPackets sent: %24"PRIu64 - "\nPackets received: %20"PRIu64 - "\nPackets dropped: %21"PRIu64, - portid, - port_statistics[portid].tx, - port_statistics[portid].rx, - port_statistics[portid].dropped); - - total_packets_dropped += port_statistics[portid].dropped; - total_packets_tx += port_statistics[portid].tx; - total_packets_rx += port_statistics[portid].rx; - } - - printf("\nVM statistics ======================================"); - for (portid = 0; portid < ctrl->nb_ports; portid++) { - printf("\nStatistics for port %u ------------------------------" - "\nPackets sent: %24"PRIu64 - "\nPackets received: %20"PRIu64, - portid, - ctrl->vm_ports[portid].stats.tx, - ctrl->vm_ports[portid].stats.rx); - - total_vm_packets_dropped += ctrl->vm_ports[portid].stats.dropped; - total_vm_packets_tx += ctrl->vm_ports[portid].stats.tx; - total_vm_packets_rx += ctrl->vm_ports[portid].stats.rx; - } - printf("\nAggregate statistics ===============================" - "\nTotal packets sent: %18"PRIu64 - "\nTotal packets received: %14"PRIu64 - "\nTotal packets dropped: %15"PRIu64 - "\nTotal VM packets sent: %15"PRIu64 - "\nTotal VM packets received: %11"PRIu64, - total_packets_tx, - total_packets_rx, - total_packets_dropped, - total_vm_packets_tx, - total_vm_packets_rx); - printf("\n====================================================\n"); -} - -static int -print_to_file(const char *cmdline, const char *config_name) -{ - FILE *file; - char path[PATH_MAX]; - - snprintf(path, sizeof(path), QEMU_CMD_FMT, config_name); - file = fopen(path, "w"); - if (file == NULL) { - RTE_LOG(ERR, L2FWD_IVSHMEM, "Could not open '%s' \n", path); - return -1; - } - - RTE_LOG(DEBUG, L2FWD_IVSHMEM, "QEMU command line for config '%s': %s \n", - config_name, cmdline); - - fprintf(file, "%s\n", cmdline); - fclose(file); - return 0; -} - -static int -generate_ivshmem_cmdline(const char *config_name) -{ - char cmdline[PATH_MAX]; - if (rte_ivshmem_metadata_cmdline_generate(cmdline, sizeof(cmdline), - config_name) < 0) - return -1; - - if (print_to_file(cmdline, config_name) < 0) - return -1; - - rte_ivshmem_metadata_dump(stdout, config_name); - return 0; -} - -/* display usage */ -static void -l2fwd_ivshmem_usage(const char *prgname) -{ - printf("%s [EAL options] -- -p PORTMASK [-q NQ -T PERIOD]\n" - " -p PORTMASK: hexadecimal bitmask of ports to configure\n" - " -q NQ: number of queue (=ports) per lcore (default is 1)\n" - " -T PERIOD: statistics will be refreshed each PERIOD seconds " - "(0 to disable, 10 default, 86400 maximum)\n", - prgname); -} - -static unsigned int -l2fwd_ivshmem_parse_nqueue(const char *q_arg) -{ - char *end = NULL; - unsigned long n; - - /* parse hexadecimal string */ - n = strtoul(q_arg, &end, 10); - if ((q_arg[0] == '\0') || (end == NULL) || (*end != '\0')) - return 0; - if (n == 0) - return 0; - if (n >= MAX_RX_QUEUE_PER_LCORE) - return 0; - - return n; -} - -static int -l2fwd_ivshmem_parse_portmask(const char *portmask) -{ - char *end = NULL; - unsigned long pm; - - /* parse hexadecimal string */ - pm = strtoul(portmask, &end, 16); - if ((portmask[0] == '\0') || (end == NULL) || (*end != '\0')) - return -1; - - if (pm == 0) - return -1; - - return pm; -} - -static int -l2fwd_ivshmem_parse_timer_period(const char *q_arg) -{ - char *end = NULL; - int n; - - /* parse number string */ - n = strtol(q_arg, &end, 10); - if ((q_arg[0] == '\0') || (end == NULL) || (*end != '\0')) - return -1; - if (n >= MAX_TIMER_PERIOD) - return -1; - - return n; -} - -/* Parse the argument given in the command line of the application */ -static int -l2fwd_ivshmem_parse_args(int argc, char **argv) -{ - int opt, ret; - char **argvopt; - int option_index; - char *prgname = argv[0]; - static struct option lgopts[] = { - {CMDLINE_OPT_FWD_CONF, 1, 0, 0}, - {NULL, 0, 0, 0} - }; - - argvopt = argv; - - while ((opt = getopt_long(argc, argvopt, "q:p:T:", - lgopts, &option_index)) != EOF) { - - switch (opt) { - /* portmask */ - case 'p': - l2fwd_ivshmem_enabled_port_mask = l2fwd_ivshmem_parse_portmask(optarg); - if (l2fwd_ivshmem_enabled_port_mask == 0) { - printf("invalid portmask\n"); - l2fwd_ivshmem_usage(prgname); - return -1; - } - break; - - /* nqueue */ - case 'q': - l2fwd_ivshmem_rx_queue_per_lcore = l2fwd_ivshmem_parse_nqueue(optarg); - if (l2fwd_ivshmem_rx_queue_per_lcore == 0) { - printf("invalid queue number\n"); - l2fwd_ivshmem_usage(prgname); - return -1; - } - break; - - /* timer period */ - case 'T': - timer_period = l2fwd_ivshmem_parse_timer_period(optarg) * 1000 * TIMER_MILLISECOND; - if (timer_period < 0) { - printf("invalid timer period\n"); - l2fwd_ivshmem_usage(prgname); - return -1; - } - break; - - /* long options */ - case 0: - l2fwd_ivshmem_usage(prgname); - return -1; - - default: - l2fwd_ivshmem_usage(prgname); - return -1; - } - } - - if (optind >= 0) - argv[optind-1] = prgname; - - ret = optind-1; - optind = 0; /* reset getopt lib */ - return ret; -} - -/* Check the link status of all ports in up to 9s, and print them finally */ -static void -check_all_ports_link_status(uint8_t port_num, uint32_t port_mask) -{ -#define CHECK_INTERVAL 100 /* 100ms */ -#define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */ - uint8_t portid, count, all_ports_up, print_flag = 0; - struct rte_eth_link link; - - printf("\nChecking link status"); - fflush(stdout); - for (count = 0; count <= MAX_CHECK_TIME; count++) { - all_ports_up = 1; - for (portid = 0; portid < port_num; portid++) { - if ((port_mask & (1 << portid)) == 0) - continue; - memset(&link, 0, sizeof(link)); - rte_eth_link_get_nowait(portid, &link); - /* print link status if flag set */ - if (print_flag == 1) { - if (link.link_status) - printf("Port %d Link Up - speed %u " - "Mbps - %s\n", (uint8_t)portid, - (unsigned)link.link_speed, - (link.link_duplex == ETH_LINK_FULL_DUPLEX) ? - ("full-duplex") : ("half-duplex\n")); - else - printf("Port %d Link Down\n", - (uint8_t)portid); - continue; - } - /* clear all_ports_up flag if any link down */ - if (link.link_status == ETH_LINK_DOWN) { - all_ports_up = 0; - break; - } - } - /* after finally printing all link status, get out */ - if (print_flag == 1) - break; - - if (all_ports_up == 0) { - printf("."); - fflush(stdout); - rte_delay_ms(CHECK_INTERVAL); - } - - /* set the print_flag if all ports up or timeout */ - if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) { - print_flag = 1; - printf("done\n"); - } - } -} - -/* Send the burst of packets on an output interface */ -static int -l2fwd_ivshmem_send_burst(struct lcore_queue_conf *qconf, unsigned n, uint8_t port) -{ - struct rte_mbuf **m_table; - unsigned ret; - unsigned queueid =0; - - m_table = (struct rte_mbuf **)qconf->tx_mbufs[port].m_table; - - ret = rte_eth_tx_burst(port, (uint16_t) queueid, m_table, (uint16_t) n); - port_statistics[port].tx += ret; - if (unlikely(ret < n)) { - port_statistics[port].dropped += (n - ret); - do { - rte_pktmbuf_free(m_table[ret]); - } while (++ret < n); - } - - return 0; -} - -/* Enqueue packets for TX and prepare them to be sent on the network */ -static int -l2fwd_ivshmem_send_packet(struct rte_mbuf *m, uint8_t port) -{ - unsigned lcore_id, len; - struct lcore_queue_conf *qconf; - - lcore_id = rte_lcore_id(); - - qconf = &lcore_queue_conf[lcore_id]; - len = qconf->tx_mbufs[port].len; - qconf->tx_mbufs[port].m_table[len] = m; - len++; - - /* enough pkts to be sent */ - if (unlikely(len == MAX_PKT_BURST)) { - l2fwd_ivshmem_send_burst(qconf, MAX_PKT_BURST, port); - len = 0; - } - - qconf->tx_mbufs[port].len = len; - return 0; -} - -static int -l2fwd_ivshmem_receive_burst(struct lcore_queue_conf *qconf, unsigned portid, - unsigned vm_port) -{ - struct rte_mbuf ** m; - struct rte_ring * rx; - unsigned len, pkt_idx; - - m = qconf->rx_mbufs[portid].m_table; - len = qconf->rx_mbufs[portid].len; - rx = qconf->port_param[vm_port]->rx_ring; - - /* if enqueueing failed, ring is probably full, so drop the packets */ - if (rte_ring_enqueue_bulk(rx, (void**) m, len) < 0) { - port_statistics[portid].dropped += len; - - pkt_idx = 0; - do { - rte_pktmbuf_free(m[pkt_idx]); - } while (++pkt_idx < len); - } - else - /* increment rx stats by however many packets we managed to receive */ - port_statistics[portid].rx += len; - - return 0; -} - -/* Enqueue packets for RX and prepare them to be sent to VM */ -static int -l2fwd_ivshmem_receive_packets(struct rte_mbuf ** m, unsigned n, unsigned portid, - unsigned vm_port) -{ - unsigned lcore_id, len, pkt_idx; - struct lcore_queue_conf *qconf; - - lcore_id = rte_lcore_id(); - - qconf = &lcore_queue_conf[lcore_id]; - - len = qconf->rx_mbufs[portid].len; - pkt_idx = 0; - - /* enqueue packets */ - while (pkt_idx < n && len < MAX_PKT_BURST * 2) { - qconf->rx_mbufs[portid].m_table[len++] = m[pkt_idx++]; - } - - /* increment queue len by however many packets we managed to receive */ - qconf->rx_mbufs[portid].len += pkt_idx; - - /* drop the unreceived packets */ - if (unlikely(pkt_idx < n)) { - port_statistics[portid].dropped += n - pkt_idx; - do { - rte_pktmbuf_free(m[pkt_idx]); - } while (++pkt_idx < n); - } - - /* drain the queue halfway through the maximum capacity */ - if (unlikely(qconf->rx_mbufs[portid].len >= MAX_PKT_BURST)) - l2fwd_ivshmem_receive_burst(qconf, portid, vm_port); - - return 0; -} - -/* loop for host forwarding mode. - * the data flow is as follows: - * 1) get packets from TX queue and send it out from a given port - * 2) RX packets from given port and enqueue them on RX ring - * 3) dequeue packets from TX ring and put them on TX queue for a given port - */ -static void -fwd_loop(void) -{ - struct rte_mbuf *pkts_burst[MAX_PKT_BURST * 2]; - struct rte_mbuf *m; - unsigned lcore_id; - uint64_t prev_tsc, diff_tsc, cur_tsc, timer_tsc; - unsigned i, j, portid, nb_rx; - struct lcore_queue_conf *qconf; - struct rte_ring *tx; - const uint64_t drain_tsc = (rte_get_tsc_hz() + US_PER_S - 1) / US_PER_S * BURST_TX_DRAIN_US; - - prev_tsc = 0; - timer_tsc = 0; - - lcore_id = rte_lcore_id(); - qconf = &lcore_queue_conf[lcore_id]; - - if (qconf->n_rx_port == 0) { - RTE_LOG(INFO, L2FWD_IVSHMEM, "lcore %u has nothing to do\n", lcore_id); - return; - } - - RTE_LOG(INFO, L2FWD_IVSHMEM, "entering main loop on lcore %u\n", lcore_id); - - for (i = 0; i < qconf->n_rx_port; i++) { - - portid = qconf->rx_port_list[i]; - RTE_LOG(INFO, L2FWD_IVSHMEM, " -- lcoreid=%u portid=%u\n", lcore_id, - portid); - } - - while (ctrl->state == STATE_FWD) { - - cur_tsc = rte_rdtsc(); - - /* - * Burst queue drain - */ - diff_tsc = cur_tsc - prev_tsc; - if (unlikely(diff_tsc > drain_tsc)) { - - /* - * TX - */ - for (portid = 0; portid < RTE_MAX_ETHPORTS; portid++) { - if (qconf->tx_mbufs[portid].len == 0) - continue; - l2fwd_ivshmem_send_burst(qconf, - qconf->tx_mbufs[portid].len, - (uint8_t) portid); - qconf->tx_mbufs[portid].len = 0; - } - - /* - * RX - */ - for (i = 0; i < qconf->n_rx_port; i++) { - portid = qconf->rx_port_list[i]; - if (qconf->rx_mbufs[portid].len == 0) - continue; - l2fwd_ivshmem_receive_burst(qconf, portid, i); - qconf->rx_mbufs[portid].len = 0; - } - - /* if timer is enabled */ - if (timer_period > 0) { - - /* advance the timer */ - timer_tsc += diff_tsc; - - /* if timer has reached its timeout */ - if (unlikely(timer_tsc >= (uint64_t) timer_period)) { - - /* do this only on master core */ - if (lcore_id == rte_get_master_lcore()) { - print_stats(); - /* reset the timer */ - timer_tsc = 0; - } - } - } - - prev_tsc = cur_tsc; - } - - /* - * packet RX and forwarding - */ - for (i = 0; i < qconf->n_rx_port; i++) { - - /* RX packets from port and put them on RX ring */ - portid = qconf->rx_port_list[i]; - nb_rx = rte_eth_rx_burst((uint8_t) portid, 0, - pkts_burst, MAX_PKT_BURST); - - if (nb_rx != 0) - l2fwd_ivshmem_receive_packets(pkts_burst, nb_rx, portid, i); - - /* dequeue packets from TX ring and send them to TX queue */ - tx = qconf->port_param[i]->tx_ring; - - nb_rx = rte_ring_count(tx); - - nb_rx = RTE_MIN(nb_rx, (unsigned) MAX_PKT_BURST); - - if (nb_rx == 0) - continue; - - /* should not happen */ - if (unlikely(rte_ring_dequeue_bulk(tx, (void**) pkts_burst, nb_rx) < 0)) { - ctrl->state = STATE_FAIL; - return; - } - - for (j = 0; j < nb_rx; j++) { - m = pkts_burst[j]; - l2fwd_ivshmem_send_packet(m, portid); - } - } - } -} - -static int -l2fwd_ivshmem_launch_one_lcore(__attribute__((unused)) void *dummy) -{ - fwd_loop(); - return 0; -} - -int main(int argc, char **argv) -{ - char name[RTE_RING_NAMESIZE]; - struct rte_ring *r; - struct lcore_queue_conf *qconf; - struct rte_eth_dev_info dev_info; - uint8_t portid, port_nr; - uint8_t nb_ports, nb_ports_available; - uint8_t nb_ports_in_mask; - int ret; - unsigned lcore_id, rx_lcore_id; - - /* init EAL */ - ret = rte_eal_init(argc, argv); - if (ret < 0) - rte_exit(EXIT_FAILURE, "Invalid EAL arguments\n"); - argc -= ret; - argv += ret; - - /* parse application arguments (after the EAL ones) */ - ret = l2fwd_ivshmem_parse_args(argc, argv); - if (ret < 0) - rte_exit(EXIT_FAILURE, "Invalid l2fwd-ivshmem arguments\n"); - - /* create a shared mbuf pool */ - l2fwd_ivshmem_pktmbuf_pool = - rte_pktmbuf_pool_create(MBUF_MP_NAME, NB_MBUF, 32, - 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id()); - if (l2fwd_ivshmem_pktmbuf_pool == NULL) - rte_exit(EXIT_FAILURE, "Cannot init mbuf pool\n"); - - nb_ports = rte_eth_dev_count(); - if (nb_ports == 0) - rte_exit(EXIT_FAILURE, "No Ethernet ports - bye\n"); - - /* - * reserve memzone to communicate with VMs - we cannot use rte_malloc here - * because while it is technically possible, it is a very bad idea to share - * the heap between two primary processes. - */ - ctrl_mz = rte_memzone_reserve(CTRL_MZ_NAME, sizeof(struct ivshmem_ctrl), - SOCKET_ID_ANY, 0); - if (ctrl_mz == NULL) - rte_exit(EXIT_FAILURE, "Cannot reserve control memzone\n"); - ctrl = (struct ivshmem_ctrl*) ctrl_mz->addr; - - memset(ctrl, 0, sizeof(struct ivshmem_ctrl)); - - /* - * Each port is assigned an output port. - */ - nb_ports_in_mask = 0; - for (portid = 0; portid < nb_ports; portid++) { - /* skip ports that are not enabled */ - if ((l2fwd_ivshmem_enabled_port_mask & (1 << portid)) == 0) - continue; - if (portid % 2) { - ctrl->vm_ports[nb_ports_in_mask].dst = &ctrl->vm_ports[nb_ports_in_mask-1]; - ctrl->vm_ports[nb_ports_in_mask-1].dst = &ctrl->vm_ports[nb_ports_in_mask]; - } - - nb_ports_in_mask++; - - rte_eth_dev_info_get(portid, &dev_info); - } - if (nb_ports_in_mask % 2) { - printf("Notice: odd number of ports in portmask.\n"); - ctrl->vm_ports[nb_ports_in_mask-1].dst = - &ctrl->vm_ports[nb_ports_in_mask-1]; - } - - rx_lcore_id = 0; - qconf = NULL; - - printf("Initializing ports configuration...\n"); - - nb_ports_available = nb_ports; - - /* Initialise each port */ - for (portid = 0; portid < nb_ports; portid++) { - - /* skip ports that are not enabled */ - if ((l2fwd_ivshmem_enabled_port_mask & (1 << portid)) == 0) { - printf("Skipping disabled port %u\n", (unsigned) portid); - nb_ports_available--; - continue; - } - - /* init port */ - printf("Initializing port %u... ", (unsigned) portid); - fflush(stdout); - ret = rte_eth_dev_configure(portid, 1, 1, &port_conf); - if (ret < 0) - rte_exit(EXIT_FAILURE, "Cannot configure device: err=%d, port=%u\n", - ret, (unsigned) portid); - - rte_eth_macaddr_get(portid,&l2fwd_ivshmem_ports_eth_addr[portid]); - - /* init one RX queue */ - fflush(stdout); - ret = rte_eth_rx_queue_setup(portid, 0, nb_rxd, - rte_eth_dev_socket_id(portid), - NULL, - l2fwd_ivshmem_pktmbuf_pool); - if (ret < 0) - rte_exit(EXIT_FAILURE, "rte_eth_rx_queue_setup:err=%d, port=%u\n", - ret, (unsigned) portid); - - /* init one TX queue on each port */ - fflush(stdout); - ret = rte_eth_tx_queue_setup(portid, 0, nb_txd, - rte_eth_dev_socket_id(portid), - NULL); - if (ret < 0) - rte_exit(EXIT_FAILURE, "rte_eth_tx_queue_setup:err=%d, port=%u\n", - ret, (unsigned) portid); - - /* Start device */ - ret = rte_eth_dev_start(portid); - if (ret < 0) - rte_exit(EXIT_FAILURE, "rte_eth_dev_start:err=%d, port=%u\n", - ret, (unsigned) portid); - - printf("done: \n"); - - rte_eth_promiscuous_enable(portid); - - printf("Port %u, MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n\n", - (unsigned) portid, - l2fwd_ivshmem_ports_eth_addr[portid].addr_bytes[0], - l2fwd_ivshmem_ports_eth_addr[portid].addr_bytes[1], - l2fwd_ivshmem_ports_eth_addr[portid].addr_bytes[2], - l2fwd_ivshmem_ports_eth_addr[portid].addr_bytes[3], - l2fwd_ivshmem_ports_eth_addr[portid].addr_bytes[4], - l2fwd_ivshmem_ports_eth_addr[portid].addr_bytes[5]); - - /* initialize port stats */ - memset(&port_statistics, 0, sizeof(port_statistics)); - } - - if (!nb_ports_available) { - rte_exit(EXIT_FAILURE, - "All available ports are disabled. Please set portmask.\n"); - } - port_nr = 0; - - /* Initialize the port/queue configuration of each logical core */ - for (portid = 0; portid < nb_ports; portid++) { - if ((l2fwd_ivshmem_enabled_port_mask & (1 << portid)) == 0) - continue; - - /* get the lcore_id for this port */ - while (rte_lcore_is_enabled(rx_lcore_id) == 0 || - lcore_queue_conf[rx_lcore_id].n_rx_port == - l2fwd_ivshmem_rx_queue_per_lcore) { - rx_lcore_id++; - if (rx_lcore_id >= RTE_MAX_LCORE) - rte_exit(EXIT_FAILURE, "Not enough cores\n"); - } - - if (qconf != &lcore_queue_conf[rx_lcore_id]) - /* Assigned a new logical core in the loop above. */ - qconf = &lcore_queue_conf[rx_lcore_id]; - - - rte_eth_macaddr_get(portid, &ctrl->vm_ports[port_nr].ethaddr); - - qconf->rx_port_list[qconf->n_rx_port] = portid; - qconf->port_param[qconf->n_rx_port] = &ctrl->vm_ports[port_nr]; - qconf->n_rx_port++; - port_nr++; - printf("Lcore %u: RX port %u\n", rx_lcore_id, (unsigned) portid); - } - - check_all_ports_link_status(nb_ports_available, l2fwd_ivshmem_enabled_port_mask); - - /* create rings for each VM port (several ports can be on the same VM). - * note that we store the pointers in ctrl - that way, they are the same - * and valid across all VMs because ctrl is also in DPDK memory */ - for (portid = 0; portid < nb_ports_available; portid++) { - - /* RX ring. SP/SC because it's only used by host and a single VM */ - snprintf(name, sizeof(name), "%s%i", RX_RING_PREFIX, portid); - r = rte_ring_create(name, NB_MBUF, - SOCKET_ID_ANY, RING_F_SP_ENQ | RING_F_SC_DEQ); - if (r == NULL) - rte_exit(EXIT_FAILURE, "Cannot create ring %s\n", name); - - ctrl->vm_ports[portid].rx_ring = r; - - /* TX ring. SP/SC because it's only used by host and a single VM */ - snprintf(name, sizeof(name), "%s%i", TX_RING_PREFIX, portid); - r = rte_ring_create(name, NB_MBUF, - SOCKET_ID_ANY, RING_F_SP_ENQ | RING_F_SC_DEQ); - if (r == NULL) - rte_exit(EXIT_FAILURE, "Cannot create ring %s\n", name); - - ctrl->vm_ports[portid].tx_ring = r; - } - - /* create metadata, output cmdline */ - if (rte_ivshmem_metadata_create(METADATA_NAME) < 0) - rte_exit(EXIT_FAILURE, "Cannot create IVSHMEM metadata\n"); - - if (rte_ivshmem_metadata_add_memzone(ctrl_mz, METADATA_NAME)) - rte_exit(EXIT_FAILURE, "Cannot add memzone to IVSHMEM metadata\n"); - - if (rte_ivshmem_metadata_add_mempool(l2fwd_ivshmem_pktmbuf_pool, METADATA_NAME)) - rte_exit(EXIT_FAILURE, "Cannot add mbuf mempool to IVSHMEM metadata\n"); - - for (portid = 0; portid < nb_ports_available; portid++) { - if (rte_ivshmem_metadata_add_ring(ctrl->vm_ports[portid].rx_ring, - METADATA_NAME) < 0) - rte_exit(EXIT_FAILURE, "Cannot add ring %s to IVSHMEM metadata\n", - ctrl->vm_ports[portid].rx_ring->name); - if (rte_ivshmem_metadata_add_ring(ctrl->vm_ports[portid].tx_ring, - METADATA_NAME) < 0) - rte_exit(EXIT_FAILURE, "Cannot add ring %s to IVSHMEM metadata\n", - ctrl->vm_ports[portid].tx_ring->name); - } - generate_ivshmem_cmdline(METADATA_NAME); - - ctrl->nb_ports = nb_ports_available; - - printf("Waiting for VM to initialize...\n"); - - /* wait for VM to initialize */ - while (ctrl->state != STATE_FWD) { - if (ctrl->state == STATE_FAIL) - rte_exit(EXIT_FAILURE, "VM reported failure\n"); - - sleep(1); - } - - printf("Done!\n"); - - sigsetup(); - - /* launch per-lcore init on every lcore */ - rte_eal_mp_remote_launch(l2fwd_ivshmem_launch_one_lcore, NULL, CALL_MASTER); - RTE_LCORE_FOREACH_SLAVE(lcore_id) { - if (rte_eal_wait_lcore(lcore_id) < 0) - return -1; - } - - if (ctrl->state == STATE_FAIL) - rte_exit(EXIT_FAILURE, "VM reported failure\n"); - - return 0; -} diff --git a/examples/l2fwd-ivshmem/include/common.h b/examples/l2fwd-ivshmem/include/common.h deleted file mode 100644 index 8564d32bf4..0000000000 --- a/examples/l2fwd-ivshmem/include/common.h +++ /dev/null @@ -1,111 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _IVSHMEM_COMMON_H_ -#define _IVSHMEM_COMMON_H_ - -#define RTE_LOGTYPE_L2FWD_IVSHMEM RTE_LOGTYPE_USER1 - -#define CTRL_MZ_NAME "CTRL_MEMZONE" -#define MBUF_MP_NAME "MBUF_MEMPOOL" -#define RX_RING_PREFIX "RX_" -#define TX_RING_PREFIX "TX_" - -/* A tsc-based timer responsible for triggering statistics printout */ -#define TIMER_MILLISECOND 2000000ULL /* around 1ms at 2 Ghz */ -#define MAX_TIMER_PERIOD 86400 /* 1 day max */ -static int64_t timer_period = 10 * TIMER_MILLISECOND * 1000; /* default period is 10 seconds */ - -#define DIM(x)\ - (sizeof(x)/sizeof(x)[0]) - -#define MAX_PKT_BURST 32 - -const struct rte_memzone * ctrl_mz; - -enum l2fwd_state { - STATE_NONE = 0, - STATE_FWD, - STATE_EXIT, - STATE_FAIL -}; - -/* Per-port statistics struct */ -struct port_statistics { - uint64_t tx; - uint64_t rx; - uint64_t dropped; -} __rte_cache_aligned; - -struct mbuf_table { - unsigned len; - struct rte_mbuf *m_table[MAX_PKT_BURST * 2]; /**< allow up to two bursts */ -}; - -struct vm_port_param { - struct rte_ring * rx_ring; /**< receiving ring for current port */ - struct rte_ring * tx_ring; /**< transmitting ring for current port */ - struct vm_port_param * dst; /**< current port's destination port */ - volatile struct port_statistics stats; /**< statistics for current port */ - struct ether_addr ethaddr; /**< Ethernet address of the port */ -}; - -/* control structure, to synchronize host and VM */ -struct ivshmem_ctrl { - rte_spinlock_t lock; - uint8_t nb_ports; /**< total nr of ports */ - volatile enum l2fwd_state state; /**< report state */ - struct vm_port_param vm_ports[RTE_MAX_ETHPORTS]; -}; - -struct ivshmem_ctrl * ctrl; - -static unsigned int l2fwd_ivshmem_rx_queue_per_lcore = 1; - -static void sighandler(int __rte_unused s) -{ - ctrl->state = STATE_EXIT; -} - -static void sigsetup(void) -{ - struct sigaction sigIntHandler; - - sigIntHandler.sa_handler = sighandler; - sigemptyset(&sigIntHandler.sa_mask); - sigIntHandler.sa_flags = 0; - - sigaction(SIGINT, &sigIntHandler, NULL); -} - -#endif /* _IVSHMEM_COMMON_H_ */ diff --git a/examples/packet_ordering/Makefile b/examples/packet_ordering/Makefile index 9e080a30cb..de066c4cc1 100644 --- a/examples/packet_ordering/Makefile +++ b/examples/packet_ordering/Makefile @@ -34,7 +34,7 @@ $(error "Please define RTE_SDK environment variable") endif # Default target, can be overridden by command line or environment -RTE_TARGET ?= x86_64-ivshmem-linuxapp-gcc +RTE_TARGET ?= x86_64-native-linuxapp-gcc include $(RTE_SDK)/mk/rte.vars.mk diff --git a/lib/Makefile b/lib/Makefile index ca7c02fd84..990f23a4a0 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -61,7 +61,6 @@ DIRS-$(CONFIG_RTE_LIBRTE_PDUMP) += librte_pdump ifeq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y) DIRS-$(CONFIG_RTE_LIBRTE_KNI) += librte_kni -DIRS-$(CONFIG_RTE_LIBRTE_IVSHMEM) += librte_ivshmem endif include $(RTE_SDK)/mk/rte.subdir.mk diff --git a/lib/librte_eal/common/eal_common_memzone.c b/lib/librte_eal/common/eal_common_memzone.c index 1bd0a33d1d..64f4e0ade4 100644 --- a/lib/librte_eal/common/eal_common_memzone.c +++ b/lib/librte_eal/common/eal_common_memzone.c @@ -337,19 +337,7 @@ rte_memzone_free(const struct rte_memzone *mz) idx = ((uintptr_t)mz - (uintptr_t)mcfg->memzone); idx = idx / sizeof(struct rte_memzone); -#ifdef RTE_LIBRTE_IVSHMEM - /* - * If ioremap_addr is set, it's an IVSHMEM memzone and we cannot - * free it. - */ - if (mcfg->memzone[idx].ioremap_addr != 0) { - rte_rwlock_write_unlock(&mcfg->mlock); - return -EINVAL; - } -#endif - addr = mcfg->memzone[idx].addr; - if (addr == NULL) ret = -EINVAL; else if (mcfg->memzone_cnt == 0) { diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h index 857dc3eaa4..0bda493e8a 100644 --- a/lib/librte_eal/common/eal_private.h +++ b/lib/librte_eal/common/eal_private.h @@ -126,28 +126,6 @@ int rte_eal_log_init(const char *id, int facility); */ int rte_eal_pci_init(void); -#ifdef RTE_LIBRTE_IVSHMEM -/** - * Init the memory from IVSHMEM devices - * - * This function is private to EAL. - * - * @return - * 0 on success, negative on error - */ -int rte_eal_ivshmem_init(void); - -/** - * Init objects in IVSHMEM devices - * - * This function is private to EAL. - * - * @return - * 0 on success, negative on error - */ -int rte_eal_ivshmem_obj_init(void); -#endif - struct rte_pci_driver; struct rte_pci_device; diff --git a/lib/librte_eal/common/include/rte_memory.h b/lib/librte_eal/common/include/rte_memory.h index 06611093f4..d9e8c21340 100644 --- a/lib/librte_eal/common/include/rte_memory.h +++ b/lib/librte_eal/common/include/rte_memory.h @@ -107,9 +107,6 @@ struct rte_memseg { void *addr; /**< Start virtual address. */ uint64_t addr_64; /**< Makes sure addr is always 64 bits */ }; -#ifdef RTE_LIBRTE_IVSHMEM - phys_addr_t ioremap_addr; /**< Real physical address inside the VM */ -#endif size_t len; /**< Length of the segment. */ uint64_t hugepage_sz; /**< The pagesize of underlying memory */ int32_t socket_id; /**< NUMA socket ID. */ diff --git a/lib/librte_eal/common/include/rte_memzone.h b/lib/librte_eal/common/include/rte_memzone.h index f69b5a87b9..dae98f5b0f 100644 --- a/lib/librte_eal/common/include/rte_memzone.h +++ b/lib/librte_eal/common/include/rte_memzone.h @@ -82,9 +82,6 @@ struct rte_memzone { void *addr; /**< Start virtual address. */ uint64_t addr_64; /**< Makes sure addr is always 64-bits */ }; -#ifdef RTE_LIBRTE_IVSHMEM - phys_addr_t ioremap_addr; /**< Real physical address inside the VM */ -#endif size_t len; /**< Length of the memzone. */ uint64_t hugepage_sz; /**< The page size of underlying memory */ @@ -256,12 +253,10 @@ const struct rte_memzone *rte_memzone_reserve_bounded(const char *name, /** * Free a memzone. * - * Note: an IVSHMEM zone cannot be freed. - * * @param mz * A pointer to the memzone * @return - * -EINVAL - invalid parameter, IVSHMEM memzone. + * -EINVAL - invalid parameter. * 0 - success */ int rte_memzone_free(const struct rte_memzone *mz); diff --git a/lib/librte_eal/common/malloc_heap.c b/lib/librte_eal/common/malloc_heap.c index 763fa32445..267a4c6cd5 100644 --- a/lib/librte_eal/common/malloc_heap.c +++ b/lib/librte_eal/common/malloc_heap.c @@ -221,14 +221,6 @@ rte_eal_malloc_heap_init(void) for (ms = &mcfg->memseg[0], ms_cnt = 0; (ms_cnt < RTE_MAX_MEMSEG) && (ms->len > 0); ms_cnt++, ms++) { -#ifdef RTE_LIBRTE_IVSHMEM - /* - * if segment has ioremap address set, it's an IVSHMEM segment and - * it is not memory to allocate from. - */ - if (ms->ioremap_addr != 0) - continue; -#endif malloc_heap_add_memseg(&mcfg->malloc_heaps[ms->socket_id], ms); } diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile index 3a7631a71c..193957f1c5 100644 --- a/lib/librte_eal/linuxapp/eal/Makefile +++ b/lib/librte_eal/linuxapp/eal/Makefile @@ -44,12 +44,6 @@ VPATH += $(RTE_SDK)/lib/librte_eal/common CFLAGS += -I$(SRCDIR)/include CFLAGS += -I$(RTE_SDK)/lib/librte_eal/common CFLAGS += -I$(RTE_SDK)/lib/librte_eal/common/include -ifeq ($(CONFIG_RTE_LIBRTE_IVSHMEM),y) -# workaround for circular dependency eal -> ivshmem -> ring/mempool -> eal -CFLAGS += -I$(RTE_SDK)/lib/librte_ring -CFLAGS += -I$(RTE_SDK)/lib/librte_mempool -CFLAGS += -I$(RTE_SDK)/lib/librte_ivshmem -endif CFLAGS += $(WERROR_FLAGS) -O3 LDLIBS += -ldl @@ -76,9 +70,6 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_lcore.c SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_timer.c SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_interrupts.c SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_alarm.c -ifeq ($(CONFIG_RTE_LIBRTE_IVSHMEM),y) -SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_ivshmem.c -endif # from common dir SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_lcore.c diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c index 3fb2188ff6..d5b81a328d 100644 --- a/lib/librte_eal/linuxapp/eal/eal.c +++ b/lib/librte_eal/linuxapp/eal/eal.c @@ -797,11 +797,6 @@ rte_eal_init(int argc, char **argv) rte_panic("Cannot init VFIO\n"); #endif -#ifdef RTE_LIBRTE_IVSHMEM - if (rte_eal_ivshmem_init() < 0) - rte_panic("Cannot init IVSHMEM\n"); -#endif - if (rte_eal_memory_init() < 0) rte_panic("Cannot init memory\n"); @@ -814,11 +809,6 @@ rte_eal_init(int argc, char **argv) if (rte_eal_tailqs_init() < 0) rte_panic("Cannot init tail queues for objects\n"); -#ifdef RTE_LIBRTE_IVSHMEM - if (rte_eal_ivshmem_obj_init() < 0) - rte_panic("Cannot init IVSHMEM objects\n"); -#endif - if (rte_eal_log_init(logid, internal_config.syslog_facility) < 0) rte_panic("Cannot init logs\n"); diff --git a/lib/librte_eal/linuxapp/eal/eal_ivshmem.c b/lib/librte_eal/linuxapp/eal/eal_ivshmem.c deleted file mode 100644 index 67b3caf26c..0000000000 --- a/lib/librte_eal/linuxapp/eal/eal_ivshmem.c +++ /dev/null @@ -1,954 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifdef RTE_LIBRTE_IVSHMEM /* hide it from coverage */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "eal_internal_cfg.h" -#include "eal_private.h" - -#define PCI_VENDOR_ID_IVSHMEM 0x1Af4 -#define PCI_DEVICE_ID_IVSHMEM 0x1110 - -#define IVSHMEM_MAGIC 0x0BADC0DE - -#define IVSHMEM_RESOURCE_PATH "/sys/bus/pci/devices/%04x:%02x:%02x.%x/resource2" -#define IVSHMEM_CONFIG_PATH "/var/run/.%s_ivshmem_config" - -#define PHYS 0x1 -#define VIRT 0x2 -#define IOREMAP 0x4 -#define FULL (PHYS|VIRT|IOREMAP) - -#define METADATA_SIZE_ALIGNED \ - (RTE_ALIGN_CEIL(sizeof(struct rte_ivshmem_metadata),pagesz)) - -#define CONTAINS(x,y)\ - (((y).addr_64 >= (x).addr_64) && ((y).addr_64 < (x).addr_64 + (x).len)) - -#define DIM(x) (sizeof(x)/sizeof(x[0])) - -struct ivshmem_pci_device { - char path[PATH_MAX]; - phys_addr_t ioremap_addr; -}; - -/* data type to store in config */ -struct ivshmem_segment { - struct rte_ivshmem_metadata_entry entry; - uint64_t align; - char path[PATH_MAX]; -}; -struct ivshmem_shared_config { - struct ivshmem_segment segment[RTE_MAX_MEMSEG]; - uint32_t segment_idx; - struct ivshmem_pci_device pci_devs[RTE_LIBRTE_IVSHMEM_MAX_PCI_DEVS]; - uint32_t pci_devs_idx; -}; -static struct ivshmem_shared_config * ivshmem_config; -static int memseg_idx; -static int pagesz; - -/* Tailq heads to add rings to */ -TAILQ_HEAD(rte_ring_list, rte_tailq_entry); - -/* - * Utility functions - */ - -static int -is_ivshmem_device(struct rte_pci_device * dev) -{ - return dev->id.vendor_id == PCI_VENDOR_ID_IVSHMEM - && dev->id.device_id == PCI_DEVICE_ID_IVSHMEM; -} - -static void * -map_metadata(int fd, uint64_t len) -{ - size_t metadata_len = sizeof(struct rte_ivshmem_metadata); - size_t aligned_len = METADATA_SIZE_ALIGNED; - - return mmap(NULL, metadata_len, PROT_READ | PROT_WRITE, - MAP_SHARED, fd, len - aligned_len); -} - -static void -unmap_metadata(void * ptr) -{ - munmap(ptr, sizeof(struct rte_ivshmem_metadata)); -} - -static int -has_ivshmem_metadata(int fd, uint64_t len) -{ - struct rte_ivshmem_metadata metadata; - void * ptr; - - ptr = map_metadata(fd, len); - - if (ptr == MAP_FAILED) - return -1; - - metadata = *(struct rte_ivshmem_metadata*) (ptr); - - unmap_metadata(ptr); - - return metadata.magic_number == IVSHMEM_MAGIC; -} - -static void -remove_segment(struct ivshmem_segment * ms, int len, int idx) -{ - int i; - - for (i = idx; i < len - 1; i++) - memcpy(&ms[i], &ms[i+1], sizeof(struct ivshmem_segment)); - memset(&ms[len-1], 0, sizeof(struct ivshmem_segment)); -} - -static int -overlap(const struct rte_memzone * mz1, const struct rte_memzone * mz2) -{ - uint64_t start1, end1, start2, end2; - uint64_t p_start1, p_end1, p_start2, p_end2; - uint64_t i_start1, i_end1, i_start2, i_end2; - int result = 0; - - /* gather virtual addresses */ - start1 = mz1->addr_64; - end1 = mz1->addr_64 + mz1->len; - start2 = mz2->addr_64; - end2 = mz2->addr_64 + mz2->len; - - /* gather physical addresses */ - p_start1 = mz1->phys_addr; - p_end1 = mz1->phys_addr + mz1->len; - p_start2 = mz2->phys_addr; - p_end2 = mz2->phys_addr + mz2->len; - - /* gather ioremap addresses */ - i_start1 = mz1->ioremap_addr; - i_end1 = mz1->ioremap_addr + mz1->len; - i_start2 = mz2->ioremap_addr; - i_end2 = mz2->ioremap_addr + mz2->len; - - /* check for overlap in virtual addresses */ - if (start1 >= start2 && start1 < end2) - result |= VIRT; - if (start2 >= start1 && start2 < end1) - result |= VIRT; - - /* check for overlap in physical addresses */ - if (p_start1 >= p_start2 && p_start1 < p_end2) - result |= PHYS; - if (p_start2 >= p_start1 && p_start2 < p_end1) - result |= PHYS; - - /* check for overlap in ioremap addresses */ - if (i_start1 >= i_start2 && i_start1 < i_end2) - result |= IOREMAP; - if (i_start2 >= i_start1 && i_start2 < i_end1) - result |= IOREMAP; - - return result; -} - -static int -adjacent(const struct rte_memzone * mz1, const struct rte_memzone * mz2) -{ - uint64_t start1, end1, start2, end2; - uint64_t p_start1, p_end1, p_start2, p_end2; - uint64_t i_start1, i_end1, i_start2, i_end2; - int result = 0; - - /* gather virtual addresses */ - start1 = mz1->addr_64; - end1 = mz1->addr_64 + mz1->len; - start2 = mz2->addr_64; - end2 = mz2->addr_64 + mz2->len; - - /* gather physical addresses */ - p_start1 = mz1->phys_addr; - p_end1 = mz1->phys_addr + mz1->len; - p_start2 = mz2->phys_addr; - p_end2 = mz2->phys_addr + mz2->len; - - /* gather ioremap addresses */ - i_start1 = mz1->ioremap_addr; - i_end1 = mz1->ioremap_addr + mz1->len; - i_start2 = mz2->ioremap_addr; - i_end2 = mz2->ioremap_addr + mz2->len; - - /* check if segments are virtually adjacent */ - if (start1 == end2) - result |= VIRT; - if (start2 == end1) - result |= VIRT; - - /* check if segments are physically adjacent */ - if (p_start1 == p_end2) - result |= PHYS; - if (p_start2 == p_end1) - result |= PHYS; - - /* check if segments are ioremap-adjacent */ - if (i_start1 == i_end2) - result |= IOREMAP; - if (i_start2 == i_end1) - result |= IOREMAP; - - return result; -} - -static int -has_adjacent_segments(struct ivshmem_segment * ms, int len) -{ - int i, j; - - for (i = 0; i < len; i++) - for (j = i + 1; j < len; j++) { - /* we're only interested in fully adjacent segments; partially - * adjacent segments can coexist. - */ - if (adjacent(&ms[i].entry.mz, &ms[j].entry.mz) == FULL) - return 1; - } - return 0; -} - -static int -has_overlapping_segments(struct ivshmem_segment * ms, int len) -{ - int i, j; - - for (i = 0; i < len; i++) - for (j = i + 1; j < len; j++) - if (overlap(&ms[i].entry.mz, &ms[j].entry.mz)) - return 1; - return 0; -} - -static int -seg_compare(const void * a, const void * b) -{ - const struct ivshmem_segment * s1 = (const struct ivshmem_segment*) a; - const struct ivshmem_segment * s2 = (const struct ivshmem_segment*) b; - - /* move unallocated zones to the end */ - if (s1->entry.mz.addr == NULL && s2->entry.mz.addr == NULL) - return 0; - if (s1->entry.mz.addr == 0) - return 1; - if (s2->entry.mz.addr == 0) - return -1; - - return s1->entry.mz.phys_addr > s2->entry.mz.phys_addr; -} - -#ifdef RTE_LIBRTE_IVSHMEM_DEBUG -static void -entry_dump(struct rte_ivshmem_metadata_entry *e) -{ - RTE_LOG(DEBUG, EAL, "\tvirt: %p-%p\n", e->mz.addr, - RTE_PTR_ADD(e->mz.addr, e->mz.len)); - RTE_LOG(DEBUG, EAL, "\tphys: 0x%" PRIx64 "-0x%" PRIx64 "\n", - e->mz.phys_addr, - e->mz.phys_addr + e->mz.len); - RTE_LOG(DEBUG, EAL, "\tio: 0x%" PRIx64 "-0x%" PRIx64 "\n", - e->mz.ioremap_addr, - e->mz.ioremap_addr + e->mz.len); - RTE_LOG(DEBUG, EAL, "\tlen: 0x%" PRIx64 "\n", e->mz.len); - RTE_LOG(DEBUG, EAL, "\toff: 0x%" PRIx64 "\n", e->offset); -} -#endif - - - -/* - * Actual useful code - */ - -/* read through metadata mapped from the IVSHMEM device */ -static int -read_metadata(char * path, int path_len, int fd, uint64_t flen) -{ - struct rte_ivshmem_metadata metadata; - struct rte_ivshmem_metadata_entry * entry; - int idx, i; - void * ptr; - - ptr = map_metadata(fd, flen); - - if (ptr == MAP_FAILED) - return -1; - - metadata = *(struct rte_ivshmem_metadata*) (ptr); - - unmap_metadata(ptr); - - RTE_LOG(DEBUG, EAL, "Parsing metadata for \"%s\"\n", metadata.name); - - idx = ivshmem_config->segment_idx; - - for (i = 0; i < RTE_LIBRTE_IVSHMEM_MAX_ENTRIES && - idx <= RTE_MAX_MEMSEG; i++) { - - if (idx == RTE_MAX_MEMSEG) { - RTE_LOG(ERR, EAL, "Not enough memory segments!\n"); - return -1; - } - - entry = &metadata.entry[i]; - - /* stop on uninitialized memzone */ - if (entry->mz.len == 0) - break; - - /* copy metadata entry */ - memcpy(&ivshmem_config->segment[idx].entry, entry, - sizeof(struct rte_ivshmem_metadata_entry)); - - /* copy path */ - snprintf(ivshmem_config->segment[idx].path, path_len, "%s", path); - - idx++; - } - ivshmem_config->segment_idx = idx; - - return 0; -} - -/* check through each segment and look for adjacent or overlapping ones. */ -static int -cleanup_segments(struct ivshmem_segment * ms, int tbl_len) -{ - struct ivshmem_segment * s, * tmp; - int i, j, concat, seg_adjacent, seg_overlapping; - uint64_t start1, start2, end1, end2, p_start1, p_start2, i_start1, i_start2; - - qsort(ms, tbl_len, sizeof(struct ivshmem_segment), - seg_compare); - - while (has_overlapping_segments(ms, tbl_len) || - has_adjacent_segments(ms, tbl_len)) { - - for (i = 0; i < tbl_len; i++) { - s = &ms[i]; - - concat = 0; - - for (j = i + 1; j < tbl_len; j++) { - tmp = &ms[j]; - - /* check if this segment is overlapping with existing segment, - * or is adjacent to existing segment */ - seg_overlapping = overlap(&s->entry.mz, &tmp->entry.mz); - seg_adjacent = adjacent(&s->entry.mz, &tmp->entry.mz); - - /* check if segments fully overlap or are fully adjacent */ - if ((seg_adjacent == FULL) || (seg_overlapping == FULL)) { - -#ifdef RTE_LIBRTE_IVSHMEM_DEBUG - RTE_LOG(DEBUG, EAL, "Concatenating segments\n"); - RTE_LOG(DEBUG, EAL, "Segment %i:\n", i); - entry_dump(&s->entry); - RTE_LOG(DEBUG, EAL, "Segment %i:\n", j); - entry_dump(&tmp->entry); -#endif - - start1 = s->entry.mz.addr_64; - start2 = tmp->entry.mz.addr_64; - p_start1 = s->entry.mz.phys_addr; - p_start2 = tmp->entry.mz.phys_addr; - i_start1 = s->entry.mz.ioremap_addr; - i_start2 = tmp->entry.mz.ioremap_addr; - end1 = s->entry.mz.addr_64 + s->entry.mz.len; - end2 = tmp->entry.mz.addr_64 + tmp->entry.mz.len; - - /* settle for minimum start address and maximum length */ - s->entry.mz.addr_64 = RTE_MIN(start1, start2); - s->entry.mz.phys_addr = RTE_MIN(p_start1, p_start2); - s->entry.mz.ioremap_addr = RTE_MIN(i_start1, i_start2); - s->entry.offset = RTE_MIN(s->entry.offset, tmp->entry.offset); - s->entry.mz.len = RTE_MAX(end1, end2) - s->entry.mz.addr_64; - concat = 1; - -#ifdef RTE_LIBRTE_IVSHMEM_DEBUG - RTE_LOG(DEBUG, EAL, "Resulting segment:\n"); - entry_dump(&s->entry); - -#endif - } - /* if segments not fully overlap, we have an error condition. - * adjacent segments can coexist. - */ - else if (seg_overlapping > 0) { - RTE_LOG(ERR, EAL, "Segments %i and %i overlap!\n", i, j); -#ifdef RTE_LIBRTE_IVSHMEM_DEBUG - RTE_LOG(DEBUG, EAL, "Segment %i:\n", i); - entry_dump(&s->entry); - RTE_LOG(DEBUG, EAL, "Segment %i:\n", j); - entry_dump(&tmp->entry); -#endif - return -1; - } - if (concat) - break; - } - /* if we concatenated, remove segment at j */ - if (concat) { - remove_segment(ms, tbl_len, j); - tbl_len--; - break; - } - } - } - - return tbl_len; -} - -static int -create_shared_config(void) -{ - char path[PATH_MAX]; - int fd; - - /* build ivshmem config file path */ - snprintf(path, sizeof(path), IVSHMEM_CONFIG_PATH, - internal_config.hugefile_prefix); - - fd = open(path, O_CREAT | O_RDWR, 0600); - - if (fd < 0) { - RTE_LOG(ERR, EAL, "Could not open %s: %s\n", path, strerror(errno)); - return -1; - } - - /* try ex-locking first - if the file is locked, we have a problem */ - if (flock(fd, LOCK_EX | LOCK_NB) == -1) { - RTE_LOG(ERR, EAL, "Locking %s failed: %s\n", path, strerror(errno)); - close(fd); - return -1; - } - - if (ftruncate(fd, sizeof(struct ivshmem_shared_config)) < 0) { - RTE_LOG(ERR, EAL, "ftruncate failed: %s\n", strerror(errno)); - return -1; - } - - ivshmem_config = mmap(NULL, sizeof(struct ivshmem_shared_config), - PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - - if (ivshmem_config == MAP_FAILED) - return -1; - - memset(ivshmem_config, 0, sizeof(struct ivshmem_shared_config)); - - /* change the exclusive lock we got earlier to a shared lock */ - if (flock(fd, LOCK_SH | LOCK_NB) == -1) { - RTE_LOG(ERR, EAL, "Locking %s failed: %s \n", path, strerror(errno)); - return -1; - } - - close(fd); - - return 0; -} - -/* open shared config file and, if present, map the config. - * having no config file is not an error condition, as we later check if - * ivshmem_config is NULL (if it is, that means nothing was mapped). */ -static int -open_shared_config(void) -{ - char path[PATH_MAX]; - int fd; - - /* build ivshmem config file path */ - snprintf(path, sizeof(path), IVSHMEM_CONFIG_PATH, - internal_config.hugefile_prefix); - - fd = open(path, O_RDONLY); - - /* if the file doesn't exist, just return success */ - if (fd < 0 && errno == ENOENT) - return 0; - /* else we have an error condition */ - else if (fd < 0) { - RTE_LOG(ERR, EAL, "Could not open %s: %s\n", - path, strerror(errno)); - return -1; - } - - /* try ex-locking first - if the lock *does* succeed, this means it's a - * stray config file, so it should be deleted. - */ - if (flock(fd, LOCK_EX | LOCK_NB) != -1) { - - /* if we can't remove the file, something is wrong */ - if (unlink(path) < 0) { - RTE_LOG(ERR, EAL, "Could not remove %s: %s\n", path, - strerror(errno)); - return -1; - } - - /* release the lock */ - flock(fd, LOCK_UN); - close(fd); - - /* return success as having a stray config file is equivalent to not - * having config file at all. - */ - return 0; - } - - ivshmem_config = mmap(NULL, sizeof(struct ivshmem_shared_config), - PROT_READ, MAP_SHARED, fd, 0); - - if (ivshmem_config == MAP_FAILED) - return -1; - - /* place a shared lock on config file */ - if (flock(fd, LOCK_SH | LOCK_NB) == -1) { - RTE_LOG(ERR, EAL, "Locking %s failed: %s \n", path, strerror(errno)); - return -1; - } - - close(fd); - - return 0; -} - -/* - * This function does the following: - * - * 1) Builds a table of ivshmem_segments with proper offset alignment - * 2) Cleans up that table so that we don't have any overlapping or adjacent - * memory segments - * 3) Creates memsegs from this table and maps them into memory. - */ -static inline int -map_all_segments(void) -{ - struct ivshmem_segment ms_tbl[RTE_MAX_MEMSEG]; - struct ivshmem_pci_device * pci_dev; - struct rte_mem_config * mcfg; - struct ivshmem_segment * seg; - int fd, fd_zero; - unsigned i, j; - struct rte_memzone mz; - struct rte_memseg ms; - void * base_addr; - uint64_t align, len; - phys_addr_t ioremap_addr; - - ioremap_addr = 0; - - memset(ms_tbl, 0, sizeof(ms_tbl)); - memset(&mz, 0, sizeof(struct rte_memzone)); - memset(&ms, 0, sizeof(struct rte_memseg)); - - /* first, build a table of memsegs to map, to avoid failed mmaps due to - * overlaps - */ - for (i = 0; i < ivshmem_config->segment_idx && i <= RTE_MAX_MEMSEG; i++) { - if (i == RTE_MAX_MEMSEG) { - RTE_LOG(ERR, EAL, "Too many segments requested!\n"); - return -1; - } - - seg = &ivshmem_config->segment[i]; - - /* copy segment to table */ - memcpy(&ms_tbl[i], seg, sizeof(struct ivshmem_segment)); - - /* find ioremap addr */ - for (j = 0; j < DIM(ivshmem_config->pci_devs); j++) { - pci_dev = &ivshmem_config->pci_devs[j]; - if (!strncmp(pci_dev->path, seg->path, sizeof(pci_dev->path))) { - ioremap_addr = pci_dev->ioremap_addr; - break; - } - } - if (ioremap_addr == 0) { - RTE_LOG(ERR, EAL, "Cannot find ioremap addr!\n"); - return -1; - } - - /* work out alignments */ - align = seg->entry.mz.addr_64 - - RTE_ALIGN_FLOOR(seg->entry.mz.addr_64, 0x1000); - len = RTE_ALIGN_CEIL(seg->entry.mz.len + align, 0x1000); - - /* save original alignments */ - ms_tbl[i].align = align; - - /* create a memory zone */ - mz.addr_64 = seg->entry.mz.addr_64 - align; - mz.len = len; - mz.hugepage_sz = seg->entry.mz.hugepage_sz; - mz.phys_addr = seg->entry.mz.phys_addr - align; - - /* find true physical address */ - mz.ioremap_addr = ioremap_addr + seg->entry.offset - align; - - ms_tbl[i].entry.offset = seg->entry.offset - align; - - memcpy(&ms_tbl[i].entry.mz, &mz, sizeof(struct rte_memzone)); - } - - /* clean up the segments */ - memseg_idx = cleanup_segments(ms_tbl, ivshmem_config->segment_idx); - - if (memseg_idx < 0) - return -1; - - mcfg = rte_eal_get_configuration()->mem_config; - - fd_zero = open("/dev/zero", O_RDWR); - - if (fd_zero < 0) { - RTE_LOG(ERR, EAL, "Cannot open /dev/zero: %s\n", strerror(errno)); - return -1; - } - - /* create memsegs and put them into DPDK memory */ - for (i = 0; i < (unsigned) memseg_idx; i++) { - - seg = &ms_tbl[i]; - - ms.addr_64 = seg->entry.mz.addr_64; - ms.hugepage_sz = seg->entry.mz.hugepage_sz; - ms.len = seg->entry.mz.len; - ms.nchannel = rte_memory_get_nchannel(); - ms.nrank = rte_memory_get_nrank(); - ms.phys_addr = seg->entry.mz.phys_addr; - ms.ioremap_addr = seg->entry.mz.ioremap_addr; - ms.socket_id = seg->entry.mz.socket_id; - - base_addr = mmap(ms.addr, ms.len, - PROT_READ | PROT_WRITE, MAP_PRIVATE, fd_zero, 0); - - if (base_addr == MAP_FAILED || base_addr != ms.addr) { - RTE_LOG(ERR, EAL, "Cannot map /dev/zero!\n"); - return -1; - } - - fd = open(seg->path, O_RDWR); - - if (fd < 0) { - RTE_LOG(ERR, EAL, "Cannot open %s: %s\n", seg->path, - strerror(errno)); - return -1; - } - - munmap(ms.addr, ms.len); - - base_addr = mmap(ms.addr, ms.len, - PROT_READ | PROT_WRITE, MAP_SHARED, fd, - seg->entry.offset); - - - if (base_addr == MAP_FAILED || base_addr != ms.addr) { - RTE_LOG(ERR, EAL, "Cannot map segment into memory: " - "expected %p got %p (%s)\n", ms.addr, base_addr, - strerror(errno)); - return -1; - } - - RTE_LOG(DEBUG, EAL, "Memory segment mapped: %p (len %" PRIx64 ") at " - "offset 0x%" PRIx64 "\n", - ms.addr, ms.len, seg->entry.offset); - - /* put the pointers back into their real positions using original - * alignment */ - ms.addr_64 += seg->align; - ms.phys_addr += seg->align; - ms.ioremap_addr += seg->align; - ms.len -= seg->align; - - /* at this point, the rest of DPDK memory is not initialized, so we - * expect memsegs to be empty */ - memcpy(&mcfg->memseg[i], &ms, - sizeof(struct rte_memseg)); - - close(fd); - - RTE_LOG(DEBUG, EAL, "IVSHMEM segment found, size: 0x%lx\n", - ms.len); - } - - return 0; -} - -/* this happens at a later stage, after general EAL memory initialization */ -int -rte_eal_ivshmem_obj_init(void) -{ - struct rte_ring_list* ring_list = NULL; - struct rte_mem_config * mcfg; - struct ivshmem_segment * seg; - struct rte_memzone * mz; - struct rte_ring * r; - struct rte_tailq_entry *te; - unsigned i, ms, idx; - uint64_t offset; - - /* secondary process would not need any object discovery - it'll all - * already be in shared config */ - if (rte_eal_process_type() != RTE_PROC_PRIMARY || ivshmem_config == NULL) - return 0; - - /* check that we have an initialised ring tail queue */ - ring_list = RTE_TAILQ_LOOKUP(RTE_TAILQ_RING_NAME, rte_ring_list); - if (ring_list == NULL) { - RTE_LOG(ERR, EAL, "No rte_ring tailq found!\n"); - return -1; - } - - mcfg = rte_eal_get_configuration()->mem_config; - - /* create memzones */ - for (i = 0; i < ivshmem_config->segment_idx && i <= RTE_MAX_MEMZONE; i++) { - - seg = &ivshmem_config->segment[i]; - - /* add memzone */ - if (mcfg->memzone_cnt == RTE_MAX_MEMZONE) { - RTE_LOG(ERR, EAL, "No more memory zones available!\n"); - return -1; - } - - idx = mcfg->memzone_cnt; - - RTE_LOG(DEBUG, EAL, "Found memzone: '%s' at %p (len 0x%" PRIx64 ")\n", - seg->entry.mz.name, seg->entry.mz.addr, seg->entry.mz.len); - - memcpy(&mcfg->memzone[idx], &seg->entry.mz, - sizeof(struct rte_memzone)); - - /* find ioremap address */ - for (ms = 0; ms <= RTE_MAX_MEMSEG; ms++) { - if (ms == RTE_MAX_MEMSEG) { - RTE_LOG(ERR, EAL, "Physical address of segment not found!\n"); - return -1; - } - if (CONTAINS(mcfg->memseg[ms], mcfg->memzone[idx])) { - offset = mcfg->memzone[idx].addr_64 - - mcfg->memseg[ms].addr_64; - mcfg->memzone[idx].ioremap_addr = mcfg->memseg[ms].ioremap_addr + - offset; - break; - } - } - - mcfg->memzone_cnt++; - } - - rte_rwlock_write_lock(RTE_EAL_TAILQ_RWLOCK); - - /* find rings */ - for (i = 0; i < mcfg->memzone_cnt; i++) { - mz = &mcfg->memzone[i]; - - /* check if memzone has a ring prefix */ - if (strncmp(mz->name, RTE_RING_MZ_PREFIX, - sizeof(RTE_RING_MZ_PREFIX) - 1) != 0) - continue; - - r = (struct rte_ring*) (mz->addr_64); - - te = rte_zmalloc("RING_TAILQ_ENTRY", sizeof(*te), 0); - if (te == NULL) { - RTE_LOG(ERR, EAL, "Cannot allocate ring tailq entry!\n"); - return -1; - } - - te->data = (void *) r; - - TAILQ_INSERT_TAIL(ring_list, te, next); - - RTE_LOG(DEBUG, EAL, "Found ring: '%s' at %p\n", r->name, mz->addr); - } - rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK); - -#ifdef RTE_LIBRTE_IVSHMEM_DEBUG - rte_memzone_dump(stdout); - rte_ring_list_dump(stdout); -#endif - - return 0; -} - -/* initialize ivshmem structures */ -int rte_eal_ivshmem_init(void) -{ - struct rte_pci_device * dev; - struct rte_pci_resource * res; - int fd, ret; - char path[PATH_MAX]; - - /* initialize everything to 0 */ - memset(path, 0, sizeof(path)); - ivshmem_config = NULL; - - pagesz = getpagesize(); - - RTE_LOG(DEBUG, EAL, "Searching for IVSHMEM devices...\n"); - - if (rte_eal_process_type() == RTE_PROC_SECONDARY) { - - if (open_shared_config() < 0) { - RTE_LOG(ERR, EAL, "Could not open IVSHMEM config!\n"); - return -1; - } - } - else { - - TAILQ_FOREACH(dev, &pci_device_list, next) { - - if (is_ivshmem_device(dev)) { - - /* IVSHMEM memory is always on BAR2 */ - res = &dev->mem_resource[2]; - - /* if we don't have a BAR2 */ - if (res->len == 0) - continue; - - /* construct pci device path */ - snprintf(path, sizeof(path), IVSHMEM_RESOURCE_PATH, - dev->addr.domain, dev->addr.bus, dev->addr.devid, - dev->addr.function); - - /* try to find memseg */ - fd = open(path, O_RDWR); - if (fd < 0) { - RTE_LOG(ERR, EAL, "Could not open %s\n", path); - return -1; - } - - /* check if it's a DPDK IVSHMEM device */ - ret = has_ivshmem_metadata(fd, res->len); - - /* is DPDK device */ - if (ret == 1) { - - /* config file creation is deferred until the first - * DPDK device is found. then, it has to be created - * only once. */ - if (ivshmem_config == NULL && - create_shared_config() < 0) { - RTE_LOG(ERR, EAL, "Could not create IVSHMEM config!\n"); - close(fd); - return -1; - } - - if (read_metadata(path, sizeof(path), fd, res->len) < 0) { - RTE_LOG(ERR, EAL, "Could not read metadata from" - " device %02x:%02x.%x!\n", dev->addr.bus, - dev->addr.devid, dev->addr.function); - close(fd); - return -1; - } - - if (ivshmem_config->pci_devs_idx == RTE_LIBRTE_IVSHMEM_MAX_PCI_DEVS) { - RTE_LOG(WARNING, EAL, - "IVSHMEM PCI device limit exceeded. Increase " - "CONFIG_RTE_LIBRTE_IVSHMEM_MAX_PCI_DEVS in " - "your config file.\n"); - break; - } - - RTE_LOG(INFO, EAL, "Found IVSHMEM device %02x:%02x.%x\n", - dev->addr.bus, dev->addr.devid, dev->addr.function); - - ivshmem_config->pci_devs[ivshmem_config->pci_devs_idx].ioremap_addr = res->phys_addr; - snprintf(ivshmem_config->pci_devs[ivshmem_config->pci_devs_idx].path, - sizeof(ivshmem_config->pci_devs[ivshmem_config->pci_devs_idx].path), - "%s", path); - - ivshmem_config->pci_devs_idx++; - } - /* failed to read */ - else if (ret < 0) { - RTE_LOG(ERR, EAL, "Could not read IVSHMEM device: %s\n", - strerror(errno)); - close(fd); - return -1; - } - /* not a DPDK device */ - else - RTE_LOG(DEBUG, EAL, "Skipping non-DPDK IVSHMEM device\n"); - - /* close the BAR fd */ - close(fd); - } - } - } - - /* ivshmem_config is not NULL only if config was created and/or mapped */ - if (ivshmem_config) { - if (map_all_segments() < 0) { - RTE_LOG(ERR, EAL, "Mapping IVSHMEM segments failed!\n"); - return -1; - } - } - else { - RTE_LOG(DEBUG, EAL, "No IVSHMEM configuration found! \n"); - } - - return 0; -} - -#endif diff --git a/lib/librte_eal/linuxapp/eal/eal_memory.c b/lib/librte_eal/linuxapp/eal/eal_memory.c index 41e0a92887..992a1b142c 100644 --- a/lib/librte_eal/linuxapp/eal/eal_memory.c +++ b/lib/librte_eal/linuxapp/eal/eal_memory.c @@ -1436,15 +1436,8 @@ rte_eal_hugepage_init(void) free(tmp_hp); tmp_hp = NULL; - /* find earliest free memseg - this is needed because in case of IVSHMEM, - * segments might have already been initialized */ - for (j = 0; j < RTE_MAX_MEMSEG; j++) - if (mcfg->memseg[j].addr == NULL) { - /* move to previous segment and exit loop */ - j--; - break; - } - + /* first memseg index shall be 0 after incrementing it below */ + j = -1; for (i = 0; i < nr_hugefiles; i++) { new_memseg = 0; @@ -1597,15 +1590,6 @@ rte_eal_hugepage_attach(void) if (mcfg->memseg[s].len == 0) break; -#ifdef RTE_LIBRTE_IVSHMEM - /* - * if segment has ioremap address set, it's an IVSHMEM segment and - * doesn't need mapping as it was already mapped earlier - */ - if (mcfg->memseg[s].ioremap_addr != 0) - continue; -#endif - /* * fdzero is mmapped to get a contiguous block of virtual * addresses of the appropriate memseg size. @@ -1644,16 +1628,6 @@ rte_eal_hugepage_attach(void) void *addr, *base_addr; uintptr_t offset = 0; size_t mapping_size; -#ifdef RTE_LIBRTE_IVSHMEM - /* - * if segment has ioremap address set, it's an IVSHMEM segment and - * doesn't need mapping as it was already mapped earlier - */ - if (mcfg->memseg[s].ioremap_addr != 0) { - s++; - continue; - } -#endif /* * free previously mapped memory so we can map the * hugepages into the space diff --git a/lib/librte_ivshmem/Makefile b/lib/librte_ivshmem/Makefile deleted file mode 100644 index c099438c8e..0000000000 --- a/lib/librte_ivshmem/Makefile +++ /dev/null @@ -1,54 +0,0 @@ -# BSD LICENSE -# -# Copyright(c) 2010-2014 Intel Corporation. All rights reserved. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Intel Corporation nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -include $(RTE_SDK)/mk/rte.vars.mk - -# library name -LIB = librte_ivshmem.a - -CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR) -O3 - -EXPORT_MAP := rte_ivshmem_version.map - -LIBABIVER := 1 - -# all source are stored in SRCS-y -SRCS-$(CONFIG_RTE_LIBRTE_IVSHMEM) := rte_ivshmem.c - -# install includes -SYMLINK-$(CONFIG_RTE_LIBRTE_IVSHMEM)-include := rte_ivshmem.h - -# this lib needs EAL, ring and mempool -DEPDIRS-$(CONFIG_RTE_LIBRTE_IVSHMEM) += lib/librte_eal -DEPDIRS-$(CONFIG_RTE_LIBRTE_IVSHMEM) += lib/librte_ring -DEPDIRS-$(CONFIG_RTE_LIBRTE_IVSHMEM) += lib/librte_mempool - -include $(RTE_SDK)/mk/rte.lib.mk diff --git a/lib/librte_ivshmem/rte_ivshmem.c b/lib/librte_ivshmem/rte_ivshmem.c deleted file mode 100644 index c26edb61a6..0000000000 --- a/lib/librte_ivshmem/rte_ivshmem.c +++ /dev/null @@ -1,919 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "rte_ivshmem.h" - -#define IVSHMEM_CONFIG_FILE_FMT "/var/run/.dpdk_ivshmem_metadata_%s" -#define IVSHMEM_QEMU_CMD_LINE_HEADER_FMT "-device ivshmem,size=%" PRIu64 "M,shm=fd%s" -#define IVSHMEM_QEMU_CMD_FD_FMT ":%s:0x%" PRIx64 ":0x%" PRIx64 -#define IVSHMEM_QEMU_CMDLINE_BUFSIZE 1024 -#define IVSHMEM_MAX_PAGES (1 << 12) -#define adjacent(x,y) (((x).phys_addr+(x).len)==(y).phys_addr) -#define METADATA_SIZE_ALIGNED \ - (RTE_ALIGN_CEIL(sizeof(struct rte_ivshmem_metadata),pagesz)) - -#define GET_PAGEMAP_ADDR(in,addr,dlm,err) \ -{ \ - char *end; \ - errno = 0; \ - addr = strtoull((in), &end, 16); \ - if (errno != 0 || *end != (dlm)) { \ - RTE_LOG(ERR, EAL, err); \ - goto error; \ - } \ - (in) = end + 1; \ -} - -static int pagesz; - -struct memseg_cache_entry { - char filepath[PATH_MAX]; - uint64_t offset; - uint64_t len; -}; - -struct ivshmem_config { - struct rte_ivshmem_metadata * metadata; - struct memseg_cache_entry memseg_cache[IVSHMEM_MAX_PAGES]; - /**< account for multiple files per segment case */ - struct flock lock; - rte_spinlock_t sl; -}; - -static struct ivshmem_config -ivshmem_global_config[RTE_LIBRTE_IVSHMEM_MAX_METADATA_FILES]; - -static rte_spinlock_t global_cfg_sl; - -static struct ivshmem_config * -get_config_by_name(const char * name) -{ - struct rte_ivshmem_metadata * config; - unsigned i; - - for (i = 0; i < RTE_DIM(ivshmem_global_config); i++) { - config = ivshmem_global_config[i].metadata; - if (config == NULL) - return NULL; - if (strncmp(name, config->name, IVSHMEM_NAME_LEN) == 0) - return &ivshmem_global_config[i]; - } - - return NULL; -} - -static int -overlap(const struct rte_memzone * s1, const struct rte_memzone * s2) -{ - uint64_t start1, end1, start2, end2; - - start1 = s1->addr_64; - end1 = s1->addr_64 + s1->len; - start2 = s2->addr_64; - end2 = s2->addr_64 + s2->len; - - if (start1 >= start2 && start1 < end2) - return 1; - if (start2 >= start1 && start2 < end1) - return 1; - - return 0; -} - -static struct rte_memzone * -get_memzone_by_addr(const void * addr) -{ - struct rte_memzone * tmp, * mz; - struct rte_mem_config * mcfg; - int i; - - mcfg = rte_eal_get_configuration()->mem_config; - mz = NULL; - - /* find memzone for the ring */ - for (i = 0; i < RTE_MAX_MEMZONE; i++) { - tmp = &mcfg->memzone[i]; - - if (tmp->addr_64 == (uint64_t) addr) { - mz = tmp; - break; - } - } - - return mz; -} - -static int -entry_compare(const void * a, const void * b) -{ - const struct rte_ivshmem_metadata_entry * e1 = - (const struct rte_ivshmem_metadata_entry*) a; - const struct rte_ivshmem_metadata_entry * e2 = - (const struct rte_ivshmem_metadata_entry*) b; - - /* move unallocated zones to the end */ - if (e1->mz.addr == NULL && e2->mz.addr == NULL) - return 0; - if (e1->mz.addr == 0) - return 1; - if (e2->mz.addr == 0) - return -1; - - return e1->mz.phys_addr > e2->mz.phys_addr; -} - -/* fills hugepage cache entry for a given start virt_addr */ -static int -get_hugefile_by_virt_addr(uint64_t virt_addr, struct memseg_cache_entry * e) -{ - uint64_t start_addr, end_addr; - char *start,*path_end; - char buf[PATH_MAX*2]; - FILE *f; - - start = NULL; - path_end = NULL; - start_addr = 0; - - memset(e->filepath, 0, sizeof(e->filepath)); - - /* open /proc/self/maps */ - f = fopen("/proc/self/maps", "r"); - if (f == NULL) { - RTE_LOG(ERR, EAL, "cannot open /proc/self/maps!\n"); - return -1; - } - - /* parse maps */ - while (fgets(buf, sizeof(buf), f) != NULL) { - - /* get endptr to end of start addr */ - start = buf; - - GET_PAGEMAP_ADDR(start,start_addr,'-', - "Cannot find start address in maps!\n"); - - /* if start address is bigger than our address, skip */ - if (start_addr > virt_addr) - continue; - - GET_PAGEMAP_ADDR(start,end_addr,' ', - "Cannot find end address in maps!\n"); - - /* if end address is less than our address, skip */ - if (end_addr <= virt_addr) - continue; - - /* find where the path starts */ - start = strstr(start, "/"); - - if (start == NULL) - continue; - - /* at this point, we know that this is our map. - * now let's find the file */ - path_end = strstr(start, "\n"); - break; - } - - if (path_end == NULL) { - RTE_LOG(ERR, EAL, "Hugefile path not found!\n"); - goto error; - } - - /* calculate offset and copy the file path */ - snprintf(e->filepath, RTE_PTR_DIFF(path_end, start) + 1, "%s", start); - - e->offset = virt_addr - start_addr; - - fclose(f); - - return 0; -error: - fclose(f); - return -1; -} - -/* - * This is a complex function. What it does is the following: - * 1. Goes through metadata and gets list of hugepages involved - * 2. Sorts the hugepages by size (1G first) - * 3. Goes through metadata again and writes correct offsets - * 4. Goes through pages and finds out their filenames, offsets etc. - */ -static int -build_config(struct rte_ivshmem_metadata * metadata) -{ - struct rte_ivshmem_metadata_entry * e_local; - struct memseg_cache_entry * ms_local; - struct rte_memseg pages[IVSHMEM_MAX_PAGES]; - struct rte_ivshmem_metadata_entry *entry; - struct memseg_cache_entry * c_entry, * prev_entry; - struct ivshmem_config * config; - unsigned i, j, mz_iter, ms_iter; - uint64_t biggest_len; - int biggest_idx; - - /* return error if we try to use an unknown config file */ - config = get_config_by_name(metadata->name); - if (config == NULL) { - RTE_LOG(ERR, EAL, "Cannot find IVSHMEM config %s!\n", metadata->name); - goto fail_e; - } - - memset(pages, 0, sizeof(pages)); - - e_local = malloc(sizeof(config->metadata->entry)); - if (e_local == NULL) - goto fail_e; - ms_local = malloc(sizeof(config->memseg_cache)); - if (ms_local == NULL) - goto fail_ms; - - - /* make local copies before doing anything */ - memcpy(e_local, config->metadata->entry, sizeof(config->metadata->entry)); - memcpy(ms_local, config->memseg_cache, sizeof(config->memseg_cache)); - - qsort(e_local, RTE_DIM(config->metadata->entry), sizeof(struct rte_ivshmem_metadata_entry), - entry_compare); - - /* first pass - collect all huge pages */ - for (mz_iter = 0; mz_iter < RTE_DIM(config->metadata->entry); mz_iter++) { - - entry = &e_local[mz_iter]; - - uint64_t start_addr = RTE_ALIGN_FLOOR(entry->mz.addr_64, - entry->mz.hugepage_sz); - uint64_t offset = entry->mz.addr_64 - start_addr; - uint64_t len = RTE_ALIGN_CEIL(entry->mz.len + offset, - entry->mz.hugepage_sz); - - if (entry->mz.addr_64 == 0 || start_addr == 0 || len == 0) - continue; - - int start_page; - - /* find first unused page - mz are phys_addr sorted so we don't have to - * look out for holes */ - for (i = 0; i < RTE_DIM(pages); i++) { - - /* skip if we already have this page */ - if (pages[i].addr_64 == start_addr) { - start_addr += entry->mz.hugepage_sz; - len -= entry->mz.hugepage_sz; - continue; - } - /* we found a new page */ - else if (pages[i].addr_64 == 0) { - start_page = i; - break; - } - } - if (i == RTE_DIM(pages)) { - RTE_LOG(ERR, EAL, "Cannot find unused page!\n"); - goto fail; - } - - /* populate however many pages the memzone has */ - for (i = start_page; i < RTE_DIM(pages) && len != 0; i++) { - - pages[i].addr_64 = start_addr; - pages[i].len = entry->mz.hugepage_sz; - start_addr += entry->mz.hugepage_sz; - len -= entry->mz.hugepage_sz; - } - /* if there's still length left */ - if (len != 0) { - RTE_LOG(ERR, EAL, "Not enough space for pages!\n"); - goto fail; - } - } - - /* second pass - sort pages by size */ - for (i = 0; i < RTE_DIM(pages); i++) { - - if (pages[i].addr == NULL) - break; - - biggest_len = 0; - biggest_idx = -1; - - /* - * browse all entries starting at 'i', and find the - * entry with the smallest addr - */ - for (j=i; j< RTE_DIM(pages); j++) { - if (pages[j].addr == NULL) - break; - if (biggest_len == 0 || - pages[j].len > biggest_len) { - biggest_len = pages[j].len; - biggest_idx = j; - } - } - - /* should not happen */ - if (biggest_idx == -1) { - RTE_LOG(ERR, EAL, "Error sorting by size!\n"); - goto fail; - } - if (i != (unsigned) biggest_idx) { - struct rte_memseg tmp; - - memcpy(&tmp, &pages[biggest_idx], sizeof(struct rte_memseg)); - - /* we don't want to break contiguousness, so instead of just - * swapping segments, we move all the preceding segments to the - * right and then put the old segment @ biggest_idx in place of - * segment @ i */ - for (j = biggest_idx - 1; j >= i; j--) { - memcpy(&pages[j+1], &pages[j], sizeof(struct rte_memseg)); - memset(&pages[j], 0, sizeof(struct rte_memseg)); - if (j == 0) - break; - } - - /* put old biggest segment to its new place */ - memcpy(&pages[i], &tmp, sizeof(struct rte_memseg)); - } - } - - /* third pass - write correct offsets */ - for (mz_iter = 0; mz_iter < RTE_DIM(config->metadata->entry); mz_iter++) { - - uint64_t offset = 0; - - entry = &e_local[mz_iter]; - - if (entry->mz.addr_64 == 0) - break; - - /* find page for current memzone */ - for (i = 0; i < RTE_DIM(pages); i++) { - /* we found our page */ - if (entry->mz.addr_64 >= pages[i].addr_64 && - entry->mz.addr_64 < pages[i].addr_64 + pages[i].len) { - entry->offset = (entry->mz.addr_64 - pages[i].addr_64) + - offset; - break; - } - offset += pages[i].len; - } - if (i == RTE_DIM(pages)) { - RTE_LOG(ERR, EAL, "Page not found!\n"); - goto fail; - } - } - - ms_iter = 0; - prev_entry = NULL; - - /* fourth pass - create proper memseg cache */ - for (i = 0; i < RTE_DIM(pages) && - ms_iter <= RTE_DIM(config->memseg_cache); i++) { - if (pages[i].addr_64 == 0) - break; - - - if (ms_iter == RTE_DIM(pages)) { - RTE_LOG(ERR, EAL, "The universe has collapsed!\n"); - goto fail; - } - - c_entry = &ms_local[ms_iter]; - c_entry->len = pages[i].len; - - if (get_hugefile_by_virt_addr(pages[i].addr_64, c_entry) < 0) - goto fail; - - /* if previous entry has the same filename and is contiguous, - * clear current entry and increase previous entry's length - */ - if (prev_entry != NULL && - strncmp(c_entry->filepath, prev_entry->filepath, - sizeof(c_entry->filepath)) == 0 && - prev_entry->offset + prev_entry->len == c_entry->offset) { - prev_entry->len += pages[i].len; - memset(c_entry, 0, sizeof(struct memseg_cache_entry)); - } - else { - prev_entry = c_entry; - ms_iter++; - } - } - - /* update current configuration with new valid data */ - memcpy(config->metadata->entry, e_local, sizeof(config->metadata->entry)); - memcpy(config->memseg_cache, ms_local, sizeof(config->memseg_cache)); - - free(ms_local); - free(e_local); - - return 0; -fail: - free(ms_local); -fail_ms: - free(e_local); -fail_e: - return -1; -} - -static int -add_memzone_to_metadata(const struct rte_memzone * mz, - struct ivshmem_config * config) -{ - struct rte_ivshmem_metadata_entry * entry; - unsigned i, idx; - struct rte_mem_config *mcfg; - - if (mz->len == 0) { - RTE_LOG(ERR, EAL, "Trying to add an empty memzone\n"); - return -1; - } - - rte_spinlock_lock(&config->sl); - - mcfg = rte_eal_get_configuration()->mem_config; - - /* it prevents the memzone being freed while we add it to the metadata */ - rte_rwlock_write_lock(&mcfg->mlock); - - /* find free slot in this config */ - for (i = 0; i < RTE_DIM(config->metadata->entry); i++) { - entry = &config->metadata->entry[i]; - - if (&entry->mz.addr_64 != 0 && overlap(mz, &entry->mz)) { - RTE_LOG(ERR, EAL, "Overlapping memzones!\n"); - goto fail; - } - - /* if addr is zero, the memzone is probably free */ - if (entry->mz.addr_64 == 0) { - RTE_LOG(DEBUG, EAL, "Adding memzone '%s' at %p to metadata %s\n", - mz->name, mz->addr, config->metadata->name); - memcpy(&entry->mz, mz, sizeof(struct rte_memzone)); - - /* run config file parser */ - if (build_config(config->metadata) < 0) - goto fail; - - break; - } - } - - /* if we reached the maximum, that means we have no place in config */ - if (i == RTE_DIM(config->metadata->entry)) { - RTE_LOG(ERR, EAL, "No space left in IVSHMEM metadata %s!\n", - config->metadata->name); - goto fail; - } - - idx = ((uintptr_t)mz - (uintptr_t)mcfg->memzone); - idx = idx / sizeof(struct rte_memzone); - - /* mark the memzone not freeable */ - mcfg->memzone[idx].ioremap_addr = mz->phys_addr; - - rte_rwlock_write_unlock(&mcfg->mlock); - rte_spinlock_unlock(&config->sl); - return 0; -fail: - rte_rwlock_write_unlock(&mcfg->mlock); - rte_spinlock_unlock(&config->sl); - return -1; -} - -static int -add_ring_to_metadata(const struct rte_ring * r, - struct ivshmem_config * config) -{ - struct rte_memzone * mz; - - mz = get_memzone_by_addr(r); - - if (!mz) { - RTE_LOG(ERR, EAL, "Cannot find memzone for ring!\n"); - return -1; - } - - return add_memzone_to_metadata(mz, config); -} - -static int -add_mempool_memzone_to_metadata(const void *addr, - struct ivshmem_config *config) -{ - struct rte_memzone *mz; - - mz = get_memzone_by_addr(addr); - - if (!mz) { - RTE_LOG(ERR, EAL, "Cannot find memzone for mempool!\n"); - return -1; - } - - return add_memzone_to_metadata(mz, config); -} - -static int -add_mempool_to_metadata(const struct rte_mempool *mp, - struct ivshmem_config *config) -{ - struct rte_mempool_memhdr *memhdr; - int ret; - - ret = add_mempool_memzone_to_metadata(mp, config); - if (ret < 0) - return -1; - - STAILQ_FOREACH(memhdr, &mp->mem_list, next) { - ret = add_mempool_memzone_to_metadata(memhdr->addr, config); - if (ret < 0) - return -1; - } - - /* mempool consists of memzone and ring */ - return add_ring_to_metadata(mp->pool_data, config); -} - -int -rte_ivshmem_metadata_add_ring(const struct rte_ring * r, const char * name) -{ - struct ivshmem_config * config; - - if (name == NULL || r == NULL) - return -1; - - config = get_config_by_name(name); - - if (config == NULL) { - RTE_LOG(ERR, EAL, "Cannot find IVSHMEM config %s!\n", name); - return -1; - } - - return add_ring_to_metadata(r, config); -} - -int -rte_ivshmem_metadata_add_memzone(const struct rte_memzone * mz, const char * name) -{ - struct ivshmem_config * config; - - if (name == NULL || mz == NULL) - return -1; - - config = get_config_by_name(name); - - if (config == NULL) { - RTE_LOG(ERR, EAL, "Cannot find IVSHMEM config %s!\n", name); - return -1; - } - - return add_memzone_to_metadata(mz, config); -} - -int -rte_ivshmem_metadata_add_mempool(const struct rte_mempool * mp, const char * name) -{ - struct ivshmem_config * config; - - if (name == NULL || mp == NULL) - return -1; - - config = get_config_by_name(name); - - if (config == NULL) { - RTE_LOG(ERR, EAL, "Cannot find IVSHMEM config %s!\n", name); - return -1; - } - - return add_mempool_to_metadata(mp, config); -} - -static inline void -ivshmem_config_path(char *buffer, size_t bufflen, const char *name) -{ - snprintf(buffer, bufflen, IVSHMEM_CONFIG_FILE_FMT, name); -} - - - -static inline -void *ivshmem_metadata_create(const char *name, size_t size, - struct flock *lock) -{ - int retval, fd; - void *metadata_addr; - char pathname[PATH_MAX]; - - ivshmem_config_path(pathname, sizeof(pathname), name); - - fd = open(pathname, O_RDWR | O_CREAT, 0660); - if (fd < 0) { - RTE_LOG(ERR, EAL, "Cannot open '%s'\n", pathname); - return NULL; - } - - size = METADATA_SIZE_ALIGNED; - - retval = fcntl(fd, F_SETLK, lock); - if (retval < 0){ - close(fd); - RTE_LOG(ERR, EAL, "Cannot create lock on '%s'. Is another " - "process using it?\n", pathname); - return NULL; - } - - retval = ftruncate(fd, size); - if (retval < 0){ - close(fd); - RTE_LOG(ERR, EAL, "Cannot resize '%s'\n", pathname); - return NULL; - } - - metadata_addr = mmap(NULL, size, - PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - - if (metadata_addr == MAP_FAILED){ - RTE_LOG(ERR, EAL, "Cannot mmap memory for '%s'\n", pathname); - - /* we don't care if we can't unlock */ - fcntl(fd, F_UNLCK, lock); - close(fd); - - return NULL; - } - - return metadata_addr; -} - -int rte_ivshmem_metadata_create(const char *name) -{ - struct ivshmem_config * ivshmem_config; - unsigned index; - - if (pagesz == 0) - pagesz = getpagesize(); - - if (name == NULL) - return -1; - - rte_spinlock_lock(&global_cfg_sl); - - for (index = 0; index < RTE_DIM(ivshmem_global_config); index++) { - if (ivshmem_global_config[index].metadata == NULL) { - ivshmem_config = &ivshmem_global_config[index]; - break; - } - } - - if (index == RTE_DIM(ivshmem_global_config)) { - RTE_LOG(ERR, EAL, "Cannot create more ivshmem config files. " - "Maximum has been reached\n"); - rte_spinlock_unlock(&global_cfg_sl); - return -1; - } - - ivshmem_config->lock.l_type = F_WRLCK; - ivshmem_config->lock.l_whence = SEEK_SET; - - ivshmem_config->lock.l_start = 0; - ivshmem_config->lock.l_len = METADATA_SIZE_ALIGNED; - - ivshmem_global_config[index].metadata = ((struct rte_ivshmem_metadata *) - ivshmem_metadata_create( - name, - sizeof(struct rte_ivshmem_metadata), - &ivshmem_config->lock)); - - if (ivshmem_global_config[index].metadata == NULL) { - rte_spinlock_unlock(&global_cfg_sl); - return -1; - } - - /* Metadata setup */ - memset(ivshmem_config->metadata, 0, sizeof(struct rte_ivshmem_metadata)); - ivshmem_config->metadata->magic_number = IVSHMEM_MAGIC; - snprintf(ivshmem_config->metadata->name, - sizeof(ivshmem_config->metadata->name), "%s", name); - - rte_spinlock_unlock(&global_cfg_sl); - - return 0; -} - -int -rte_ivshmem_metadata_cmdline_generate(char *buffer, unsigned size, const char *name) -{ - const struct memseg_cache_entry * ms_cache, *entry; - struct ivshmem_config * config; - char cmdline[IVSHMEM_QEMU_CMDLINE_BUFSIZE], *cmdline_ptr; - char cfg_file_path[PATH_MAX]; - unsigned remaining_len, tmplen, iter; - uint64_t shared_mem_size, zero_size, total_size; - - if (buffer == NULL || name == NULL) - return -1; - - config = get_config_by_name(name); - - if (config == NULL) { - RTE_LOG(ERR, EAL, "Config %s not found!\n", name); - return -1; - } - - rte_spinlock_lock(&config->sl); - - /* prepare metadata file path */ - snprintf(cfg_file_path, sizeof(cfg_file_path), IVSHMEM_CONFIG_FILE_FMT, - config->metadata->name); - - ms_cache = config->memseg_cache; - - cmdline_ptr = cmdline; - remaining_len = sizeof(cmdline); - - shared_mem_size = 0; - iter = 0; - - while ((ms_cache[iter].len != 0) && (iter < RTE_DIM(config->metadata->entry))) { - - entry = &ms_cache[iter]; - - /* Offset and sizes within the current pathname */ - tmplen = snprintf(cmdline_ptr, remaining_len, IVSHMEM_QEMU_CMD_FD_FMT, - entry->filepath, entry->offset, entry->len); - - shared_mem_size += entry->len; - - cmdline_ptr = RTE_PTR_ADD(cmdline_ptr, tmplen); - remaining_len -= tmplen; - - if (remaining_len == 0) { - RTE_LOG(ERR, EAL, "Command line too long!\n"); - rte_spinlock_unlock(&config->sl); - return -1; - } - - iter++; - } - - total_size = rte_align64pow2(shared_mem_size + METADATA_SIZE_ALIGNED); - zero_size = total_size - shared_mem_size - METADATA_SIZE_ALIGNED; - - /* add /dev/zero to command-line to fill the space */ - tmplen = snprintf(cmdline_ptr, remaining_len, IVSHMEM_QEMU_CMD_FD_FMT, - "/dev/zero", - (uint64_t)0x0, - zero_size); - - cmdline_ptr = RTE_PTR_ADD(cmdline_ptr, tmplen); - remaining_len -= tmplen; - - if (remaining_len == 0) { - RTE_LOG(ERR, EAL, "Command line too long!\n"); - rte_spinlock_unlock(&config->sl); - return -1; - } - - /* add metadata file to the end of command-line */ - tmplen = snprintf(cmdline_ptr, remaining_len, IVSHMEM_QEMU_CMD_FD_FMT, - cfg_file_path, - (uint64_t)0x0, - METADATA_SIZE_ALIGNED); - - cmdline_ptr = RTE_PTR_ADD(cmdline_ptr, tmplen); - remaining_len -= tmplen; - - if (remaining_len == 0) { - RTE_LOG(ERR, EAL, "Command line too long!\n"); - rte_spinlock_unlock(&config->sl); - return -1; - } - - /* if current length of the command line is bigger than the buffer supplied - * by the user, or if command-line is bigger than what IVSHMEM accepts */ - if ((sizeof(cmdline) - remaining_len) > size) { - RTE_LOG(ERR, EAL, "Buffer is too short!\n"); - rte_spinlock_unlock(&config->sl); - return -1; - } - /* complete the command-line */ - snprintf(buffer, size, - IVSHMEM_QEMU_CMD_LINE_HEADER_FMT, - total_size >> 20, - cmdline); - - rte_spinlock_unlock(&config->sl); - - return 0; -} - -void -rte_ivshmem_metadata_dump(FILE *f, const char *name) -{ - unsigned i = 0; - struct ivshmem_config * config; - struct rte_ivshmem_metadata_entry *entry; -#ifdef RTE_LIBRTE_IVSHMEM_DEBUG - uint64_t addr; - uint64_t end, hugepage_sz; - struct memseg_cache_entry e; -#endif - - if (name == NULL) - return; - - /* return error if we try to use an unknown config file */ - config = get_config_by_name(name); - if (config == NULL) { - RTE_LOG(ERR, EAL, "Cannot find IVSHMEM config %s!\n", name); - return; - } - - rte_spinlock_lock(&config->sl); - - entry = &config->metadata->entry[0]; - - while (entry->mz.addr != NULL && i < RTE_DIM(config->metadata->entry)) { - - fprintf(f, "Entry %u: name:<%-20s>, phys:0x%-15lx, len:0x%-15lx, " - "virt:%-15p, off:0x%-15lx\n", - i, - entry->mz.name, - entry->mz.phys_addr, - entry->mz.len, - entry->mz.addr, - entry->offset); - i++; - -#ifdef RTE_LIBRTE_IVSHMEM_DEBUG - fprintf(f, "\tHugepage files:\n"); - - hugepage_sz = entry->mz.hugepage_sz; - addr = RTE_ALIGN_FLOOR(entry->mz.addr_64, hugepage_sz); - end = addr + RTE_ALIGN_CEIL(entry->mz.len + (entry->mz.addr_64 - addr), - hugepage_sz); - - for (; addr < end; addr += hugepage_sz) { - memset(&e, 0, sizeof(e)); - - get_hugefile_by_virt_addr(addr, &e); - - fprintf(f, "\t0x%"PRIx64 "-0x%" PRIx64 " offset: 0x%" PRIx64 " %s\n", - addr, addr + hugepage_sz, e.offset, e.filepath); - } -#endif - entry++; - } - - rte_spinlock_unlock(&config->sl); -} diff --git a/lib/librte_ivshmem/rte_ivshmem.h b/lib/librte_ivshmem/rte_ivshmem.h deleted file mode 100644 index a5d36d6b18..0000000000 --- a/lib/librte_ivshmem/rte_ivshmem.h +++ /dev/null @@ -1,165 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef RTE_IVSHMEM_H_ -#define RTE_IVSHMEM_H_ - -#include -#include - -/** - * @file - * - * The RTE IVSHMEM interface provides functions to create metadata files - * describing memory segments to be shared via QEMU IVSHMEM. - */ - - -#ifdef __cplusplus -extern "C" { -#endif - -#define IVSHMEM_MAGIC 0x0BADC0DE -#define IVSHMEM_NAME_LEN 32 - -/** - * Structure that holds IVSHMEM shared metadata entry. - */ -struct rte_ivshmem_metadata_entry { - struct rte_memzone mz; /**< shared memzone */ - uint64_t offset; /**< offset of memzone within IVSHMEM device */ -}; - -/** - * Structure that holds IVSHMEM metadata. - */ -struct rte_ivshmem_metadata { - int magic_number; /**< magic number */ - char name[IVSHMEM_NAME_LEN]; /**< name of the metadata file */ - struct rte_ivshmem_metadata_entry entry[RTE_LIBRTE_IVSHMEM_MAX_ENTRIES]; - /**< metadata entries */ -}; - -/** - * Creates metadata file with a given name - * - * @param name - * Name of metadata file to be created - * - * @return - * - On success, zero - * - On failure, a negative value - */ -int rte_ivshmem_metadata_create(const char * name); - -/** - * Adds memzone to a specific metadata file - * - * @param mz - * Memzone to be added - * @param md_name - * Name of metadata file for the memzone to be added to - * - * @return - * - On success, zero - * - On failure, a negative value - */ -int rte_ivshmem_metadata_add_memzone(const struct rte_memzone * mz, - const char * md_name); - -/** - * Adds a ring descriptor to a specific metadata file - * - * @param r - * Ring descriptor to be added - * @param md_name - * Name of metadata file for the ring to be added to - * - * @return - * - On success, zero - * - On failure, a negative value - */ -int rte_ivshmem_metadata_add_ring(const struct rte_ring * r, - const char * md_name); - -/** - * Adds a mempool to a specific metadata file - * - * @param mp - * Mempool to be added - * @param md_name - * Name of metadata file for the mempool to be added to - * - * @return - * - On success, zero - * - On failure, a negative value - */ -int rte_ivshmem_metadata_add_mempool(const struct rte_mempool * mp, - const char * md_name); - - -/** - * Generates the QEMU command-line for IVSHMEM device for a given metadata file. - * This function is to be called after all the objects were added. - * - * @param buffer - * Buffer to be filled with the command line arguments. - * @param size - * Size of the buffer. - * @param name - * Name of metadata file to generate QEMU command-line parameters for - * - * @return - * - On success, zero - * - On failure, a negative value - */ -int rte_ivshmem_metadata_cmdline_generate(char *buffer, unsigned size, - const char *name); - - -/** - * Dump all metadata entries from a given metadata file to the console. - * - * @param f - * A pointer to a file for output - * @name - * Name of the metadata file to be dumped to console. - */ -void rte_ivshmem_metadata_dump(FILE *f, const char *name); - - -#ifdef __cplusplus -} -#endif - -#endif /* RTE_IVSHMEM_H_ */ diff --git a/lib/librte_ivshmem/rte_ivshmem_version.map b/lib/librte_ivshmem/rte_ivshmem_version.map deleted file mode 100644 index 5a393ddc35..0000000000 --- a/lib/librte_ivshmem/rte_ivshmem_version.map +++ /dev/null @@ -1,12 +0,0 @@ -DPDK_2.0 { - global: - - rte_ivshmem_metadata_add_mempool; - rte_ivshmem_metadata_add_memzone; - rte_ivshmem_metadata_add_ring; - rte_ivshmem_metadata_cmdline_generate; - rte_ivshmem_metadata_create; - rte_ivshmem_metadata_dump; - - local: *; -}; diff --git a/mk/rte.app.mk b/mk/rte.app.mk index eb28e115be..1a0095b021 100644 --- a/mk/rte.app.mk +++ b/mk/rte.app.mk @@ -62,7 +62,6 @@ _LDLIBS-y += -L$(RTE_SDK_BIN)/lib ifeq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y) _LDLIBS-$(CONFIG_RTE_LIBRTE_KNI) += -lrte_kni -_LDLIBS-$(CONFIG_RTE_LIBRTE_IVSHMEM) += -lrte_ivshmem endif _LDLIBS-$(CONFIG_RTE_LIBRTE_PIPELINE) += -lrte_pipeline