get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/15051/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 15051,
    "url": "http://patches.dpdk.org/api/patches/15051/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1469795316-31740-1-git-send-email-david.marchand@6wind.com/",
    "project": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<1469795316-31740-1-git-send-email-david.marchand@6wind.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1469795316-31740-1-git-send-email-david.marchand@6wind.com",
    "date": "2016-07-29T12:28:36",
    "name": "[dpdk-dev] ivshmem: remove integration in dpdk",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "6961d300afb4bad31fba370f158e71e844ea54e3",
    "submitter": {
        "id": 3,
        "url": "http://patches.dpdk.org/api/people/3/?format=api",
        "name": "David Marchand",
        "email": "david.marchand@6wind.com"
    },
    "delegate": null,
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/1469795316-31740-1-git-send-email-david.marchand@6wind.com/mbox/",
    "series": [],
    "comments": "http://patches.dpdk.org/api/patches/15051/comments/",
    "check": "pending",
    "checks": "http://patches.dpdk.org/api/patches/15051/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [IPv6:::1])\n\tby dpdk.org (Postfix) with ESMTP id E67AD5588;\n\tFri, 29 Jul 2016 14:28:47 +0200 (CEST)",
            "from mail-wm0-f52.google.com (mail-wm0-f52.google.com\n\t[74.125.82.52]) by dpdk.org (Postfix) with ESMTP id C0FE25580\n\tfor <dev@dpdk.org>; Fri, 29 Jul 2016 14:28:46 +0200 (CEST)",
            "by mail-wm0-f52.google.com with SMTP id q128so288131041wma.1\n\tfor <dev@dpdk.org>; Fri, 29 Jul 2016 05:28:46 -0700 (PDT)",
            "from gloops.dev.6wind.com (144.77.126.78.rev.sfr.net.\n\t[78.126.77.144]) by smtp.gmail.com with ESMTPSA id\n\td8sm2870187wmi.0.2016.07.29.05.28.40\n\t(version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128);\n\tFri, 29 Jul 2016 05:28:40 -0700 (PDT)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=6wind-com.20150623.gappssmtp.com; s=20150623;\n\th=from:to:cc:subject:date:message-id:mime-version\n\t:content-transfer-encoding;\n\tbh=iuUyRqJMcTOBnLOKxS+YtQxUMyYfIRVQlUsqC7HVAhw=;\n\tb=w/nxfi1TdlwOyh6b/gMDBA9hNhGWJr1PNsQ2KQYDCBcZ8R6synqQIZX1T7OhbWhYJn\n\tlkQ8CoKOAi8QsaM93YVxy7t3J8tN3iuj8v8zqkS5a/rtUbaTjR0pLWZmCAYOdVtCBo2Z\n\tVWdVcwKTJiHNTEnf8lhx9k2EjxvwUsumT/gMWpaTwR7/pKZrsZIclm9RXsNWI06HCOhx\n\tg4YliCrSfubqWmmHboOlYE/nbi8Q8P58W8sBts811VW/PKPwLkD3eid01qvf75j9JaXX\n\tZU7ceLbLI+Bo6boT3WXSnPs09JcdvcMVr8WVzmW2wkERBZXYwIxHKDbPW7pGvzt0DUZO\n\tKOiw==",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20130820;\n\th=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version\n\t:content-transfer-encoding;\n\tbh=iuUyRqJMcTOBnLOKxS+YtQxUMyYfIRVQlUsqC7HVAhw=;\n\tb=Ia1C1v3TrFXMzC++nB4pMobVrJpSOmUVM/y2h5Uo9Ln1UDWE/1mLVusd78aOVwkHJ3\n\tS0HZaQV9kW2ifMixagiSmkolrQNFe93fAu6gN0a+mXjhWAyPI8PrNzhaeFqfxbGqmroi\n\t4qZHpvu4D1sLNfd73KUlZwwDJ4Kz5PEhg+y47QM+pw8UY0aot872GFaBr18gwg7spLT4\n\t0EohUhYr50y3rURPZi4wKYaWAZ/qGDYxfz55nzUqb3vyPry0l9xmPLT+95hRlIFJfhur\n\tiNRE+HalznkhQgeN/QC4nOT9pdb8MgWsSw7glOc2hgLQ0ZMCLeGUI/UahYktGg8Tpd9j\n\tQSwg==",
        "X-Gm-Message-State": "AEkooutLO+ohM6ppbhxvXO8qjsACCrSwcYtlRJJ4GUPRwCx5CWdh5aSLRvw9hHn1ElH4ZurO",
        "X-Received": "by 10.28.69.6 with SMTP id s6mr46006606wma.46.1469795322027;\n\tFri, 29 Jul 2016 05:28:42 -0700 (PDT)",
        "From": "David Marchand <david.marchand@6wind.com>",
        "To": "dev@dpdk.org",
        "Cc": "thomas.monjalon@6wind.com,\n\tanatoly.burakov@intel.com",
        "Date": "Fri, 29 Jul 2016 14:28:36 +0200",
        "Message-Id": "<1469795316-31740-1-git-send-email-david.marchand@6wind.com>",
        "X-Mailer": "git-send-email 1.9.1",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain; charset=UTF-8",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[dpdk-dev] [PATCH] ivshmem: remove integration in dpdk",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "patches and discussions about DPDK <dev.dpdk.org>",
        "List-Unsubscribe": "<http://dpdk.org/ml/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://dpdk.org/ml/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<http://dpdk.org/ml/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "Following discussions on the mailing list [1] and since nobody stood up to\nimplement the necessary cleanups, here is the ivshmem integration removal.\n\nThere is not much to say about this patch, a lot of code is being removed.\nThe default configuration file for packet_ordering example is replaced with\nthe \"native\" x86 file.\nThe only tricky part is in eal_memory with the memseg index stuff.\n\nMore cleanups can be done after this but will come in subsequent patchsets.\n\n[1]: http://dpdk.org/ml/archives/dev/2016-June/040844.html\n\nSigned-off-by: David Marchand <david.marchand@6wind.com>\n---\n MAINTAINERS                                  |   8 -\n app/test/Makefile                            |   1 -\n app/test/autotest_data.py                    |   6 -\n app/test/test.c                              |   3 -\n app/test/test.h                              |   1 -\n app/test/test_ivshmem.c                      | 433 ------------\n config/defconfig_arm64-armv8a-linuxapp-gcc   |   1 -\n config/defconfig_x86_64-ivshmem-linuxapp-gcc |  49 --\n config/defconfig_x86_64-ivshmem-linuxapp-icc |  49 --\n doc/api/doxy-api-index.md                    |   1 -\n doc/api/doxy-api.conf                        |   1 -\n doc/api/examples.dox                         |   2 -\n doc/guides/linux_gsg/build_dpdk.rst          |   2 +-\n doc/guides/linux_gsg/quick_start.rst         |  14 +-\n doc/guides/prog_guide/img/ivshmem.png        | Bin 44920 -> 0 bytes\n doc/guides/prog_guide/index.rst              |   1 -\n doc/guides/prog_guide/ivshmem_lib.rst        | 160 -----\n doc/guides/prog_guide/source_org.rst         |   1 -\n doc/guides/rel_notes/deprecation.rst         |   3 -\n doc/guides/rel_notes/release_16_11.rst       |   3 +\n examples/Makefile                            |   1 -\n examples/l2fwd-ivshmem/Makefile              |  43 --\n examples/l2fwd-ivshmem/guest/Makefile        |  50 --\n examples/l2fwd-ivshmem/guest/guest.c         | 452 -------------\n examples/l2fwd-ivshmem/host/Makefile         |  50 --\n examples/l2fwd-ivshmem/host/host.c           | 895 -------------------------\n examples/l2fwd-ivshmem/include/common.h      | 111 ----\n examples/packet_ordering/Makefile            |   2 +-\n lib/Makefile                                 |   1 -\n lib/librte_eal/common/eal_common_memzone.c   |  12 -\n lib/librte_eal/common/eal_private.h          |  22 -\n lib/librte_eal/common/include/rte_memory.h   |   3 -\n lib/librte_eal/common/include/rte_memzone.h  |   7 +-\n lib/librte_eal/common/malloc_heap.c          |   8 -\n lib/librte_eal/linuxapp/eal/Makefile         |   9 -\n lib/librte_eal/linuxapp/eal/eal.c            |  10 -\n lib/librte_eal/linuxapp/eal/eal_ivshmem.c    | 954 ---------------------------\n lib/librte_eal/linuxapp/eal/eal_memory.c     |  30 +-\n lib/librte_ivshmem/Makefile                  |  54 --\n lib/librte_ivshmem/rte_ivshmem.c             | 919 --------------------------\n lib/librte_ivshmem/rte_ivshmem.h             | 165 -----\n lib/librte_ivshmem/rte_ivshmem_version.map   |  12 -\n mk/rte.app.mk                                |   1 -\n 43 files changed, 13 insertions(+), 4537 deletions(-)\n delete mode 100644 app/test/test_ivshmem.c\n delete mode 100644 config/defconfig_x86_64-ivshmem-linuxapp-gcc\n delete mode 100644 config/defconfig_x86_64-ivshmem-linuxapp-icc\n delete mode 100644 doc/guides/prog_guide/img/ivshmem.png\n delete mode 100644 doc/guides/prog_guide/ivshmem_lib.rst\n delete mode 100644 examples/l2fwd-ivshmem/Makefile\n delete mode 100644 examples/l2fwd-ivshmem/guest/Makefile\n delete mode 100644 examples/l2fwd-ivshmem/guest/guest.c\n delete mode 100644 examples/l2fwd-ivshmem/host/Makefile\n delete mode 100644 examples/l2fwd-ivshmem/host/host.c\n delete mode 100644 examples/l2fwd-ivshmem/include/common.h\n delete mode 100644 lib/librte_eal/linuxapp/eal/eal_ivshmem.c\n delete mode 100644 lib/librte_ivshmem/Makefile\n delete mode 100644 lib/librte_ivshmem/rte_ivshmem.c\n delete mode 100644 lib/librte_ivshmem/rte_ivshmem.h\n delete mode 100644 lib/librte_ivshmem/rte_ivshmem_version.map",
    "diff": "diff --git a/MAINTAINERS b/MAINTAINERS\nindex 6536c6b..5e3d825 100644\n--- a/MAINTAINERS\n+++ b/MAINTAINERS\n@@ -546,14 +546,6 @@ F: app/test/test_cmdline*\n F: examples/cmdline/\n F: doc/guides/sample_app_ug/cmd_line.rst\n \n-Qemu IVSHMEM\n-M: Anatoly Burakov <anatoly.burakov@intel.com>\n-F: lib/librte_ivshmem/\n-F: lib/librte_eal/linuxapp/eal/eal_ivshmem.c\n-F: doc/guides/prog_guide/ivshmem_lib.rst\n-F: app/test/test_ivshmem.c\n-F: examples/l2fwd-ivshmem/\n-\n Key/Value parsing\n M: Olivier Matz <olivier.matz@6wind.com>\n F: lib/librte_kvargs/\ndiff --git a/app/test/Makefile b/app/test/Makefile\nindex 49ea195..611d77a 100644\n--- a/app/test/Makefile\n+++ b/app/test/Makefile\n@@ -167,7 +167,6 @@ SRCS-$(CONFIG_RTE_LIBRTE_KNI) += test_kni.c\n SRCS-$(CONFIG_RTE_LIBRTE_POWER) += test_power.c test_power_acpi_cpufreq.c\n SRCS-$(CONFIG_RTE_LIBRTE_POWER) += test_power_kvm_vm.c\n SRCS-y += test_common.c\n-SRCS-$(CONFIG_RTE_LIBRTE_IVSHMEM) += test_ivshmem.c\n \n SRCS-$(CONFIG_RTE_LIBRTE_DISTRIBUTOR) += test_distributor.c\n SRCS-$(CONFIG_RTE_LIBRTE_DISTRIBUTOR) += test_distributor_perf.c\ndiff --git a/app/test/autotest_data.py b/app/test/autotest_data.py\nindex defd46e..9e8fd94 100644\n--- a/app/test/autotest_data.py\n+++ b/app/test/autotest_data.py\n@@ -174,12 +174,6 @@ parallel_test_group_list = [\n \t\t\t\"Report\" :  None,\n \t\t},\n \t\t{\n-\t\t \"Name\" :\t\"IVSHMEM autotest\",\n-\t\t \"Command\" : \t\"ivshmem_autotest\",\n-\t\t \"Func\" :\tdefault_autotest,\n-\t\t \"Report\" :\tNone,\n-\t\t},\n-\t\t{\n \t\t \"Name\" :\t\"Memcpy autotest\",\n \t\t \"Command\" : \t\"memcpy_autotest\",\n \t\t \"Func\" :\tdefault_autotest,\ndiff --git a/app/test/test.c b/app/test/test.c\nindex ccad0e3..cd0e784 100644\n--- a/app/test/test.c\n+++ b/app/test/test.c\n@@ -95,9 +95,6 @@ do_recursive_call(void)\n \t\t\t{ \"test_memory_flags\", no_action },\n \t\t\t{ \"test_file_prefix\", no_action },\n \t\t\t{ \"test_no_huge_flag\", no_action },\n-#ifdef RTE_LIBRTE_IVSHMEM\n-\t\t\t{ \"test_ivshmem\", test_ivshmem },\n-#endif\n \t};\n \n \tif (recursive_call == NULL)\ndiff --git a/app/test/test.h b/app/test/test.h\nindex 467b9c0..b250c84 100644\n--- a/app/test/test.h\n+++ b/app/test/test.h\n@@ -235,7 +235,6 @@ int test_pci_run;\n \n int test_mp_secondary(void);\n \n-int test_ivshmem(void);\n int test_set_rxtx_conf(cmdline_fixed_string_t mode);\n int test_set_rxtx_anchor(cmdline_fixed_string_t type);\n int test_set_rxtx_sc(cmdline_fixed_string_t type);\ndiff --git a/app/test/test_ivshmem.c b/app/test/test_ivshmem.c\ndeleted file mode 100644\nindex ae9fd6c..0000000\n--- a/app/test/test_ivshmem.c\n+++ /dev/null\n@@ -1,433 +0,0 @@\n-/*-\n- *   BSD LICENSE\n- *\n- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.\n- *   All rights reserved.\n- *\n- *   Redistribution and use in source and binary forms, with or without\n- *   modification, are permitted provided that the following conditions\n- *   are met:\n- *\n- *     * Redistributions of source code must retain the above copyright\n- *       notice, this list of conditions and the following disclaimer.\n- *     * Redistributions in binary form must reproduce the above copyright\n- *       notice, this list of conditions and the following disclaimer in\n- *       the documentation and/or other materials provided with the\n- *       distribution.\n- *     * Neither the name of Intel Corporation nor the names of its\n- *       contributors may be used to endorse or promote products derived\n- *       from this software without specific prior written permission.\n- *\n- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n- *   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n- */\n-\n-#include <fcntl.h>\n-#include <limits.h>\n-#include <unistd.h>\n-#include <string.h>\n-#include <sys/mman.h>\n-#include <sys/wait.h>\n-#include <stdio.h>\n-\n-#include <cmdline_parse.h>\n-\n-#include \"test.h\"\n-\n-#include <rte_common.h>\n-#include <rte_ivshmem.h>\n-#include <rte_string_fns.h>\n-#include \"process.h\"\n-\n-#define DUPLICATE_METADATA \"duplicate\"\n-#define METADATA_NAME \"metadata\"\n-#define NONEXISTENT_METADATA \"nonexistent\"\n-#define FIRST_TEST 'a'\n-\n-#define launch_proc(ARGV) process_dup(ARGV, \\\n-\t\tsizeof(ARGV)/(sizeof(ARGV[0])), \"test_ivshmem\")\n-\n-#define ASSERT(cond,msg) do {\t\t\t\t\t\t\\\n-\t\tif (!(cond)) {\t\t\t\t\t\t\t\t\\\n-\t\t\tprintf(\"**** TEST %s() failed: %s\\n\",\t\\\n-\t\t\t\t__func__, msg);\t\t\t\t\t\t\\\n-\t\t\treturn -1;\t\t\t\t\t\t\t\t\\\n-\t\t}\t\t\t\t\t\t\t\t\t\t\t\\\n-} while(0)\n-\n-static char*\n-get_current_prefix(char * prefix, int size)\n-{\n-\tchar path[PATH_MAX] = {0};\n-\tchar buf[PATH_MAX] = {0};\n-\n-\t/* get file for config (fd is always 3) */\n-\tsnprintf(path, sizeof(path), \"/proc/self/fd/%d\", 3);\n-\n-\t/* return NULL on error */\n-\tif (readlink(path, buf, sizeof(buf)) == -1)\n-\t\treturn NULL;\n-\n-\t/* get the basename */\n-\tsnprintf(buf, sizeof(buf), \"%s\", basename(buf));\n-\n-\t/* copy string all the way from second char up to start of _config */\n-\tsnprintf(prefix, size, \"%.*s\",\n-\t\t\t(int)(strnlen(buf, sizeof(buf)) - sizeof(\"_config\")),\n-\t\t\t&buf[1]);\n-\n-\treturn prefix;\n-}\n-\n-static struct rte_ivshmem_metadata*\n-mmap_metadata(const char *name)\n-{\n-\tint fd;\n-\tchar pathname[PATH_MAX];\n-\tstruct rte_ivshmem_metadata *metadata;\n-\n-\tsnprintf(pathname, sizeof(pathname),\n-\t\t\t\"/var/run/.dpdk_ivshmem_metadata_%s\", name);\n-\n-\tfd = open(pathname, O_RDWR, 0660);\n-\tif (fd < 0)\n-\t\treturn NULL;\n-\n-\tmetadata = (struct rte_ivshmem_metadata*) mmap(NULL,\n-\t\t\tsizeof(struct rte_ivshmem_metadata), PROT_READ | PROT_WRITE,\n-\t\t\tMAP_SHARED, fd, 0);\n-\n-\tif (metadata == MAP_FAILED)\n-\t\treturn NULL;\n-\n-\tclose(fd);\n-\n-\treturn metadata;\n-}\n-\n-static int\n-create_duplicate(void)\n-{\n-\t/* create a metadata that another process will then try to overwrite */\n-\tASSERT (rte_ivshmem_metadata_create(DUPLICATE_METADATA) == 0,\n-\t\t\t\"Creating metadata failed\");\n-\treturn 0;\n-}\n-\n-static int\n-test_ivshmem_create_lots_of_memzones(void)\n-{\n-\tint i;\n-\tchar name[IVSHMEM_NAME_LEN];\n-\tconst struct rte_memzone *mz;\n-\n-\tASSERT(rte_ivshmem_metadata_create(METADATA_NAME) == 0,\n-\t\t\t\"Failed to create metadata\");\n-\n-\tfor (i = 0; i < RTE_LIBRTE_IVSHMEM_MAX_ENTRIES; i++) {\n-\t\tsnprintf(name, sizeof(name), \"mz_%i\", i);\n-\n-\t\tmz = rte_memzone_reserve(name, RTE_CACHE_LINE_SIZE, SOCKET_ID_ANY, 0);\n-\t\tASSERT(mz != NULL, \"Failed to reserve memzone\");\n-\n-\t\tASSERT(rte_ivshmem_metadata_add_memzone(mz, METADATA_NAME) == 0,\n-\t\t\t\t\"Failed to add memzone\");\n-\t}\n-\tmz = rte_memzone_reserve(\"one too many\", RTE_CACHE_LINE_SIZE, SOCKET_ID_ANY, 0);\n-\tASSERT(mz != NULL, \"Failed to reserve memzone\");\n-\n-\tASSERT(rte_ivshmem_metadata_add_memzone(mz, METADATA_NAME) < 0,\n-\t\t\"Metadata should have been full\");\n-\n-\treturn 0;\n-}\n-\n-static int\n-test_ivshmem_create_duplicate_memzone(void)\n-{\n-\tconst struct rte_memzone *mz;\n-\n-\tASSERT(rte_ivshmem_metadata_create(METADATA_NAME) == 0,\n-\t\t\t\"Failed to create metadata\");\n-\n-\tmz = rte_memzone_reserve(\"mz\", RTE_CACHE_LINE_SIZE, SOCKET_ID_ANY, 0);\n-\tASSERT(mz != NULL, \"Failed to reserve memzone\");\n-\n-\tASSERT(rte_ivshmem_metadata_add_memzone(mz, METADATA_NAME) == 0,\n-\t\t\t\"Failed to add memzone\");\n-\n-\tASSERT(rte_ivshmem_metadata_add_memzone(mz, METADATA_NAME) < 0,\n-\t\t\t\"Added the same memzone twice\");\n-\n-\treturn 0;\n-}\n-\n-static int\n-test_ivshmem_api_test(void)\n-{\n-\tconst struct rte_memzone * mz;\n-\tstruct rte_mempool * mp;\n-\tstruct rte_ring * r;\n-\tchar buf[BUFSIZ];\n-\n-\tmemset(buf, 0, sizeof(buf));\n-\n-\tr = rte_ring_create(\"ring\", 1, SOCKET_ID_ANY, 0);\n-\tmp = rte_mempool_create(\"mempool\", 1, 1, 1, 1, NULL, NULL, NULL, NULL,\n-\t\t\tSOCKET_ID_ANY, 0);\n-\tmz = rte_memzone_reserve(\"memzone\", 64, SOCKET_ID_ANY, 0);\n-\n-\tASSERT(r != NULL, \"Failed to create ring\");\n-\tASSERT(mp != NULL, \"Failed to create mempool\");\n-\tASSERT(mz != NULL, \"Failed to reserve memzone\");\n-\n-\t/* try to create NULL metadata */\n-\tASSERT(rte_ivshmem_metadata_create(NULL) < 0,\n-\t\t\t\"Created metadata with NULL name\");\n-\n-\t/* create valid metadata to do tests on */\n-\tASSERT(rte_ivshmem_metadata_create(METADATA_NAME) == 0,\n-\t\t\t\"Failed to create metadata\");\n-\n-\t/* test adding memzone */\n-\tASSERT(rte_ivshmem_metadata_add_memzone(NULL, NULL) < 0,\n-\t\t\t\"Added NULL memzone to NULL metadata\");\n-\tASSERT(rte_ivshmem_metadata_add_memzone(NULL, METADATA_NAME) < 0,\n-\t\t\t\"Added NULL memzone\");\n-\tASSERT(rte_ivshmem_metadata_add_memzone(mz, NULL) < 0,\n-\t\t\t\"Added memzone to NULL metadata\");\n-\tASSERT(rte_ivshmem_metadata_add_memzone(mz, NONEXISTENT_METADATA) < 0,\n-\t\t\t\"Added memzone to nonexistent metadata\");\n-\n-\t/* test adding ring */\n-\tASSERT(rte_ivshmem_metadata_add_ring(NULL, NULL) < 0,\n-\t\t\t\"Added NULL ring to NULL metadata\");\n-\tASSERT(rte_ivshmem_metadata_add_ring(NULL, METADATA_NAME) < 0,\n-\t\t\t\"Added NULL ring\");\n-\tASSERT(rte_ivshmem_metadata_add_ring(r, NULL) < 0,\n-\t\t\t\"Added ring to NULL metadata\");\n-\tASSERT(rte_ivshmem_metadata_add_ring(r, NONEXISTENT_METADATA) < 0,\n-\t\t\t\"Added ring to nonexistent metadata\");\n-\n-\t/* test adding mempool */\n-\tASSERT(rte_ivshmem_metadata_add_mempool(NULL, NULL) < 0,\n-\t\t\t\"Added NULL mempool to NULL metadata\");\n-\tASSERT(rte_ivshmem_metadata_add_mempool(NULL, METADATA_NAME) < 0,\n-\t\t\t\"Added NULL mempool\");\n-\tASSERT(rte_ivshmem_metadata_add_mempool(mp, NULL) < 0,\n-\t\t\t\"Added mempool to NULL metadata\");\n-\tASSERT(rte_ivshmem_metadata_add_mempool(mp, NONEXISTENT_METADATA) < 0,\n-\t\t\t\"Added mempool to nonexistent metadata\");\n-\n-\t/* test creating command line */\n-\tASSERT(rte_ivshmem_metadata_cmdline_generate(NULL, sizeof(buf), METADATA_NAME) < 0,\n-\t\t\t\"Written command line into NULL buffer\");\n-\tASSERT(strnlen(buf, sizeof(buf)) == 0, \"Buffer is not empty\");\n-\n-\tASSERT(rte_ivshmem_metadata_cmdline_generate(buf, 0, METADATA_NAME) < 0,\n-\t\t\t\"Written command line into small buffer\");\n-\tASSERT(strnlen(buf, sizeof(buf)) == 0, \"Buffer is not empty\");\n-\n-\tASSERT(rte_ivshmem_metadata_cmdline_generate(buf, sizeof(buf), NULL) < 0,\n-\t\t\t\"Written command line for NULL metadata\");\n-\tASSERT(strnlen(buf, sizeof(buf)) == 0, \"Buffer is not empty\");\n-\n-\tASSERT(rte_ivshmem_metadata_cmdline_generate(buf, sizeof(buf),\n-\t\t\tNONEXISTENT_METADATA) < 0,\n-\t\t\t\"Writen command line for nonexistent metadata\");\n-\tASSERT(strnlen(buf, sizeof(buf)) == 0, \"Buffer is not empty\");\n-\n-\t/* add stuff to config */\n-\tASSERT(rte_ivshmem_metadata_add_memzone(mz, METADATA_NAME) == 0,\n-\t\t\t\"Failed to add memzone to valid config\");\n-\tASSERT(rte_ivshmem_metadata_add_ring(r, METADATA_NAME) == 0,\n-\t\t\t\"Failed to add ring to valid config\");\n-\tASSERT(rte_ivshmem_metadata_add_mempool(mp, METADATA_NAME) == 0,\n-\t\t\t\"Failed to add mempool to valid config\");\n-\n-\t/* create config */\n-\tASSERT(rte_ivshmem_metadata_cmdline_generate(buf, sizeof(buf),\n-\t\t\tMETADATA_NAME) == 0, \"Failed to write command-line\");\n-\n-\t/* check if something was written */\n-\tASSERT(strnlen(buf, sizeof(buf)) != 0, \"Buffer is empty\");\n-\n-\t/* make sure we don't segfault */\n-\trte_ivshmem_metadata_dump(stdout, NULL);\n-\n-\t/* dump our metadata */\n-\trte_ivshmem_metadata_dump(stdout, METADATA_NAME);\n-\n-\treturn 0;\n-}\n-\n-static int\n-test_ivshmem_create_duplicate_metadata(void)\n-{\n-\tASSERT(rte_ivshmem_metadata_create(DUPLICATE_METADATA) < 0,\n-\t\t\t\"Creating duplicate metadata should have failed\");\n-\n-\treturn 0;\n-}\n-\n-static int\n-test_ivshmem_create_metadata_config(void)\n-{\n-\tstruct rte_ivshmem_metadata *metadata;\n-\n-\trte_ivshmem_metadata_create(METADATA_NAME);\n-\n-\tmetadata = mmap_metadata(METADATA_NAME);\n-\n-\tASSERT(metadata != MAP_FAILED, \"Metadata mmaping failed\");\n-\n-\tASSERT(metadata->magic_number == IVSHMEM_MAGIC,\n-\t\t\t\"Magic number is not that magic\");\n-\n-\tASSERT(strncmp(metadata->name, METADATA_NAME, sizeof(metadata->name)) == 0,\n-\t\t\t\"Name has not been set up\");\n-\n-\tASSERT(metadata->entry[0].offset == 0, \"Offest is not initialized\");\n-\tASSERT(metadata->entry[0].mz.addr == 0, \"mz.addr is not initialized\");\n-\tASSERT(metadata->entry[0].mz.len == 0, \"mz.len is not initialized\");\n-\n-\treturn 0;\n-}\n-\n-static int\n-test_ivshmem_create_multiple_metadata_configs(void)\n-{\n-\tint i;\n-\tchar name[IVSHMEM_NAME_LEN];\n-\tstruct rte_ivshmem_metadata *metadata;\n-\n-\tfor (i = 0; i < RTE_LIBRTE_IVSHMEM_MAX_METADATA_FILES / 2; i++) {\n-\t\tsnprintf(name, sizeof(name), \"test_%d\", i);\n-\t\trte_ivshmem_metadata_create(name);\n-\t\tmetadata = mmap_metadata(name);\n-\n-\t\tASSERT(metadata->magic_number == IVSHMEM_MAGIC,\n-\t\t\t\t\"Magic number is not that magic\");\n-\n-\t\tASSERT(strncmp(metadata->name, name, sizeof(metadata->name)) == 0,\n-\t\t\t\t\"Name has not been set up\");\n-\t}\n-\n-\treturn 0;\n-}\n-\n-static int\n-test_ivshmem_create_too_many_metadata_configs(void)\n-{\n-\tint i;\n-\tchar name[IVSHMEM_NAME_LEN];\n-\n-\tfor (i = 0; i < RTE_LIBRTE_IVSHMEM_MAX_METADATA_FILES; i++) {\n-\t\tsnprintf(name, sizeof(name), \"test_%d\", i);\n-\t\tASSERT(rte_ivshmem_metadata_create(name) == 0,\n-\t\t\t\t\"Create config file failed\");\n-\t}\n-\n-\tASSERT(rte_ivshmem_metadata_create(name) < 0,\n-\t\t\t\"Create config file didn't fail\");\n-\n-\treturn 0;\n-}\n-\n-enum rte_ivshmem_tests {\n-\t_test_ivshmem_api_test = 0,\n-\t_test_ivshmem_create_metadata_config,\n-\t_test_ivshmem_create_multiple_metadata_configs,\n-\t_test_ivshmem_create_too_many_metadata_configs,\n-\t_test_ivshmem_create_duplicate_metadata,\n-\t_test_ivshmem_create_lots_of_memzones,\n-\t_test_ivshmem_create_duplicate_memzone,\n-\t_last_test,\n-};\n-\n-#define RTE_IVSHMEM_TEST_ID \"RTE_IVSHMEM_TEST_ID\"\n-\n-static int\n-launch_all_tests_on_secondary_processes(void)\n-{\n-\tint ret = 0;\n-\tchar id;\n-\tchar testid;\n-\tchar tmp[PATH_MAX] = {0};\n-\tchar prefix[PATH_MAX] = {0};\n-\n-\tget_current_prefix(tmp, sizeof(tmp));\n-\n-\tsnprintf(prefix, sizeof(prefix), \"--file-prefix=%s\", tmp);\n-\n-\tconst char *argv[] = { prgname, \"-c\", \"1\", \"-n\", \"3\",\n-\t\t\t\"--proc-type=secondary\", prefix };\n-\n-\tfor (id = 0; id < _last_test; id++) {\n-\t\ttestid = (char)(FIRST_TEST + id);\n-\t\tsetenv(RTE_IVSHMEM_TEST_ID, &testid, 1);\n-\t\tif (launch_proc(argv) != 0)\n-\t\t\treturn -1;\n-\t}\n-\treturn ret;\n-}\n-\n-int\n-test_ivshmem(void)\n-{\n-\tint testid;\n-\n-\t/* We want to have a clean execution for every test without exposing\n-\t * private global data structures in rte_ivshmem so we launch each test\n-\t * on a different secondary process. */\n-\tif (rte_eal_process_type() == RTE_PROC_PRIMARY) {\n-\n-\t\t/* first, create metadata */\n-\t\tASSERT(create_duplicate() == 0, \"Creating metadata failed\");\n-\n-\t\treturn launch_all_tests_on_secondary_processes();\n-\t}\n-\n-\ttestid = *(getenv(RTE_IVSHMEM_TEST_ID)) - FIRST_TEST;\n-\n-\tprintf(\"Secondary process running test %d \\n\", testid);\n-\n-\tswitch (testid) {\n-\tcase _test_ivshmem_api_test:\n-\t\treturn test_ivshmem_api_test();\n-\n-\tcase _test_ivshmem_create_metadata_config:\n-\t\treturn test_ivshmem_create_metadata_config();\n-\n-\tcase _test_ivshmem_create_multiple_metadata_configs:\n-\t\treturn test_ivshmem_create_multiple_metadata_configs();\n-\n-\tcase _test_ivshmem_create_too_many_metadata_configs:\n-\t\treturn test_ivshmem_create_too_many_metadata_configs();\n-\n-\tcase _test_ivshmem_create_duplicate_metadata:\n-\t\treturn test_ivshmem_create_duplicate_metadata();\n-\n-\tcase _test_ivshmem_create_lots_of_memzones:\n-\t\treturn test_ivshmem_create_lots_of_memzones();\n-\n-\tcase _test_ivshmem_create_duplicate_memzone:\n-\t\treturn test_ivshmem_create_duplicate_memzone();\n-\n-\tdefault:\n-\t\tbreak;\n-\t}\n-\n-\treturn -1;\n-}\n-\n-REGISTER_TEST_COMMAND(ivshmem_autotest, test_ivshmem);\ndiff --git a/config/defconfig_arm64-armv8a-linuxapp-gcc b/config/defconfig_arm64-armv8a-linuxapp-gcc\nindex 1a17126..73f4733 100644\n--- a/config/defconfig_arm64-armv8a-linuxapp-gcc\n+++ b/config/defconfig_arm64-armv8a-linuxapp-gcc\n@@ -44,7 +44,6 @@ CONFIG_RTE_TOOLCHAIN_GCC=y\n \n CONFIG_RTE_EAL_IGB_UIO=n\n \n-CONFIG_RTE_LIBRTE_IVSHMEM=n\n CONFIG_RTE_LIBRTE_FM10K_PMD=n\n CONFIG_RTE_LIBRTE_I40E_PMD=n\n \ndiff --git a/config/defconfig_x86_64-ivshmem-linuxapp-gcc b/config/defconfig_x86_64-ivshmem-linuxapp-gcc\ndeleted file mode 100644\nindex 41ac5c3..0000000\n--- a/config/defconfig_x86_64-ivshmem-linuxapp-gcc\n+++ /dev/null\n@@ -1,49 +0,0 @@\n-#   BSD LICENSE\n-#\n-#   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.\n-#   All rights reserved.\n-#\n-#   Redistribution and use in source and binary forms, with or without\n-#   modification, are permitted provided that the following conditions\n-#   are met:\n-#\n-#     * Redistributions of source code must retain the above copyright\n-#       notice, this list of conditions and the following disclaimer.\n-#     * Redistributions in binary form must reproduce the above copyright\n-#       notice, this list of conditions and the following disclaimer in\n-#       the documentation and/or other materials provided with the\n-#       distribution.\n-#     * Neither the name of Intel Corporation nor the names of its\n-#       contributors may be used to endorse or promote products derived\n-#       from this software without specific prior written permission.\n-#\n-#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n-#   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n-#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n-#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n-#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n-#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n-#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n-#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n-#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n-#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n-#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n-#\n-\n-#\n-# use default config\n-#\n-\n-#include \"defconfig_x86_64-native-linuxapp-gcc\"\n-\n-#\n-# Compile IVSHMEM library\n-#\n-CONFIG_RTE_LIBRTE_IVSHMEM=y\n-CONFIG_RTE_LIBRTE_IVSHMEM_DEBUG=n\n-CONFIG_RTE_LIBRTE_IVSHMEM_MAX_PCI_DEVS=4\n-CONFIG_RTE_LIBRTE_IVSHMEM_MAX_ENTRIES=128\n-CONFIG_RTE_LIBRTE_IVSHMEM_MAX_METADATA_FILES=32\n-\n-# Set EAL to single file segments\n-CONFIG_RTE_EAL_SINGLE_FILE_SEGMENTS=y\n\\ No newline at end of file\ndiff --git a/config/defconfig_x86_64-ivshmem-linuxapp-icc b/config/defconfig_x86_64-ivshmem-linuxapp-icc\ndeleted file mode 100644\nindex 77fec93..0000000\n--- a/config/defconfig_x86_64-ivshmem-linuxapp-icc\n+++ /dev/null\n@@ -1,49 +0,0 @@\n-#   BSD LICENSE\n-#\n-#   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.\n-#   All rights reserved.\n-#\n-#   Redistribution and use in source and binary forms, with or without\n-#   modification, are permitted provided that the following conditions\n-#   are met:\n-#\n-#     * Redistributions of source code must retain the above copyright\n-#       notice, this list of conditions and the following disclaimer.\n-#     * Redistributions in binary form must reproduce the above copyright\n-#       notice, this list of conditions and the following disclaimer in\n-#       the documentation and/or other materials provided with the\n-#       distribution.\n-#     * Neither the name of Intel Corporation nor the names of its\n-#       contributors may be used to endorse or promote products derived\n-#       from this software without specific prior written permission.\n-#\n-#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n-#   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n-#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n-#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n-#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n-#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n-#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n-#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n-#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n-#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n-#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n-#\n-\n-#\n-# use default config\n-#\n-\n-#include \"defconfig_x86_64-native-linuxapp-icc\"\n-\n-#\n-# Compile IVSHMEM library\n-#\n-CONFIG_RTE_LIBRTE_IVSHMEM=y\n-CONFIG_RTE_LIBRTE_IVSHMEM_DEBUG=n\n-CONFIG_RTE_LIBRTE_IVSHMEM_MAX_PCI_DEVS=4\n-CONFIG_RTE_LIBRTE_IVSHMEM_MAX_ENTRIES=128\n-CONFIG_RTE_LIBRTE_IVSHMEM_MAX_METADATA_FILES=32\n-\n-# Set EAL to single file segments\n-CONFIG_RTE_EAL_SINGLE_FILE_SEGMENTS=y\ndiff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md\nindex 2284a53..6675f96 100644\n--- a/doc/api/doxy-api-index.md\n+++ b/doc/api/doxy-api-index.md\n@@ -108,7 +108,6 @@ There are many libraries, so their headers may be grouped by topics:\n   [reorder]            (@ref rte_reorder.h),\n   [tailq]              (@ref rte_tailq.h),\n   [bitmap]             (@ref rte_bitmap.h),\n-  [ivshmem]            (@ref rte_ivshmem.h)\n \n - **packet framework**:\n   * [port]             (@ref rte_port.h):\ndiff --git a/doc/api/doxy-api.conf b/doc/api/doxy-api.conf\nindex af5d6dd..9dc7ae5 100644\n--- a/doc/api/doxy-api.conf\n+++ b/doc/api/doxy-api.conf\n@@ -43,7 +43,6 @@ INPUT                   = doc/api/doxy-api-index.md \\\n                           lib/librte_ether \\\n                           lib/librte_hash \\\n                           lib/librte_ip_frag \\\n-                          lib/librte_ivshmem \\\n                           lib/librte_jobstats \\\n                           lib/librte_kni \\\n                           lib/librte_kvargs \\\ndiff --git a/doc/api/examples.dox b/doc/api/examples.dox\nindex 200af0b..1626852 100644\n--- a/doc/api/examples.dox\n+++ b/doc/api/examples.dox\n@@ -40,8 +40,6 @@\n @example ipv4_multicast/main.c\n @example kni/main.c\n @example l2fwd-crypto/main.c\n-@example l2fwd-ivshmem/guest/guest.c\n-@example l2fwd-ivshmem/host/host.c\n @example l2fwd-jobstats/main.c\n @example l2fwd-keepalive/main.c\n @example l2fwd/main.c\ndiff --git a/doc/guides/linux_gsg/build_dpdk.rst b/doc/guides/linux_gsg/build_dpdk.rst\nindex f8007b3..474598a 100644\n--- a/doc/guides/linux_gsg/build_dpdk.rst\n+++ b/doc/guides/linux_gsg/build_dpdk.rst\n@@ -75,7 +75,7 @@ where:\n \n * ``ARCH`` can be:  ``i686``, ``x86_64``, ``ppc_64``\n \n-* ``MACHINE`` can be:  ``native``, ``ivshmem``, ``power8``\n+* ``MACHINE`` can be:  ``native``, ``power8``\n \n * ``EXECENV`` can be:  ``linuxapp``,  ``bsdapp``\n \ndiff --git a/doc/guides/linux_gsg/quick_start.rst b/doc/guides/linux_gsg/quick_start.rst\nindex 8789b58..6e858c2 100644\n--- a/doc/guides/linux_gsg/quick_start.rst\n+++ b/doc/guides/linux_gsg/quick_start.rst\n@@ -126,19 +126,15 @@ Some options in the script prompt the user for further data before proceeding.\n \n     [3] ppc_64-power8-linuxapp-gcc\n \n-    [4] x86_64-ivshmem-linuxapp-gcc\n+    [4] x86_64-native-bsdapp-clang\n \n-    [5] x86_64-ivshmem-linuxapp-icc\n+    [5] x86_64-native-bsdapp-gcc\n \n-    [6] x86_64-native-bsdapp-clang\n+    [6] x86_64-native-linuxapp-clang\n \n-    [7] x86_64-native-bsdapp-gcc\n+    [7] x86_64-native-linuxapp-gcc\n \n-    [8] x86_64-native-linuxapp-clang\n-\n-    [9] x86_64-native-linuxapp-gcc\n-\n-    [10] x86_64-native-linuxapp-icc\n+    [8] x86_64-native-linuxapp-icc\n \n     ------------------------------------------------------------------------\n \ndiff --git a/doc/guides/prog_guide/img/ivshmem.png b/doc/guides/prog_guide/img/ivshmem.png\ndeleted file mode 100644\nindex 2b34a2cfdf3d65025c1f942f5cc1f2a1ef05892c..0000000000000000000000000000000000000000\nGIT binary patch\nliteral 0\nHcmV?d00001\n\nliteral 44920\n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\nJ)d1t*{{tHm(mwzI\n\ndiff --git a/doc/guides/prog_guide/index.rst b/doc/guides/prog_guide/index.rst\nindex 07a4d35..e5a50a8 100644\n--- a/doc/guides/prog_guide/index.rst\n+++ b/doc/guides/prog_guide/index.rst\n@@ -43,7 +43,6 @@ Programmer's Guide\n     mbuf_lib\n     poll_mode_drv\n     cryptodev_lib\n-    ivshmem_lib\n     link_bonding_poll_mode_drv_lib\n     timer_lib\n     hash_lib\ndiff --git a/doc/guides/prog_guide/ivshmem_lib.rst b/doc/guides/prog_guide/ivshmem_lib.rst\ndeleted file mode 100644\nindex b8a32e4..0000000\n--- a/doc/guides/prog_guide/ivshmem_lib.rst\n+++ /dev/null\n@@ -1,160 +0,0 @@\n-..  BSD LICENSE\n-    Copyright(c) 2010-2014 Intel Corporation. All rights reserved.\n-    All rights reserved.\n-\n-    Redistribution and use in source and binary forms, with or without\n-    modification, are permitted provided that the following conditions\n-    are met:\n-\n-    * Redistributions of source code must retain the above copyright\n-    notice, this list of conditions and the following disclaimer.\n-    * Redistributions in binary form must reproduce the above copyright\n-    notice, this list of conditions and the following disclaimer in\n-    the documentation and/or other materials provided with the\n-    distribution.\n-    * Neither the name of Intel Corporation nor the names of its\n-    contributors may be used to endorse or promote products derived\n-    from this software without specific prior written permission.\n-\n-    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n-    \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n-    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n-    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n-    OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n-    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n-    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n-    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n-    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n-    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n-    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n-\n-IVSHMEM Library\n-===============\n-\n-The DPDK IVSHMEM library facilitates fast zero-copy data sharing among virtual machines\n-(host-to-guest or guest-to-guest) by means of QEMU's IVSHMEM mechanism.\n-\n-The library works by providing a command line for QEMU to map several hugepages into a single IVSHMEM device.\n-For the guest to know what is inside any given IVSHMEM device\n-(and to distinguish between DPDK and non-DPDK IVSHMEM devices),\n-a metadata file is also mapped into the IVSHMEM segment.\n-No work needs to be done by the guest application to map IVSHMEM devices into memory;\n-they are automatically recognized by the DPDK Environment Abstraction Layer (EAL).\n-\n-A typical DPDK IVSHMEM use case looks like the following.\n-\n-\n-.. figure:: img/ivshmem.*\n-\n-   Typical Ivshmem use case\n-\n-\n-The same could work with several virtual machines, providing host-to-VM or VM-to-VM communication.\n-The maximum number of metadata files is 32 (by default) and each metadata file can contain different (or even the same) hugepages.\n-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).\n-For example, if the user wants to share the same memzone across two VMs, each VM must have that memzone in its metadata file.\n-\n-IVHSHMEM Library API Overview\n------------------------------\n-\n-The following is a simple guide to using the IVSHMEM Library API:\n-\n-*   Call rte_ivshmem_metadata_create() to create a new metadata file.\n-    The metadata name is used to distinguish between multiple metadata files.\n-\n-*   Populate each metadata file with DPDK data structures.\n-    This can be done using the following API calls:\n-\n-    *   rte_ivhshmem_metadata_add_memzone() to add rte_memzone to metadata file\n-\n-    *   rte_ivshmem_metadata_add_ring() to add rte_ring to metadata file\n-\n-    *   rte_ivshmem_metadata_add_mempool() to add rte_mempool to metadata file\n-\n-*   Finally, call rte_ivshmem_metadata_cmdline_generate() to generate the command line for QEMU.\n-    Multiple metadata files (and thus multiple command lines) can be supplied to a single VM.\n-\n-.. note::\n-\n-    Only data structures fully residing in DPDK hugepage memory work correctly.\n-    Supported data structures created by malloc(), mmap()\n-    or otherwise using non-DPDK memory cause undefined behavior and even a segmentation fault.\n-    Specifically, because the memzone field in an rte_ring refers to a memzone structure residing in local memory,\n-    accessing the memzone field in a shared rte_ring will cause an immediate segmentation fault.\n-\n-IVSHMEM Environment Configuration\n----------------------------------\n-\n-The steps needed to successfully run IVSHMEM applications are the following:\n-\n-*   Compile a special version of QEMU from sources.\n-\n-    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),\n-    however, the source code will need to be patched to support using regular files as the IVSHMEM memory backend.\n-    The patch is not included in the DPDK package,\n-    but is available on the `Intel®DPDK-vswitch project webpage <https://01.org/packet-processing/intel%C2%AE-ovdk>`_\n-    (either separately or in a DPDK vSwitch package).\n-\n-*   Enable IVSHMEM library in the DPDK build configuration.\n-\n-    In the default configuration, IVSHMEM library is not compiled. To compile the IVSHMEM library,\n-    one has to either use one of the provided IVSHMEM targets\n-    (for example, x86_64-ivshmem-linuxapp-gcc),\n-    or set CONFIG_RTE_LIBRTE_IVSHMEM to \"y\" in the build configuration.\n-\n-*   Set up hugepage memory on the virtual machine.\n-\n-    The guest applications run as regular DPDK (primary) processes and thus need their own hugepage memory set up inside the VM.\n-    The process is identical to the one described in the *DPDK Getting Started Guide*.\n-\n-Best Practices for Writing IVSHMEM Applications\n------------------------------------------------\n-\n-When considering the use of IVSHMEM for sharing memory, security implications need to be carefully evaluated.\n-IVSHMEM is not suitable for untrusted guests, as IVSHMEM is essentially a window into the host process memory.\n-This also has implications for the multiple VM scenarios.\n-While the IVSHMEM library tries to share as little memory as possible,\n-it is quite probable that data designated for one VM might also be present in an IVSMHMEM device designated for another VM.\n-Consequently, any shared memory corruption will affect both host and all VMs sharing that particular memory.\n-\n-IVSHMEM applications essentially behave like multi-process applications,\n-so it is important to implement access serialization to data and thread safety.\n-DPDK ring structures are already thread-safe, however,\n-any custom data structures that the user might need would have to be thread-safe also.\n-\n-Similar to regular DPDK multi-process applications,\n-it is not recommended to use function pointers as functions might have different memory addresses in different processes.\n-\n-It is best to avoid freeing the rte_mbuf structure on a different machine from where it was allocated,\n-that is, if the mbuf was allocated on the host, the host should free it.\n-Consequently, any packet transmission and reception should also happen on the same machine (whether virtual or physical).\n-Failing to do so may lead to data corruption in the mempool cache.\n-\n-Despite the IVSHMEM mechanism being zero-copy and having good performance,\n-it is still desirable to do processing in batches and follow other procedures described in\n-:ref:`Performance Optimization <Performance_Optimization>`.\n-\n-Best Practices for Running IVSHMEM Applications\n------------------------------------------------\n-\n-For performance reasons,\n-it is best to pin host processes and QEMU processes to different cores so that they do not interfere with each other.\n-If NUMA support is enabled, it is also desirable to keep host process' hugepage memory and QEMU process on the same NUMA node.\n-\n-For the best performance across all NUMA nodes, each QEMU core should be pinned to host CPU core on the appropriate NUMA node.\n-QEMU's virtual NUMA nodes should also be set up to correspond to physical NUMA nodes.\n-More on how to set up DPDK and QEMU NUMA support can be found in *DPDK Getting Started Guide* and\n-`QEMU documentation <http://qemu.weilnetz.de/qemu-doc.html>`_ respectively.\n-A script called cpu_layout.py is provided with the DPDK package (in the tools directory)\n-that can be used to identify which CPU cores correspond to which NUMA node.\n-\n-The QEMU IVSHMEM command line creation should be considered the last step before starting the virtual machine.\n-Currently, there is no hot plug support for QEMU IVSHMEM devices,\n-so one cannot add additional memory to an IVSHMEM device once it has been created.\n-Therefore, the correct sequence to run an IVSHMEM application is to run host application first,\n-obtain the command lines for each IVSHMEM device and then run all QEMU instances with guest applications afterwards.\n-\n-It is important to note that once QEMU is started, it holds on to the hugepages it uses for IVSHMEM devices.\n-As a result, if the user wishes to shut down or restart the IVSHMEM host application,\n-it is not enough to simply shut the application down.\n-The virtual machine must also be shut down (if not, it will hold onto outdated host data).\ndiff --git a/doc/guides/prog_guide/source_org.rst b/doc/guides/prog_guide/source_org.rst\nindex 0c06d47..d9c140f 100644\n--- a/doc/guides/prog_guide/source_org.rst\n+++ b/doc/guides/prog_guide/source_org.rst\n@@ -70,7 +70,6 @@ The lib directory contains::\n     +-- librte_ether        # Generic interface to poll mode driver\n     +-- librte_hash         # Hash library\n     +-- librte_ip_frag      # IP fragmentation library\n-    +-- librte_ivshmem      # QEMU IVSHMEM library\n     +-- librte_kni          # Kernel NIC interface\n     +-- librte_kvargs       # Argument parsing library\n     +-- librte_lpm          # Longest prefix match library\ndiff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst\nindex d2dc4a9..be03262 100644\n--- a/doc/guides/rel_notes/deprecation.rst\n+++ b/doc/guides/rel_notes/deprecation.rst\n@@ -54,9 +54,6 @@ Deprecation Notices\n   will be removed in 16.11.\n   It is replaced by rte_mempool_generic_get/put functions.\n \n-* The ``rte_ivshmem`` feature (including library and EAL code) will be removed\n-  in 16.11 because it has some design issues which are not planned to be fixed.\n-\n * The vhost-cuse will be removed in 16.11. Since v2.1, a large majority of\n   development effort has gone to vhost-user, such as multiple-queue, live\n   migration, reconnect etc. Therefore, vhost-user should be used instead.\ndiff --git a/doc/guides/rel_notes/release_16_11.rst b/doc/guides/rel_notes/release_16_11.rst\nindex a6e3307..f7a2ceb 100644\n--- a/doc/guides/rel_notes/release_16_11.rst\n+++ b/doc/guides/rel_notes/release_16_11.rst\n@@ -94,6 +94,9 @@ API Changes\n \n    This section is a comment. Make sure to start the actual text at the margin.\n \n+* The ``rte_ivshmem`` feature (including library and EAL code) has been removed\n+  in 16.11 because it had some design issues which were not planned to be fixed.\n+\n \n ABI Changes\n -----------\ndiff --git a/examples/Makefile b/examples/Makefile\nindex 18b41b9..d49c7f2 100644\n--- a/examples/Makefile\n+++ b/examples/Makefile\n@@ -61,7 +61,6 @@ ifneq ($(PQOS_INSTALL_PATH),)\n DIRS-y += l2fwd-cat\n endif\n DIRS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += l2fwd-crypto\n-DIRS-$(CONFIG_RTE_LIBRTE_IVSHMEM) += l2fwd-ivshmem\n DIRS-$(CONFIG_RTE_LIBRTE_JOBSTATS) += l2fwd-jobstats\n DIRS-y += l2fwd-keepalive\n DIRS-y += l2fwd-keepalive/ka-agent\ndiff --git a/examples/l2fwd-ivshmem/Makefile b/examples/l2fwd-ivshmem/Makefile\ndeleted file mode 100644\nindex 5f1d172..0000000\n--- a/examples/l2fwd-ivshmem/Makefile\n+++ /dev/null\n@@ -1,43 +0,0 @@\n-#   BSD LICENSE\n-#\n-#   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.\n-#   All rights reserved.\n-#\n-#   Redistribution and use in source and binary forms, with or without\n-#   modification, are permitted provided that the following conditions\n-#   are met:\n-#\n-#     * Redistributions of source code must retain the above copyright\n-#       notice, this list of conditions and the following disclaimer.\n-#     * Redistributions in binary form must reproduce the above copyright\n-#       notice, this list of conditions and the following disclaimer in\n-#       the documentation and/or other materials provided with the\n-#       distribution.\n-#     * Neither the name of Intel Corporation nor the names of its\n-#       contributors may be used to endorse or promote products derived\n-#       from this software without specific prior written permission.\n-#\n-#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n-#   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n-#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n-#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n-#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n-#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n-#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n-#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n-#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n-#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n-#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n-\n-ifeq ($(RTE_SDK),)\n-$(error \"Please define RTE_SDK environment variable\")\n-endif\n-\n-# Default target, can be overriden by command line or environment\n-RTE_TARGET ?= x86_64-ivshmem-linuxapp-gcc\n-\n-include $(RTE_SDK)/mk/rte.vars.mk\n-\n-DIRS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += host guest\n-\n-include $(RTE_SDK)/mk/rte.extsubdir.mk\ndiff --git a/examples/l2fwd-ivshmem/guest/Makefile b/examples/l2fwd-ivshmem/guest/Makefile\ndeleted file mode 100644\nindex 3ca73b4..0000000\n--- a/examples/l2fwd-ivshmem/guest/Makefile\n+++ /dev/null\n@@ -1,50 +0,0 @@\n-#   BSD LICENSE\n-#\n-#   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.\n-#   All rights reserved.\n-#\n-#   Redistribution and use in source and binary forms, with or without\n-#   modification, are permitted provided that the following conditions\n-#   are met:\n-#\n-#     * Redistributions of source code must retain the above copyright\n-#       notice, this list of conditions and the following disclaimer.\n-#     * Redistributions in binary form must reproduce the above copyright\n-#       notice, this list of conditions and the following disclaimer in\n-#       the documentation and/or other materials provided with the\n-#       distribution.\n-#     * Neither the name of Intel Corporation nor the names of its\n-#       contributors may be used to endorse or promote products derived\n-#       from this software without specific prior written permission.\n-#\n-#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n-#   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n-#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n-#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n-#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n-#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n-#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n-#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n-#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n-#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n-#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n-\n-ifeq ($(RTE_SDK),)\n-$(error \"Please define RTE_SDK environment variable\")\n-endif\n-\n-# Default target, can be overriden by command line or environment\n-RTE_TARGET ?= x86_64-ivshmem-linuxapp-gcc\n-\n-include $(RTE_SDK)/mk/rte.vars.mk\n-\n-# binary name\n-APP = guest\n-\n-# all source are stored in SRCS-y\n-SRCS-y := guest.c\n-\n-CFLAGS += -O3\n-CFLAGS += $(WERROR_FLAGS)\n-\n-include $(RTE_SDK)/mk/rte.extapp.mk\ndiff --git a/examples/l2fwd-ivshmem/guest/guest.c b/examples/l2fwd-ivshmem/guest/guest.c\ndeleted file mode 100644\nindex 7c49521..0000000\n--- a/examples/l2fwd-ivshmem/guest/guest.c\n+++ /dev/null\n@@ -1,452 +0,0 @@\n-/*-\n- *   BSD LICENSE\n- *\n- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.\n- *   All rights reserved.\n- *\n- *   Redistribution and use in source and binary forms, with or without\n- *   modification, are permitted provided that the following conditions\n- *   are met:\n- *\n- *     * Redistributions of source code must retain the above copyright\n- *       notice, this list of conditions and the following disclaimer.\n- *     * Redistributions in binary form must reproduce the above copyright\n- *       notice, this list of conditions and the following disclaimer in\n- *       the documentation and/or other materials provided with the\n- *       distribution.\n- *     * Neither the name of Intel Corporation nor the names of its\n- *       contributors may be used to endorse or promote products derived\n- *       from this software without specific prior written permission.\n- *\n- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n- *   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n- */\n-\n-#include <stdio.h>\n-#include <stdlib.h>\n-#include <string.h>\n-#include <stdint.h>\n-#include <unistd.h>\n-#include <getopt.h>\n-#include <signal.h>\n-#include <sys/mman.h>\n-#include <sys/types.h>\n-#include <sys/stat.h>\n-#include <sys/queue.h>\n-#include <sys/file.h>\n-#include <unistd.h>\n-#include <limits.h>\n-#include <errno.h>\n-#include <sys/ioctl.h>\n-#include <sys/time.h>\n-\n-#include <rte_common.h>\n-#include <rte_eal_memconfig.h>\n-#include <rte_log.h>\n-#include <rte_memory.h>\n-#include <rte_memcpy.h>\n-#include <rte_memzone.h>\n-#include <rte_eal.h>\n-#include <rte_per_lcore.h>\n-#include <rte_launch.h>\n-#include <rte_atomic.h>\n-#include <rte_cycles.h>\n-#include <rte_prefetch.h>\n-#include <rte_lcore.h>\n-#include <rte_per_lcore.h>\n-#include <rte_branch_prediction.h>\n-#include <rte_interrupts.h>\n-#include <rte_pci.h>\n-#include <rte_random.h>\n-#include <rte_debug.h>\n-#include <rte_ether.h>\n-#include <rte_ethdev.h>\n-#include <rte_ring.h>\n-#include <rte_mempool.h>\n-#include <rte_mbuf.h>\n-#include <rte_ivshmem.h>\n-\n-#include \"../include/common.h\"\n-\n-#define MAX_RX_QUEUE_PER_LCORE 16\n-#define MAX_TX_QUEUE_PER_PORT 16\n-struct lcore_queue_conf {\n-\tunsigned n_rx_port;\n-\tunsigned rx_port_list[MAX_RX_QUEUE_PER_LCORE];\n-\tstruct mbuf_table rx_mbufs[RTE_MAX_ETHPORTS];\n-\tstruct vm_port_param * port_param[MAX_RX_QUEUE_PER_LCORE];\n-} __rte_cache_aligned;\n-static struct lcore_queue_conf lcore_queue_conf[RTE_MAX_LCORE];\n-\n-/* Print out statistics on packets dropped */\n-static void\n-print_stats(void)\n-{\n-\tuint64_t total_packets_dropped, total_packets_tx, total_packets_rx;\n-\tunsigned portid;\n-\n-\ttotal_packets_dropped = 0;\n-\ttotal_packets_tx = 0;\n-\ttotal_packets_rx = 0;\n-\n-\tconst char clr[] = { 27, '[', '2', 'J', '\\0' };\n-\tconst char topLeft[] = { 27, '[', '1', ';', '1', 'H','\\0' };\n-\n-\t\t/* Clear screen and move to top left */\n-\tprintf(\"%s%s\", clr, topLeft);\n-\n-\tprintf(\"\\nPort statistics ====================================\");\n-\n-\tfor (portid = 0; portid < ctrl->nb_ports; portid++) {\n-\t\t/* skip ports that are not enabled */\n-\t\tprintf(\"\\nStatistics for port %u ------------------------------\"\n-\t\t\t   \"\\nPackets sent: %24\"PRIu64\n-\t\t\t   \"\\nPackets received: %20\"PRIu64\n-\t\t\t   \"\\nPackets dropped: %21\"PRIu64,\n-\t\t\t   portid,\n-\t\t\t   ctrl->vm_ports[portid].stats.tx,\n-\t\t\t   ctrl->vm_ports[portid].stats.rx,\n-\t\t\t   ctrl->vm_ports[portid].stats.dropped);\n-\n-\t\ttotal_packets_dropped += ctrl->vm_ports[portid].stats.dropped;\n-\t\ttotal_packets_tx += ctrl->vm_ports[portid].stats.tx;\n-\t\ttotal_packets_rx += ctrl->vm_ports[portid].stats.rx;\n-\t}\n-\tprintf(\"\\nAggregate statistics ===============================\"\n-\t\t   \"\\nTotal packets sent: %18\"PRIu64\n-\t\t   \"\\nTotal packets received: %14\"PRIu64\n-\t\t   \"\\nTotal packets dropped: %15\"PRIu64,\n-\t\t   total_packets_tx,\n-\t\t   total_packets_rx,\n-\t\t   total_packets_dropped);\n-\tprintf(\"\\n====================================================\\n\");\n-}\n-\n-/* display usage */\n-static void\n-l2fwd_ivshmem_usage(const char *prgname)\n-{\n-\tprintf(\"%s [EAL options] -- [-q NQ -T PERIOD]\\n\"\n-\t\t   \"  -q NQ: number of queue (=ports) per lcore (default is 1)\\n\"\n-\t\t   \"  -T PERIOD: statistics will be refreshed each PERIOD seconds (0 to disable, 10 default, 86400 maximum)\\n\",\n-\t       prgname);\n-}\n-\n-static unsigned int\n-l2fwd_ivshmem_parse_nqueue(const char *q_arg)\n-{\n-\tchar *end = NULL;\n-\tunsigned long n;\n-\n-\t/* parse hexadecimal string */\n-\tn = strtoul(q_arg, &end, 10);\n-\tif ((q_arg[0] == '\\0') || (end == NULL) || (*end != '\\0'))\n-\t\treturn 0;\n-\tif (n == 0)\n-\t\treturn 0;\n-\tif (n >= MAX_RX_QUEUE_PER_LCORE)\n-\t\treturn 0;\n-\n-\treturn n;\n-}\n-\n-static int\n-l2fwd_ivshmem_parse_timer_period(const char *q_arg)\n-{\n-\tchar *end = NULL;\n-\tint n;\n-\n-\t/* parse number string */\n-\tn = strtol(q_arg, &end, 10);\n-\tif ((q_arg[0] == '\\0') || (end == NULL) || (*end != '\\0'))\n-\t\treturn -1;\n-\tif (n >= MAX_TIMER_PERIOD)\n-\t\treturn -1;\n-\n-\treturn n;\n-}\n-\n-/* Parse the argument given in the command line of the application */\n-static int\n-l2fwd_ivshmem_parse_args(int argc, char **argv)\n-{\n-\tint opt, ret;\n-\tchar **argvopt;\n-\tint option_index;\n-\tchar *prgname = argv[0];\n-\tstatic struct option lgopts[] = {\n-\t\t{NULL, 0, 0, 0}\n-\t};\n-\n-\targvopt = argv;\n-\n-\twhile ((opt = getopt_long(argc, argvopt, \"q:p:T:\",\n-\t\t\t\t  lgopts, &option_index)) != EOF) {\n-\n-\t\tswitch (opt) {\n-\n-\t\t/* nqueue */\n-\t\tcase 'q':\n-\t\t\tl2fwd_ivshmem_rx_queue_per_lcore = l2fwd_ivshmem_parse_nqueue(optarg);\n-\t\t\tif (l2fwd_ivshmem_rx_queue_per_lcore == 0) {\n-\t\t\t\tprintf(\"invalid queue number\\n\");\n-\t\t\t\tl2fwd_ivshmem_usage(prgname);\n-\t\t\t\treturn -1;\n-\t\t\t}\n-\t\t\tbreak;\n-\n-\t\t/* timer period */\n-\t\tcase 'T':\n-\t\t\ttimer_period = l2fwd_ivshmem_parse_timer_period(optarg) * 1000 * TIMER_MILLISECOND;\n-\t\t\tif (timer_period < 0) {\n-\t\t\t\tprintf(\"invalid timer period\\n\");\n-\t\t\t\tl2fwd_ivshmem_usage(prgname);\n-\t\t\t\treturn -1;\n-\t\t\t}\n-\t\t\tbreak;\n-\n-\t\t/* long options */\n-\t\tcase 0:\n-\t\t\tl2fwd_ivshmem_usage(prgname);\n-\t\t\treturn -1;\n-\n-\t\tdefault:\n-\t\t\tl2fwd_ivshmem_usage(prgname);\n-\t\t\treturn -1;\n-\t\t}\n-\t}\n-\n-\tif (optind >= 0)\n-\t\targv[optind-1] = prgname;\n-\n-\tret = optind-1;\n-\toptind = 0; /* reset getopt lib */\n-\treturn ret;\n-}\n-\n-/*\n- * this loop is getting packets from RX rings of each port, and puts them\n- * into TX rings of destination ports.\n- */\n-static void\n-fwd_loop(void)\n-{\n-\n-\tstruct rte_mbuf *pkts_burst[MAX_PKT_BURST];\n-\tstruct rte_mbuf **m_table;\n-\tstruct rte_mbuf *m;\n-\tstruct rte_ring *rx, *tx;\n-\tunsigned lcore_id, len;\n-\tuint64_t prev_tsc, diff_tsc, cur_tsc, timer_tsc;\n-\tunsigned i, j, portid, nb_rx;\n-\tstruct lcore_queue_conf *qconf;\n-\tstruct ether_hdr *eth;\n-\tvoid *tmp;\n-\n-\tprev_tsc = 0;\n-\ttimer_tsc = 0;\n-\n-\tlcore_id = rte_lcore_id();\n-\tqconf = &lcore_queue_conf[lcore_id];\n-\n-\tif (qconf->n_rx_port == 0) {\n-\t\tRTE_LOG(INFO, L2FWD_IVSHMEM, \"lcore %u has nothing to do\\n\", lcore_id);\n-\t\treturn;\n-\t}\n-\n-\tRTE_LOG(INFO, L2FWD_IVSHMEM, \"entering main loop on lcore %u\\n\", lcore_id);\n-\n-\tfor (i = 0; i < qconf->n_rx_port; i++) {\n-\t\tportid = qconf->rx_port_list[i];\n-\t\tRTE_LOG(INFO, L2FWD_IVSHMEM, \" -- lcoreid=%u portid=%u\\n\", lcore_id,\n-\t\t\tportid);\n-\t}\n-\n-\twhile (ctrl->state == STATE_FWD) {\n-\t\tcur_tsc = rte_rdtsc();\n-\n-\t\tdiff_tsc = cur_tsc - prev_tsc;\n-\n-\t\t/*\n-\t\t * Read packet from RX queues and send it to TX queues\n-\t\t */\n-\t\tfor (i = 0; i < qconf->n_rx_port; i++) {\n-\n-\t\t\tportid = qconf->rx_port_list[i];\n-\n-\t\t\tlen = qconf->rx_mbufs[portid].len;\n-\n-\t\t\trx = ctrl->vm_ports[portid].rx_ring;\n-\t\t\ttx = ctrl->vm_ports[portid].dst->tx_ring;\n-\n-\t\t\tm_table = qconf->rx_mbufs[portid].m_table;\n-\n-\t\t\t/* if we have something in the queue, try and transmit it down */\n-\t\t\tif (len != 0) {\n-\n-\t\t\t\t/* if we succeed in sending the packets down, mark queue as free */\n-\t\t\t\tif (rte_ring_enqueue_bulk(tx, (void**) m_table, len) == 0) {\n-\t\t\t\t\tctrl->vm_ports[portid].stats.tx += len;\n-\t\t\t\t\tqconf->rx_mbufs[portid].len = 0;\n-\t\t\t\t\tlen = 0;\n-\t\t\t\t}\n-\t\t\t}\n-\n-\t\t\tnb_rx = rte_ring_count(rx);\n-\n-\t\t\tnb_rx = RTE_MIN(nb_rx, (unsigned) MAX_PKT_BURST);\n-\n-\t\t\tif (nb_rx == 0)\n-\t\t\t\tcontinue;\n-\n-\t\t\t/* if we can get packets into the m_table */\n-\t\t\tif (nb_rx < (RTE_DIM(qconf->rx_mbufs[portid].m_table) - len)) {\n-\n-\t\t\t\t/* this situation cannot exist, so if we fail to dequeue, that\n-\t\t\t\t * means something went horribly wrong, hence the failure. */\n-\t\t\t\tif (rte_ring_dequeue_bulk(rx, (void**) pkts_burst, nb_rx) < 0) {\n-\t\t\t\t\tctrl->state = STATE_FAIL;\n-\t\t\t\t\treturn;\n-\t\t\t\t}\n-\n-\t\t\t\tctrl->vm_ports[portid].stats.rx += nb_rx;\n-\n-\t\t\t\t/* put packets into the queue */\n-\t\t\t\tfor (j = 0; j < nb_rx; j++) {\n-\t\t\t\t\tm = pkts_burst[j];\n-\n-\t\t\t\t\trte_prefetch0(rte_pktmbuf_mtod(m, void *));\n-\n-\t\t\t\t\tm_table[len + j] = m;\n-\n-\t\t\t\t\teth = rte_pktmbuf_mtod(m, struct ether_hdr *);\n-\n-\t\t\t\t\t/* 02:00:00:00:00:xx */\n-\t\t\t\t\ttmp = &eth->d_addr.addr_bytes[0];\n-\t\t\t\t\t*((uint64_t *)tmp) = 0x000000000002 + ((uint64_t)portid << 40);\n-\n-\t\t\t\t\t/* src addr */\n-\t\t\t\t\tether_addr_copy(&ctrl->vm_ports[portid].dst->ethaddr,\n-\t\t\t\t\t\t\t&eth->s_addr);\n-\t\t\t\t}\n-\t\t\t\tqconf->rx_mbufs[portid].len += nb_rx;\n-\n-\t\t\t}\n-\n-\t\t}\n-\n-\t\t/* if timer is enabled */\n-\t\tif (timer_period > 0) {\n-\n-\t\t\t/* advance the timer */\n-\t\t\ttimer_tsc += diff_tsc;\n-\n-\t\t\t/* if timer has reached its timeout */\n-\t\t\tif (unlikely(timer_tsc >= (uint64_t) timer_period)) {\n-\n-\t\t\t\t/* do this only on master core */\n-\t\t\t\tif (lcore_id == rte_get_master_lcore()) {\n-\t\t\t\t\tprint_stats();\n-\t\t\t\t\t/* reset the timer */\n-\t\t\t\t\ttimer_tsc = 0;\n-\t\t\t\t}\n-\t\t\t}\n-\t\t}\n-\n-\t\tprev_tsc = cur_tsc;\n-\t}\n-}\n-\n-static int\n-l2fwd_ivshmem_launch_one_lcore(__attribute__((unused)) void *dummy)\n-{\n-\tfwd_loop();\n-\treturn 0;\n-}\n-\n-int\n-main(int argc, char **argv)\n-{\n-\tstruct lcore_queue_conf *qconf;\n-\tconst struct rte_memzone * mz;\n-\tint ret;\n-\tuint8_t portid;\n-\tunsigned rx_lcore_id, lcore_id;\n-\n-\t/* init EAL */\n-\tret = rte_eal_init(argc, argv);\n-\tif (ret < 0)\n-\t\trte_exit(EXIT_FAILURE, \"Invalid EAL arguments\\n\");\n-\targc -= ret;\n-\targv += ret;\n-\n-\t/* parse application arguments (after the EAL ones) */\n-\tret = l2fwd_ivshmem_parse_args(argc, argv);\n-\tif (ret < 0)\n-\t\trte_exit(EXIT_FAILURE, \"Invalid l2fwd-ivshmem arguments\\n\");\n-\n-\t/* find control structure */\n-\tmz = rte_memzone_lookup(CTRL_MZ_NAME);\n-\tif (mz == NULL)\n-\t\trte_exit(EXIT_FAILURE, \"Cannot find control memzone\\n\");\n-\n-\tctrl = (struct ivshmem_ctrl*) mz->addr;\n-\n-\t/* lock the ctrl so that we don't have conflicts with anything else */\n-\trte_spinlock_lock(&ctrl->lock);\n-\n-\tif (ctrl->state == STATE_FWD)\n-\t\trte_exit(EXIT_FAILURE, \"Forwarding already started!\\n\");\n-\n-\trx_lcore_id = 0;\n-\tqconf = NULL;\n-\n-\t/* Initialize the port/queue configuration of each logical core */\n-\tfor (portid = 0; portid < ctrl->nb_ports; portid++) {\n-\n-\t\t/* get the lcore_id for this port */\n-\t\twhile (rte_lcore_is_enabled(rx_lcore_id) == 0 ||\n-\t\t\t   lcore_queue_conf[rx_lcore_id].n_rx_port ==\n-\t\t\t   l2fwd_ivshmem_rx_queue_per_lcore) {\n-\t\t\trx_lcore_id++;\n-\t\t\tif (rx_lcore_id >= RTE_MAX_LCORE)\n-\t\t\t\trte_exit(EXIT_FAILURE, \"Not enough cores\\n\");\n-\t\t}\n-\n-\t\tif (qconf != &lcore_queue_conf[rx_lcore_id])\n-\t\t\t/* Assigned a new logical core in the loop above. */\n-\t\t\tqconf = &lcore_queue_conf[rx_lcore_id];\n-\n-\t\tqconf->rx_port_list[qconf->n_rx_port] = portid;\n-\t\tqconf->port_param[qconf->n_rx_port] = &ctrl->vm_ports[portid];\n-\t\tqconf->n_rx_port++;\n-\n-\t\tprintf(\"Lcore %u: RX port %u\\n\", rx_lcore_id, (unsigned) portid);\n-\t}\n-\n-\tsigsetup();\n-\n-\t/* indicate that we are ready to forward */\n-\tctrl->state = STATE_FWD;\n-\n-\t/* unlock */\n-\trte_spinlock_unlock(&ctrl->lock);\n-\n-\t/* launch per-lcore init on every lcore */\n-\trte_eal_mp_remote_launch(l2fwd_ivshmem_launch_one_lcore, NULL, CALL_MASTER);\n-\tRTE_LCORE_FOREACH_SLAVE(lcore_id) {\n-\t\tif (rte_eal_wait_lcore(lcore_id) < 0)\n-\t\t\treturn -1;\n-\t}\n-\n-\treturn 0;\n-}\ndiff --git a/examples/l2fwd-ivshmem/host/Makefile b/examples/l2fwd-ivshmem/host/Makefile\ndeleted file mode 100644\nindex f91419e..0000000\n--- a/examples/l2fwd-ivshmem/host/Makefile\n+++ /dev/null\n@@ -1,50 +0,0 @@\n-#   BSD LICENSE\n-#\n-#   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.\n-#   All rights reserved.\n-#\n-#   Redistribution and use in source and binary forms, with or without\n-#   modification, are permitted provided that the following conditions\n-#   are met:\n-#\n-#     * Redistributions of source code must retain the above copyright\n-#       notice, this list of conditions and the following disclaimer.\n-#     * Redistributions in binary form must reproduce the above copyright\n-#       notice, this list of conditions and the following disclaimer in\n-#       the documentation and/or other materials provided with the\n-#       distribution.\n-#     * Neither the name of Intel Corporation nor the names of its\n-#       contributors may be used to endorse or promote products derived\n-#       from this software without specific prior written permission.\n-#\n-#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n-#   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n-#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n-#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n-#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n-#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n-#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n-#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n-#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n-#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n-#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n-\n-ifeq ($(RTE_SDK),)\n-$(error \"Please define RTE_SDK environment variable\")\n-endif\n-\n-# Default target, can be overriden by command line or environment\n-RTE_TARGET ?= x86_64-ivshmem-linuxapp-gcc\n-\n-include $(RTE_SDK)/mk/rte.vars.mk\n-\n-# binary name\n-APP = host\n-\n-# all source are stored in SRCS-y\n-SRCS-y := host.c\n-\n-CFLAGS += -O3\n-CFLAGS += $(WERROR_FLAGS)\n-\n-include $(RTE_SDK)/mk/rte.extapp.mk\ndiff --git a/examples/l2fwd-ivshmem/host/host.c b/examples/l2fwd-ivshmem/host/host.c\ndeleted file mode 100644\nindex da7b00d..0000000\n--- a/examples/l2fwd-ivshmem/host/host.c\n+++ /dev/null\n@@ -1,895 +0,0 @@\n-/*-\n- *   BSD LICENSE\n- *\n- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.\n- *   All rights reserved.\n- *\n- *   Redistribution and use in source and binary forms, with or without\n- *   modification, are permitted provided that the following conditions\n- *   are met:\n- *\n- *     * Redistributions of source code must retain the above copyright\n- *       notice, this list of conditions and the following disclaimer.\n- *     * Redistributions in binary form must reproduce the above copyright\n- *       notice, this list of conditions and the following disclaimer in\n- *       the documentation and/or other materials provided with the\n- *       distribution.\n- *     * Neither the name of Intel Corporation nor the names of its\n- *       contributors may be used to endorse or promote products derived\n- *       from this software without specific prior written permission.\n- *\n- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n- *   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n- */\n-\n-#include <unistd.h>\n-#include <stdlib.h>\n-#include <stdio.h>\n-#include <string.h>\n-#include <limits.h>\n-#include <inttypes.h>\n-#include <getopt.h>\n-#include <signal.h>\n-\n-#include <rte_eal.h>\n-#include <rte_cycles.h>\n-#include <rte_eal_memconfig.h>\n-#include <rte_debug.h>\n-#include <rte_ether.h>\n-#include <rte_ethdev.h>\n-#include <rte_string_fns.h>\n-#include <rte_ivshmem.h>\n-#include <rte_ring.h>\n-#include <rte_mempool.h>\n-#include <rte_mbuf.h>\n-\n-#include \"../include/common.h\"\n-\n-/*\n- * Configurable number of RX/TX ring descriptors\n- */\n-#define RTE_TEST_RX_DESC_DEFAULT 128\n-#define RTE_TEST_TX_DESC_DEFAULT 512\n-static uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT;\n-static uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT;\n-\n-#define BURST_TX_DRAIN_US 100 /* TX drain every ~100us */\n-\n-/* mask of enabled ports */\n-static uint32_t l2fwd_ivshmem_enabled_port_mask = 0;\n-\n-static struct ether_addr l2fwd_ivshmem_ports_eth_addr[RTE_MAX_ETHPORTS];\n-\n-#define NB_MBUF   8192\n-\n-#define MAX_RX_QUEUE_PER_LCORE 16\n-#define MAX_TX_QUEUE_PER_PORT 16\n-struct lcore_queue_conf {\n-\tunsigned n_rx_port;\n-\tunsigned rx_port_list[MAX_RX_QUEUE_PER_LCORE];\n-\tstruct vm_port_param * port_param[MAX_RX_QUEUE_PER_LCORE];\n-\tstruct mbuf_table tx_mbufs[RTE_MAX_ETHPORTS];\n-\tstruct mbuf_table rx_mbufs[RTE_MAX_ETHPORTS];\n-} __rte_cache_aligned;\n-static struct lcore_queue_conf lcore_queue_conf[RTE_MAX_LCORE];\n-\n-static const struct rte_eth_conf port_conf = {\n-\t.rxmode = {\n-\t\t.split_hdr_size = 0,\n-\t\t.header_split   = 0, /**< Header Split disabled */\n-\t\t.hw_ip_checksum = 0, /**< IP checksum offload disabled */\n-\t\t.hw_vlan_filter = 0, /**< VLAN filtering disabled */\n-\t\t.jumbo_frame    = 0, /**< Jumbo Frame Support disabled */\n-\t\t.hw_strip_crc   = 0, /**< CRC stripped by hardware */\n-\t},\n-\t.txmode = {\n-\t\t.mq_mode = ETH_MQ_TX_NONE,\n-\t},\n-};\n-\n-#define METADATA_NAME \"l2fwd_ivshmem\"\n-#define CMDLINE_OPT_FWD_CONF \"fwd-conf\"\n-\n-#define QEMU_CMD_FMT \"/tmp/ivshmem_qemu_cmdline_%s\"\n-\n-struct port_statistics port_statistics[RTE_MAX_ETHPORTS];\n-\n-struct rte_mempool * l2fwd_ivshmem_pktmbuf_pool = NULL;\n-\n-/* Print out statistics on packets dropped */\n-static void\n-print_stats(void)\n-{\n-\tuint64_t total_packets_dropped, total_packets_tx, total_packets_rx;\n-\tuint64_t total_vm_packets_dropped = 0;\n-\tuint64_t total_vm_packets_tx, total_vm_packets_rx;\n-\tunsigned portid;\n-\n-\ttotal_packets_dropped = 0;\n-\ttotal_packets_tx = 0;\n-\ttotal_packets_rx = 0;\n-\ttotal_vm_packets_tx = 0;\n-\ttotal_vm_packets_rx = 0;\n-\n-\tconst char clr[] = { 27, '[', '2', 'J', '\\0' };\n-\tconst char topLeft[] = { 27, '[', '1', ';', '1', 'H','\\0' };\n-\n-\t\t/* Clear screen and move to top left */\n-\tprintf(\"%s%s\", clr, topLeft);\n-\n-\tprintf(\"\\nPort statistics ====================================\");\n-\n-\tfor (portid = 0; portid < RTE_MAX_ETHPORTS; portid++) {\n-\t\t/* skip disabled ports */\n-\t\tif ((l2fwd_ivshmem_enabled_port_mask & (1 << portid)) == 0)\n-\t\t\tcontinue;\n-\t\tprintf(\"\\nStatistics for port %u ------------------------------\"\n-\t\t\t   \"\\nPackets sent: %24\"PRIu64\n-\t\t\t   \"\\nPackets received: %20\"PRIu64\n-\t\t\t   \"\\nPackets dropped: %21\"PRIu64,\n-\t\t\t   portid,\n-\t\t\t   port_statistics[portid].tx,\n-\t\t\t   port_statistics[portid].rx,\n-\t\t\t   port_statistics[portid].dropped);\n-\n-\t\ttotal_packets_dropped += port_statistics[portid].dropped;\n-\t\ttotal_packets_tx += port_statistics[portid].tx;\n-\t\ttotal_packets_rx += port_statistics[portid].rx;\n-\t}\n-\n-\tprintf(\"\\nVM statistics ======================================\");\n-\tfor (portid = 0; portid < ctrl->nb_ports; portid++) {\n-\t\tprintf(\"\\nStatistics for port %u ------------------------------\"\n-\t\t\t   \"\\nPackets sent: %24\"PRIu64\n-\t\t\t   \"\\nPackets received: %20\"PRIu64,\n-\t\t\t   portid,\n-\t\t\t   ctrl->vm_ports[portid].stats.tx,\n-\t\t\t   ctrl->vm_ports[portid].stats.rx);\n-\n-\t\ttotal_vm_packets_dropped += ctrl->vm_ports[portid].stats.dropped;\n-\t\ttotal_vm_packets_tx += ctrl->vm_ports[portid].stats.tx;\n-\t\ttotal_vm_packets_rx += ctrl->vm_ports[portid].stats.rx;\n-\t}\n-\tprintf(\"\\nAggregate statistics ===============================\"\n-\t\t\t   \"\\nTotal packets sent: %18\"PRIu64\n-\t\t\t   \"\\nTotal packets received: %14\"PRIu64\n-\t\t\t   \"\\nTotal packets dropped: %15\"PRIu64\n-\t\t\t   \"\\nTotal VM packets sent: %15\"PRIu64\n-\t\t\t   \"\\nTotal VM packets received: %11\"PRIu64,\n-\t\t\t   total_packets_tx,\n-\t\t\t   total_packets_rx,\n-\t\t\t   total_packets_dropped,\n-\t\t\t   total_vm_packets_tx,\n-\t\t\t   total_vm_packets_rx);\n-\tprintf(\"\\n====================================================\\n\");\n-}\n-\n-static int\n-print_to_file(const char *cmdline, const char *config_name)\n-{\n-\tFILE *file;\n-\tchar path[PATH_MAX];\n-\n-\tsnprintf(path, sizeof(path), QEMU_CMD_FMT, config_name);\n-\tfile = fopen(path, \"w\");\n-\tif (file == NULL) {\n-\t\tRTE_LOG(ERR, L2FWD_IVSHMEM, \"Could not open '%s' \\n\", path);\n-\t\treturn -1;\n-\t}\n-\n-\tRTE_LOG(DEBUG, L2FWD_IVSHMEM, \"QEMU command line for config '%s': %s \\n\",\n-\t\t\tconfig_name, cmdline);\n-\n-\tfprintf(file, \"%s\\n\", cmdline);\n-\tfclose(file);\n-\treturn 0;\n-}\n-\n-static int\n-generate_ivshmem_cmdline(const char *config_name)\n-{\n-\tchar cmdline[PATH_MAX];\n-\tif (rte_ivshmem_metadata_cmdline_generate(cmdline, sizeof(cmdline),\n-\t\t\tconfig_name) < 0)\n-\t\treturn -1;\n-\n-\tif (print_to_file(cmdline, config_name) < 0)\n-\t\treturn -1;\n-\n-\trte_ivshmem_metadata_dump(stdout, config_name);\n-\treturn 0;\n-}\n-\n-/* display usage */\n-static void\n-l2fwd_ivshmem_usage(const char *prgname)\n-{\n-\tprintf(\"%s [EAL options] -- -p PORTMASK [-q NQ -T PERIOD]\\n\"\n-\t\t   \"  -p PORTMASK: hexadecimal bitmask of ports to configure\\n\"\n-\t\t   \"  -q NQ: number of queue (=ports) per lcore (default is 1)\\n\"\n-\t\t   \"  -T PERIOD: statistics will be refreshed each PERIOD seconds \"\n-\t\t       \"(0 to disable, 10 default, 86400 maximum)\\n\",\n-\t       prgname);\n-}\n-\n-static unsigned int\n-l2fwd_ivshmem_parse_nqueue(const char *q_arg)\n-{\n-\tchar *end = NULL;\n-\tunsigned long n;\n-\n-\t/* parse hexadecimal string */\n-\tn = strtoul(q_arg, &end, 10);\n-\tif ((q_arg[0] == '\\0') || (end == NULL) || (*end != '\\0'))\n-\t\treturn 0;\n-\tif (n == 0)\n-\t\treturn 0;\n-\tif (n >= MAX_RX_QUEUE_PER_LCORE)\n-\t\treturn 0;\n-\n-\treturn n;\n-}\n-\n-static int\n-l2fwd_ivshmem_parse_portmask(const char *portmask)\n-{\n-\tchar *end = NULL;\n-\tunsigned long pm;\n-\n-\t/* parse hexadecimal string */\n-\tpm = strtoul(portmask, &end, 16);\n-\tif ((portmask[0] == '\\0') || (end == NULL) || (*end != '\\0'))\n-\t\treturn -1;\n-\n-\tif (pm == 0)\n-\t\treturn -1;\n-\n-\treturn pm;\n-}\n-\n-static int\n-l2fwd_ivshmem_parse_timer_period(const char *q_arg)\n-{\n-\tchar *end = NULL;\n-\tint n;\n-\n-\t/* parse number string */\n-\tn = strtol(q_arg, &end, 10);\n-\tif ((q_arg[0] == '\\0') || (end == NULL) || (*end != '\\0'))\n-\t\treturn -1;\n-\tif (n >= MAX_TIMER_PERIOD)\n-\t\treturn -1;\n-\n-\treturn n;\n-}\n-\n-/* Parse the argument given in the command line of the application */\n-static int\n-l2fwd_ivshmem_parse_args(int argc, char **argv)\n-{\n-\tint opt, ret;\n-\tchar **argvopt;\n-\tint option_index;\n-\tchar *prgname = argv[0];\n-\tstatic struct option lgopts[] = {\n-\t\t\t{CMDLINE_OPT_FWD_CONF, 1, 0, 0},\n-\t\t{NULL, 0, 0, 0}\n-\t};\n-\n-\targvopt = argv;\n-\n-\twhile ((opt = getopt_long(argc, argvopt, \"q:p:T:\",\n-\t\t\t\t  lgopts, &option_index)) != EOF) {\n-\n-\t\tswitch (opt) {\n-\t\t/* portmask */\n-\t\tcase 'p':\n-\t\t\tl2fwd_ivshmem_enabled_port_mask = l2fwd_ivshmem_parse_portmask(optarg);\n-\t\t\tif (l2fwd_ivshmem_enabled_port_mask == 0) {\n-\t\t\t\tprintf(\"invalid portmask\\n\");\n-\t\t\t\tl2fwd_ivshmem_usage(prgname);\n-\t\t\t\treturn -1;\n-\t\t\t}\n-\t\t\tbreak;\n-\n-\t\t/* nqueue */\n-\t\tcase 'q':\n-\t\t\tl2fwd_ivshmem_rx_queue_per_lcore = l2fwd_ivshmem_parse_nqueue(optarg);\n-\t\t\tif (l2fwd_ivshmem_rx_queue_per_lcore == 0) {\n-\t\t\t\tprintf(\"invalid queue number\\n\");\n-\t\t\t\tl2fwd_ivshmem_usage(prgname);\n-\t\t\t\treturn -1;\n-\t\t\t}\n-\t\t\tbreak;\n-\n-\t\t/* timer period */\n-\t\tcase 'T':\n-\t\t\ttimer_period = l2fwd_ivshmem_parse_timer_period(optarg) * 1000 * TIMER_MILLISECOND;\n-\t\t\tif (timer_period < 0) {\n-\t\t\t\tprintf(\"invalid timer period\\n\");\n-\t\t\t\tl2fwd_ivshmem_usage(prgname);\n-\t\t\t\treturn -1;\n-\t\t\t}\n-\t\t\tbreak;\n-\n-\t\t/* long options */\n-\t\tcase 0:\n-\t\t\tl2fwd_ivshmem_usage(prgname);\n-\t\t\treturn -1;\n-\n-\t\tdefault:\n-\t\t\tl2fwd_ivshmem_usage(prgname);\n-\t\t\treturn -1;\n-\t\t}\n-\t}\n-\n-\tif (optind >= 0)\n-\t\targv[optind-1] = prgname;\n-\n-\tret = optind-1;\n-\toptind = 0; /* reset getopt lib */\n-\treturn ret;\n-}\n-\n-/* Check the link status of all ports in up to 9s, and print them finally */\n-static void\n-check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)\n-{\n-#define CHECK_INTERVAL 100 /* 100ms */\n-#define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */\n-\tuint8_t portid, count, all_ports_up, print_flag = 0;\n-\tstruct rte_eth_link link;\n-\n-\tprintf(\"\\nChecking link status\");\n-\tfflush(stdout);\n-\tfor (count = 0; count <= MAX_CHECK_TIME; count++) {\n-\t\tall_ports_up = 1;\n-\t\tfor (portid = 0; portid < port_num; portid++) {\n-\t\t\tif ((port_mask & (1 << portid)) == 0)\n-\t\t\t\tcontinue;\n-\t\t\tmemset(&link, 0, sizeof(link));\n-\t\t\trte_eth_link_get_nowait(portid, &link);\n-\t\t\t/* print link status if flag set */\n-\t\t\tif (print_flag == 1) {\n-\t\t\t\tif (link.link_status)\n-\t\t\t\t\tprintf(\"Port %d Link Up - speed %u \"\n-\t\t\t\t\t\t\"Mbps - %s\\n\", (uint8_t)portid,\n-\t\t\t\t\t\t(unsigned)link.link_speed,\n-\t\t\t\t(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?\n-\t\t\t\t\t(\"full-duplex\") : (\"half-duplex\\n\"));\n-\t\t\t\telse\n-\t\t\t\t\tprintf(\"Port %d Link Down\\n\",\n-\t\t\t\t\t\t(uint8_t)portid);\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\t/* clear all_ports_up flag if any link down */\n-\t\t\tif (link.link_status == ETH_LINK_DOWN) {\n-\t\t\t\tall_ports_up = 0;\n-\t\t\t\tbreak;\n-\t\t\t}\n-\t\t}\n-\t\t/* after finally printing all link status, get out */\n-\t\tif (print_flag == 1)\n-\t\t\tbreak;\n-\n-\t\tif (all_ports_up == 0) {\n-\t\t\tprintf(\".\");\n-\t\t\tfflush(stdout);\n-\t\t\trte_delay_ms(CHECK_INTERVAL);\n-\t\t}\n-\n-\t\t/* set the print_flag if all ports up or timeout */\n-\t\tif (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) {\n-\t\t\tprint_flag = 1;\n-\t\t\tprintf(\"done\\n\");\n-\t\t}\n-\t}\n-}\n-\n-/* Send the burst of packets on an output interface */\n-static int\n-l2fwd_ivshmem_send_burst(struct lcore_queue_conf *qconf, unsigned n, uint8_t port)\n-{\n-\tstruct rte_mbuf **m_table;\n-\tunsigned ret;\n-\tunsigned queueid =0;\n-\n-\tm_table = (struct rte_mbuf **)qconf->tx_mbufs[port].m_table;\n-\n-\tret = rte_eth_tx_burst(port, (uint16_t) queueid, m_table, (uint16_t) n);\n-\tport_statistics[port].tx += ret;\n-\tif (unlikely(ret < n)) {\n-\t\tport_statistics[port].dropped += (n - ret);\n-\t\tdo {\n-\t\t\trte_pktmbuf_free(m_table[ret]);\n-\t\t} while (++ret < n);\n-\t}\n-\n-\treturn 0;\n-}\n-\n-/* Enqueue packets for TX and prepare them to be sent on the network */\n-static int\n-l2fwd_ivshmem_send_packet(struct rte_mbuf *m, uint8_t port)\n-{\n-\tunsigned lcore_id, len;\n-\tstruct lcore_queue_conf *qconf;\n-\n-\tlcore_id = rte_lcore_id();\n-\n-\tqconf = &lcore_queue_conf[lcore_id];\n-\tlen = qconf->tx_mbufs[port].len;\n-\tqconf->tx_mbufs[port].m_table[len] = m;\n-\tlen++;\n-\n-\t/* enough pkts to be sent */\n-\tif (unlikely(len == MAX_PKT_BURST)) {\n-\t\tl2fwd_ivshmem_send_burst(qconf, MAX_PKT_BURST, port);\n-\t\tlen = 0;\n-\t}\n-\n-\tqconf->tx_mbufs[port].len = len;\n-\treturn 0;\n-}\n-\n-static int\n-l2fwd_ivshmem_receive_burst(struct lcore_queue_conf *qconf, unsigned portid,\n-\t\tunsigned vm_port)\n-{\n-\tstruct rte_mbuf ** m;\n-\tstruct rte_ring * rx;\n-\tunsigned len, pkt_idx;\n-\n-\tm = qconf->rx_mbufs[portid].m_table;\n-\tlen = qconf->rx_mbufs[portid].len;\n-\trx = qconf->port_param[vm_port]->rx_ring;\n-\n-\t/* if enqueueing failed, ring is probably full, so drop the packets */\n-\tif (rte_ring_enqueue_bulk(rx, (void**) m, len) < 0) {\n-\t\tport_statistics[portid].dropped += len;\n-\n-\t\tpkt_idx = 0;\n-\t\tdo {\n-\t\t\trte_pktmbuf_free(m[pkt_idx]);\n-\t\t} while (++pkt_idx < len);\n-\t}\n-\telse\n-\t\t/* increment rx stats by however many packets we managed to receive */\n-\t\tport_statistics[portid].rx += len;\n-\n-\treturn 0;\n-}\n-\n-/* Enqueue packets for RX and prepare them to be sent to VM */\n-static int\n-l2fwd_ivshmem_receive_packets(struct rte_mbuf ** m, unsigned n, unsigned portid,\n-\t\tunsigned vm_port)\n-{\n-\tunsigned lcore_id, len, pkt_idx;\n-\tstruct lcore_queue_conf *qconf;\n-\n-\tlcore_id = rte_lcore_id();\n-\n-\tqconf = &lcore_queue_conf[lcore_id];\n-\n-\tlen = qconf->rx_mbufs[portid].len;\n-\tpkt_idx = 0;\n-\n-\t/* enqueue packets */\n-\twhile (pkt_idx < n && len < MAX_PKT_BURST * 2) {\n-\t\tqconf->rx_mbufs[portid].m_table[len++] = m[pkt_idx++];\n-\t}\n-\n-\t/* increment queue len by however many packets we managed to receive */\n-\tqconf->rx_mbufs[portid].len += pkt_idx;\n-\n-\t/* drop the unreceived packets */\n-\tif (unlikely(pkt_idx < n)) {\n-\t\tport_statistics[portid].dropped += n - pkt_idx;\n-\t\tdo {\n-\t\t\trte_pktmbuf_free(m[pkt_idx]);\n-\t\t} while (++pkt_idx < n);\n-\t}\n-\n-\t/* drain the queue halfway through the maximum capacity */\n-\tif (unlikely(qconf->rx_mbufs[portid].len >= MAX_PKT_BURST))\n-\t\tl2fwd_ivshmem_receive_burst(qconf, portid, vm_port);\n-\n-\treturn 0;\n-}\n-\n-/* loop for host forwarding mode.\n- * the data flow is as follows:\n- *  1) get packets from TX queue and send it out from a given port\n- *  2) RX packets from given port and enqueue them on RX ring\n- *  3) dequeue packets from TX ring and put them on TX queue for a given port\n- */\n-static void\n-fwd_loop(void)\n-{\n-\tstruct rte_mbuf *pkts_burst[MAX_PKT_BURST * 2];\n-\tstruct rte_mbuf *m;\n-\tunsigned lcore_id;\n-\tuint64_t prev_tsc, diff_tsc, cur_tsc, timer_tsc;\n-\tunsigned i, j, portid, nb_rx;\n-\tstruct lcore_queue_conf *qconf;\n-\tstruct rte_ring *tx;\n-\tconst uint64_t drain_tsc = (rte_get_tsc_hz() + US_PER_S - 1) / US_PER_S * BURST_TX_DRAIN_US;\n-\n-\tprev_tsc = 0;\n-\ttimer_tsc = 0;\n-\n-\tlcore_id = rte_lcore_id();\n-\tqconf = &lcore_queue_conf[lcore_id];\n-\n-\tif (qconf->n_rx_port == 0) {\n-\t\tRTE_LOG(INFO, L2FWD_IVSHMEM, \"lcore %u has nothing to do\\n\", lcore_id);\n-\t\treturn;\n-\t}\n-\n-\tRTE_LOG(INFO, L2FWD_IVSHMEM, \"entering main loop on lcore %u\\n\", lcore_id);\n-\n-\tfor (i = 0; i < qconf->n_rx_port; i++) {\n-\n-\t\tportid = qconf->rx_port_list[i];\n-\t\tRTE_LOG(INFO, L2FWD_IVSHMEM, \" -- lcoreid=%u portid=%u\\n\", lcore_id,\n-\t\t\tportid);\n-\t}\n-\n-\twhile (ctrl->state == STATE_FWD) {\n-\n-\t\tcur_tsc = rte_rdtsc();\n-\n-\t\t/*\n-\t\t * Burst queue drain\n-\t\t */\n-\t\tdiff_tsc = cur_tsc - prev_tsc;\n-\t\tif (unlikely(diff_tsc > drain_tsc)) {\n-\n-\t\t\t/*\n-\t\t\t * TX\n-\t\t\t */\n-\t\t\tfor (portid = 0; portid < RTE_MAX_ETHPORTS; portid++) {\n-\t\t\t\tif (qconf->tx_mbufs[portid].len == 0)\n-\t\t\t\t\tcontinue;\n-\t\t\t\tl2fwd_ivshmem_send_burst(qconf,\n-\t\t\t\t\t\t qconf->tx_mbufs[portid].len,\n-\t\t\t\t\t\t (uint8_t) portid);\n-\t\t\t\tqconf->tx_mbufs[portid].len = 0;\n-\t\t\t}\n-\n-\t\t\t/*\n-\t\t\t * RX\n-\t\t\t */\n-\t\t\tfor (i = 0; i < qconf->n_rx_port; i++) {\n-\t\t\t\tportid = qconf->rx_port_list[i];\n-\t\t\t\tif (qconf->rx_mbufs[portid].len == 0)\n-\t\t\t\t\tcontinue;\n-\t\t\t\tl2fwd_ivshmem_receive_burst(qconf, portid, i);\n-\t\t\t\tqconf->rx_mbufs[portid].len = 0;\n-\t\t\t}\n-\n-\t\t\t/* if timer is enabled */\n-\t\t\tif (timer_period > 0) {\n-\n-\t\t\t\t/* advance the timer */\n-\t\t\t\ttimer_tsc += diff_tsc;\n-\n-\t\t\t\t/* if timer has reached its timeout */\n-\t\t\t\tif (unlikely(timer_tsc >= (uint64_t) timer_period)) {\n-\n-\t\t\t\t\t/* do this only on master core */\n-\t\t\t\t\tif (lcore_id == rte_get_master_lcore()) {\n-\t\t\t\t\t\tprint_stats();\n-\t\t\t\t\t\t/* reset the timer */\n-\t\t\t\t\t\ttimer_tsc = 0;\n-\t\t\t\t\t}\n-\t\t\t\t}\n-\t\t\t}\n-\n-\t\t\tprev_tsc = cur_tsc;\n-\t\t}\n-\n-\t\t/*\n-\t\t * packet RX and forwarding\n-\t\t */\n-\t\tfor (i = 0; i < qconf->n_rx_port; i++) {\n-\n-\t\t\t/* RX packets from port and put them on RX ring */\n-\t\t\tportid = qconf->rx_port_list[i];\n-\t\t\tnb_rx = rte_eth_rx_burst((uint8_t) portid, 0,\n-\t\t\t\t\t\t pkts_burst, MAX_PKT_BURST);\n-\n-\t\t\tif (nb_rx != 0)\n-\t\t\t\tl2fwd_ivshmem_receive_packets(pkts_burst, nb_rx, portid, i);\n-\n-\t\t\t/* dequeue packets from TX ring and send them to TX queue */\n-\t\t\ttx = qconf->port_param[i]->tx_ring;\n-\n-\t\t\tnb_rx = rte_ring_count(tx);\n-\n-\t\t\tnb_rx = RTE_MIN(nb_rx, (unsigned) MAX_PKT_BURST);\n-\n-\t\t\tif (nb_rx == 0)\n-\t\t\t\tcontinue;\n-\n-\t\t\t/* should not happen */\n-\t\t\tif (unlikely(rte_ring_dequeue_bulk(tx, (void**) pkts_burst, nb_rx) < 0)) {\n-\t\t\t\tctrl->state = STATE_FAIL;\n-\t\t\t\treturn;\n-\t\t\t}\n-\n-\t\t\tfor (j = 0; j < nb_rx; j++) {\n-\t\t\t\tm = pkts_burst[j];\n-\t\t\t\tl2fwd_ivshmem_send_packet(m, portid);\n-\t\t\t}\n-\t\t}\n-\t}\n-}\n-\n-static int\n-l2fwd_ivshmem_launch_one_lcore(__attribute__((unused)) void *dummy)\n-{\n-\tfwd_loop();\n-\treturn 0;\n-}\n-\n-int main(int argc, char **argv)\n-{\n-\tchar name[RTE_RING_NAMESIZE];\n-\tstruct rte_ring *r;\n-\tstruct lcore_queue_conf *qconf;\n-\tstruct rte_eth_dev_info dev_info;\n-\tuint8_t portid, port_nr;\n-\tuint8_t nb_ports, nb_ports_available;\n-\tuint8_t nb_ports_in_mask;\n-\tint ret;\n-\tunsigned lcore_id, rx_lcore_id;\n-\n-\t/* init EAL */\n-\tret = rte_eal_init(argc, argv);\n-\tif (ret < 0)\n-\t\trte_exit(EXIT_FAILURE, \"Invalid EAL arguments\\n\");\n-\targc -= ret;\n-\targv += ret;\n-\n-\t/* parse application arguments (after the EAL ones) */\n-\tret = l2fwd_ivshmem_parse_args(argc, argv);\n-\tif (ret < 0)\n-\t\trte_exit(EXIT_FAILURE, \"Invalid l2fwd-ivshmem arguments\\n\");\n-\n-\t/* create a shared mbuf pool */\n-\tl2fwd_ivshmem_pktmbuf_pool =\n-\t\trte_pktmbuf_pool_create(MBUF_MP_NAME, NB_MBUF, 32,\n-\t\t\t0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());\n-\tif (l2fwd_ivshmem_pktmbuf_pool == NULL)\n-\t\trte_exit(EXIT_FAILURE, \"Cannot init mbuf pool\\n\");\n-\n-\tnb_ports = rte_eth_dev_count();\n-\tif (nb_ports == 0)\n-\t\trte_exit(EXIT_FAILURE, \"No Ethernet ports - bye\\n\");\n-\n-\t/*\n-\t * reserve memzone to communicate with VMs - we cannot use rte_malloc here\n-\t * because while it is technically possible, it is a very bad idea to share\n-\t * the heap between two primary processes.\n-\t */\n-\tctrl_mz = rte_memzone_reserve(CTRL_MZ_NAME, sizeof(struct ivshmem_ctrl),\n-\t\t\tSOCKET_ID_ANY, 0);\n-\tif (ctrl_mz == NULL)\n-\t\trte_exit(EXIT_FAILURE, \"Cannot reserve control memzone\\n\");\n-\tctrl = (struct ivshmem_ctrl*) ctrl_mz->addr;\n-\n-\tmemset(ctrl, 0, sizeof(struct ivshmem_ctrl));\n-\n-\t/*\n-\t * Each port is assigned an output port.\n-\t */\n-\tnb_ports_in_mask = 0;\n-\tfor (portid = 0; portid < nb_ports; portid++) {\n-\t\t/* skip ports that are not enabled */\n-\t\tif ((l2fwd_ivshmem_enabled_port_mask & (1 << portid)) == 0)\n-\t\t\tcontinue;\n-\t\tif (portid % 2) {\n-\t\t\tctrl->vm_ports[nb_ports_in_mask].dst = &ctrl->vm_ports[nb_ports_in_mask-1];\n-\t\t\tctrl->vm_ports[nb_ports_in_mask-1].dst = &ctrl->vm_ports[nb_ports_in_mask];\n-\t\t}\n-\n-\t\tnb_ports_in_mask++;\n-\n-\t\trte_eth_dev_info_get(portid, &dev_info);\n-\t}\n-\tif (nb_ports_in_mask % 2) {\n-\t\tprintf(\"Notice: odd number of ports in portmask.\\n\");\n-\t\tctrl->vm_ports[nb_ports_in_mask-1].dst =\n-\t\t\t\t&ctrl->vm_ports[nb_ports_in_mask-1];\n-\t}\n-\n-\trx_lcore_id = 0;\n-\tqconf = NULL;\n-\n-\tprintf(\"Initializing ports configuration...\\n\");\n-\n-\tnb_ports_available = nb_ports;\n-\n-\t/* Initialise each port */\n-\tfor (portid = 0; portid < nb_ports; portid++) {\n-\n-\t\t/* skip ports that are not enabled */\n-\t\tif ((l2fwd_ivshmem_enabled_port_mask & (1 << portid)) == 0) {\n-\t\t\tprintf(\"Skipping disabled port %u\\n\", (unsigned) portid);\n-\t\t\tnb_ports_available--;\n-\t\t\tcontinue;\n-\t\t}\n-\n-\t\t/* init port */\n-\t\tprintf(\"Initializing port %u... \", (unsigned) portid);\n-\t\tfflush(stdout);\n-\t\tret = rte_eth_dev_configure(portid, 1, 1, &port_conf);\n-\t\tif (ret < 0)\n-\t\t\trte_exit(EXIT_FAILURE, \"Cannot configure device: err=%d, port=%u\\n\",\n-\t\t\t\t  ret, (unsigned) portid);\n-\n-\t\trte_eth_macaddr_get(portid,&l2fwd_ivshmem_ports_eth_addr[portid]);\n-\n-\t\t/* init one RX queue */\n-\t\tfflush(stdout);\n-\t\tret = rte_eth_rx_queue_setup(portid, 0, nb_rxd,\n-\t\t\t\t\t\t rte_eth_dev_socket_id(portid),\n-\t\t\t\t\t\t NULL,\n-\t\t\t\t\t\t l2fwd_ivshmem_pktmbuf_pool);\n-\t\tif (ret < 0)\n-\t\t\trte_exit(EXIT_FAILURE, \"rte_eth_rx_queue_setup:err=%d, port=%u\\n\",\n-\t\t\t\t  ret, (unsigned) portid);\n-\n-\t\t/* init one TX queue on each port */\n-\t\tfflush(stdout);\n-\t\tret = rte_eth_tx_queue_setup(portid, 0, nb_txd,\n-\t\t\t\trte_eth_dev_socket_id(portid),\n-\t\t\t\tNULL);\n-\t\tif (ret < 0)\n-\t\t\trte_exit(EXIT_FAILURE, \"rte_eth_tx_queue_setup:err=%d, port=%u\\n\",\n-\t\t\t\tret, (unsigned) portid);\n-\n-\t\t/* Start device */\n-\t\tret = rte_eth_dev_start(portid);\n-\t\tif (ret < 0)\n-\t\t\trte_exit(EXIT_FAILURE, \"rte_eth_dev_start:err=%d, port=%u\\n\",\n-\t\t\t\t  ret, (unsigned) portid);\n-\n-\t\tprintf(\"done: \\n\");\n-\n-\t\trte_eth_promiscuous_enable(portid);\n-\n-\t\tprintf(\"Port %u, MAC address: %02X:%02X:%02X:%02X:%02X:%02X\\n\\n\",\n-\t\t\t\t(unsigned) portid,\n-\t\t\t\tl2fwd_ivshmem_ports_eth_addr[portid].addr_bytes[0],\n-\t\t\t\tl2fwd_ivshmem_ports_eth_addr[portid].addr_bytes[1],\n-\t\t\t\tl2fwd_ivshmem_ports_eth_addr[portid].addr_bytes[2],\n-\t\t\t\tl2fwd_ivshmem_ports_eth_addr[portid].addr_bytes[3],\n-\t\t\t\tl2fwd_ivshmem_ports_eth_addr[portid].addr_bytes[4],\n-\t\t\t\tl2fwd_ivshmem_ports_eth_addr[portid].addr_bytes[5]);\n-\n-\t\t/* initialize port stats */\n-\t\tmemset(&port_statistics, 0, sizeof(port_statistics));\n-\t}\n-\n-\tif (!nb_ports_available) {\n-\t\trte_exit(EXIT_FAILURE,\n-\t\t\t\"All available ports are disabled. Please set portmask.\\n\");\n-\t}\n-\tport_nr = 0;\n-\n-\t/* Initialize the port/queue configuration of each logical core */\n-\tfor (portid = 0; portid < nb_ports; portid++) {\n-\t\tif ((l2fwd_ivshmem_enabled_port_mask & (1 << portid)) == 0)\n-\t\t\tcontinue;\n-\n-\t\t/* get the lcore_id for this port */\n-\t\twhile (rte_lcore_is_enabled(rx_lcore_id) == 0 ||\n-\t\t\t   lcore_queue_conf[rx_lcore_id].n_rx_port ==\n-\t\t\t\t\t   l2fwd_ivshmem_rx_queue_per_lcore) {\n-\t\t\trx_lcore_id++;\n-\t\t\tif (rx_lcore_id >= RTE_MAX_LCORE)\n-\t\t\t\trte_exit(EXIT_FAILURE, \"Not enough cores\\n\");\n-\t\t}\n-\n-\t\tif (qconf != &lcore_queue_conf[rx_lcore_id])\n-\t\t\t/* Assigned a new logical core in the loop above. */\n-\t\t\tqconf = &lcore_queue_conf[rx_lcore_id];\n-\n-\n-\t\trte_eth_macaddr_get(portid, &ctrl->vm_ports[port_nr].ethaddr);\n-\n-\t\tqconf->rx_port_list[qconf->n_rx_port] = portid;\n-\t\tqconf->port_param[qconf->n_rx_port] = &ctrl->vm_ports[port_nr];\n-\t\tqconf->n_rx_port++;\n-\t\tport_nr++;\n-\t\tprintf(\"Lcore %u: RX port %u\\n\", rx_lcore_id, (unsigned) portid);\n-\t}\n-\n-\tcheck_all_ports_link_status(nb_ports_available, l2fwd_ivshmem_enabled_port_mask);\n-\n-\t/* create rings for each VM port (several ports can be on the same VM).\n-\t * note that we store the pointers in ctrl - that way, they are the same\n-\t * and valid across all VMs because ctrl is also in DPDK memory */\n-\tfor (portid = 0; portid < nb_ports_available; portid++) {\n-\n-\t\t/* RX ring. SP/SC because it's only used by host and a single VM */\n-\t\tsnprintf(name, sizeof(name), \"%s%i\", RX_RING_PREFIX, portid);\n-\t\tr = rte_ring_create(name, NB_MBUF,\n-\t\t\t\tSOCKET_ID_ANY, RING_F_SP_ENQ | RING_F_SC_DEQ);\n-\t\tif (r == NULL)\n-\t\t\trte_exit(EXIT_FAILURE, \"Cannot create ring %s\\n\", name);\n-\n-\t\tctrl->vm_ports[portid].rx_ring = r;\n-\n-\t\t/* TX ring. SP/SC because it's only used by host and a single VM */\n-\t\tsnprintf(name, sizeof(name), \"%s%i\", TX_RING_PREFIX, portid);\n-\t\tr = rte_ring_create(name, NB_MBUF,\n-\t\t\t\tSOCKET_ID_ANY, RING_F_SP_ENQ | RING_F_SC_DEQ);\n-\t\tif (r == NULL)\n-\t\t\trte_exit(EXIT_FAILURE, \"Cannot create ring %s\\n\", name);\n-\n-\t\tctrl->vm_ports[portid].tx_ring = r;\n-\t}\n-\n-\t/* create metadata, output cmdline */\n-\tif (rte_ivshmem_metadata_create(METADATA_NAME) < 0)\n-\t\trte_exit(EXIT_FAILURE, \"Cannot create IVSHMEM metadata\\n\");\n-\n-\tif (rte_ivshmem_metadata_add_memzone(ctrl_mz, METADATA_NAME))\n-\t\trte_exit(EXIT_FAILURE, \"Cannot add memzone to IVSHMEM metadata\\n\");\n-\n-\tif (rte_ivshmem_metadata_add_mempool(l2fwd_ivshmem_pktmbuf_pool, METADATA_NAME))\n-\t\trte_exit(EXIT_FAILURE, \"Cannot add mbuf mempool to IVSHMEM metadata\\n\");\n-\n-\tfor (portid = 0; portid < nb_ports_available; portid++) {\n-\t\tif (rte_ivshmem_metadata_add_ring(ctrl->vm_ports[portid].rx_ring,\n-\t\t\t\tMETADATA_NAME) < 0)\n-\t\t\trte_exit(EXIT_FAILURE, \"Cannot add ring %s to IVSHMEM metadata\\n\",\n-\t\t\t\t\tctrl->vm_ports[portid].rx_ring->name);\n-\t\tif (rte_ivshmem_metadata_add_ring(ctrl->vm_ports[portid].tx_ring,\n-\t\t\t\tMETADATA_NAME) < 0)\n-\t\t\trte_exit(EXIT_FAILURE, \"Cannot add ring %s to IVSHMEM metadata\\n\",\n-\t\t\t\t\tctrl->vm_ports[portid].tx_ring->name);\n-\t}\n-\tgenerate_ivshmem_cmdline(METADATA_NAME);\n-\n-\tctrl->nb_ports = nb_ports_available;\n-\n-\tprintf(\"Waiting for VM to initialize...\\n\");\n-\n-\t/* wait for VM to initialize */\n-\twhile (ctrl->state != STATE_FWD) {\n-\t\tif (ctrl->state == STATE_FAIL)\n-\t\t\trte_exit(EXIT_FAILURE, \"VM reported failure\\n\");\n-\n-\t\tsleep(1);\n-\t}\n-\n-\tprintf(\"Done!\\n\");\n-\n-\tsigsetup();\n-\n-\t/* launch per-lcore init on every lcore */\n-\trte_eal_mp_remote_launch(l2fwd_ivshmem_launch_one_lcore, NULL, CALL_MASTER);\n-\tRTE_LCORE_FOREACH_SLAVE(lcore_id) {\n-\t\tif (rte_eal_wait_lcore(lcore_id) < 0)\n-\t\t\treturn -1;\n-\t}\n-\n-\tif (ctrl->state == STATE_FAIL)\n-\t\trte_exit(EXIT_FAILURE, \"VM reported failure\\n\");\n-\n-\treturn 0;\n-}\ndiff --git a/examples/l2fwd-ivshmem/include/common.h b/examples/l2fwd-ivshmem/include/common.h\ndeleted file mode 100644\nindex 8564d32..0000000\n--- a/examples/l2fwd-ivshmem/include/common.h\n+++ /dev/null\n@@ -1,111 +0,0 @@\n-/*-\n- *   BSD LICENSE\n- *\n- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.\n- *   All rights reserved.\n- *\n- *   Redistribution and use in source and binary forms, with or without\n- *   modification, are permitted provided that the following conditions\n- *   are met:\n- *\n- *     * Redistributions of source code must retain the above copyright\n- *       notice, this list of conditions and the following disclaimer.\n- *     * Redistributions in binary form must reproduce the above copyright\n- *       notice, this list of conditions and the following disclaimer in\n- *       the documentation and/or other materials provided with the\n- *       distribution.\n- *     * Neither the name of Intel Corporation nor the names of its\n- *       contributors may be used to endorse or promote products derived\n- *       from this software without specific prior written permission.\n- *\n- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n- *   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n- */\n-\n-#ifndef _IVSHMEM_COMMON_H_\n-#define _IVSHMEM_COMMON_H_\n-\n-#define RTE_LOGTYPE_L2FWD_IVSHMEM RTE_LOGTYPE_USER1\n-\n-#define CTRL_MZ_NAME \"CTRL_MEMZONE\"\n-#define MBUF_MP_NAME \"MBUF_MEMPOOL\"\n-#define RX_RING_PREFIX \"RX_\"\n-#define TX_RING_PREFIX \"TX_\"\n-\n-/* A tsc-based timer responsible for triggering statistics printout */\n-#define TIMER_MILLISECOND 2000000ULL /* around 1ms at 2 Ghz */\n-#define MAX_TIMER_PERIOD 86400 /* 1 day max */\n-static int64_t timer_period = 10 * TIMER_MILLISECOND * 1000; /* default period is 10 seconds */\n-\n-#define DIM(x)\\\n-\t(sizeof(x)/sizeof(x)[0])\n-\n-#define MAX_PKT_BURST 32\n-\n-const struct rte_memzone * ctrl_mz;\n-\n-enum l2fwd_state {\n-\tSTATE_NONE = 0,\n-\tSTATE_FWD,\n-\tSTATE_EXIT,\n-\tSTATE_FAIL\n-};\n-\n-/* Per-port statistics struct */\n-struct port_statistics {\n-\tuint64_t tx;\n-\tuint64_t rx;\n-\tuint64_t dropped;\n-} __rte_cache_aligned;\n-\n-struct mbuf_table {\n-\tunsigned len;\n-\tstruct rte_mbuf *m_table[MAX_PKT_BURST * 2]; /**< allow up to two bursts */\n-};\n-\n-struct vm_port_param {\n-\tstruct rte_ring * rx_ring;         /**< receiving ring for current port */\n-\tstruct rte_ring * tx_ring;         /**< transmitting ring for current port */\n-\tstruct vm_port_param * dst;        /**< current port's destination port */\n-\tvolatile struct port_statistics stats;      /**< statistics for current port */\n-\tstruct ether_addr ethaddr;         /**< Ethernet address of the port */\n-};\n-\n-/* control structure, to synchronize host and VM */\n-struct ivshmem_ctrl {\n-\trte_spinlock_t lock;\n-\tuint8_t nb_ports;                /**< total nr of ports */\n-\tvolatile enum l2fwd_state state; /**< report state */\n-\tstruct vm_port_param vm_ports[RTE_MAX_ETHPORTS];\n-};\n-\n-struct ivshmem_ctrl * ctrl;\n-\n-static unsigned int l2fwd_ivshmem_rx_queue_per_lcore = 1;\n-\n-static void sighandler(int __rte_unused s)\n-{\n-\tctrl->state = STATE_EXIT;\n-}\n-\n-static void sigsetup(void)\n-{\n-\t   struct sigaction sigIntHandler;\n-\n-\t   sigIntHandler.sa_handler = sighandler;\n-\t   sigemptyset(&sigIntHandler.sa_mask);\n-\t   sigIntHandler.sa_flags = 0;\n-\n-\t   sigaction(SIGINT, &sigIntHandler, NULL);\n-}\n-\n-#endif /* _IVSHMEM_COMMON_H_ */\ndiff --git a/examples/packet_ordering/Makefile b/examples/packet_ordering/Makefile\nindex 9e080a3..de066c4 100644\n--- a/examples/packet_ordering/Makefile\n+++ b/examples/packet_ordering/Makefile\n@@ -34,7 +34,7 @@ $(error \"Please define RTE_SDK environment variable\")\n endif\n \n # Default target, can be overridden by command line or environment\n-RTE_TARGET ?= x86_64-ivshmem-linuxapp-gcc\n+RTE_TARGET ?= x86_64-native-linuxapp-gcc\n \n include $(RTE_SDK)/mk/rte.vars.mk\n \ndiff --git a/lib/Makefile b/lib/Makefile\nindex ca7c02f..990f23a 100644\n--- a/lib/Makefile\n+++ b/lib/Makefile\n@@ -61,7 +61,6 @@ DIRS-$(CONFIG_RTE_LIBRTE_PDUMP) += librte_pdump\n \n ifeq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)\n DIRS-$(CONFIG_RTE_LIBRTE_KNI) += librte_kni\n-DIRS-$(CONFIG_RTE_LIBRTE_IVSHMEM) += librte_ivshmem\n endif\n \n include $(RTE_SDK)/mk/rte.subdir.mk\ndiff --git a/lib/librte_eal/common/eal_common_memzone.c b/lib/librte_eal/common/eal_common_memzone.c\nindex 1bd0a33..64f4e0a 100644\n--- a/lib/librte_eal/common/eal_common_memzone.c\n+++ b/lib/librte_eal/common/eal_common_memzone.c\n@@ -337,19 +337,7 @@ rte_memzone_free(const struct rte_memzone *mz)\n \tidx = ((uintptr_t)mz - (uintptr_t)mcfg->memzone);\n \tidx = idx / sizeof(struct rte_memzone);\n \n-#ifdef RTE_LIBRTE_IVSHMEM\n-\t/*\n-\t * If ioremap_addr is set, it's an IVSHMEM memzone and we cannot\n-\t * free it.\n-\t */\n-\tif (mcfg->memzone[idx].ioremap_addr != 0) {\n-\t\trte_rwlock_write_unlock(&mcfg->mlock);\n-\t\treturn -EINVAL;\n-\t}\n-#endif\n-\n \taddr = mcfg->memzone[idx].addr;\n-\n \tif (addr == NULL)\n \t\tret = -EINVAL;\n \telse if (mcfg->memzone_cnt == 0) {\ndiff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h\nindex 857dc3e..0bda493 100644\n--- a/lib/librte_eal/common/eal_private.h\n+++ b/lib/librte_eal/common/eal_private.h\n@@ -126,28 +126,6 @@ int rte_eal_log_init(const char *id, int facility);\n  */\n int rte_eal_pci_init(void);\n \n-#ifdef RTE_LIBRTE_IVSHMEM\n-/**\n- * Init the memory from IVSHMEM devices\n- *\n- * This function is private to EAL.\n- *\n- * @return\n- *  0 on success, negative on error\n- */\n-int rte_eal_ivshmem_init(void);\n-\n-/**\n- * Init objects in IVSHMEM devices\n- *\n- * This function is private to EAL.\n- *\n- * @return\n- *  0 on success, negative on error\n- */\n-int rte_eal_ivshmem_obj_init(void);\n-#endif\n-\n struct rte_pci_driver;\n struct rte_pci_device;\n \ndiff --git a/lib/librte_eal/common/include/rte_memory.h b/lib/librte_eal/common/include/rte_memory.h\nindex 0661109..d9e8c21 100644\n--- a/lib/librte_eal/common/include/rte_memory.h\n+++ b/lib/librte_eal/common/include/rte_memory.h\n@@ -107,9 +107,6 @@ struct rte_memseg {\n \t\tvoid *addr;         /**< Start virtual address. */\n \t\tuint64_t addr_64;   /**< Makes sure addr is always 64 bits */\n \t};\n-#ifdef RTE_LIBRTE_IVSHMEM\n-\tphys_addr_t ioremap_addr; /**< Real physical address inside the VM */\n-#endif\n \tsize_t len;               /**< Length of the segment. */\n \tuint64_t hugepage_sz;       /**< The pagesize of underlying memory */\n \tint32_t socket_id;          /**< NUMA socket ID. */\ndiff --git a/lib/librte_eal/common/include/rte_memzone.h b/lib/librte_eal/common/include/rte_memzone.h\nindex f69b5a8..dae98f5 100644\n--- a/lib/librte_eal/common/include/rte_memzone.h\n+++ b/lib/librte_eal/common/include/rte_memzone.h\n@@ -82,9 +82,6 @@ struct rte_memzone {\n \t\tvoid *addr;                   /**< Start virtual address. */\n \t\tuint64_t addr_64;             /**< Makes sure addr is always 64-bits */\n \t};\n-#ifdef RTE_LIBRTE_IVSHMEM\n-\tphys_addr_t ioremap_addr;         /**< Real physical address inside the VM */\n-#endif\n \tsize_t len;                       /**< Length of the memzone. */\n \n \tuint64_t hugepage_sz;             /**< The page size of underlying memory */\n@@ -256,12 +253,10 @@ const struct rte_memzone *rte_memzone_reserve_bounded(const char *name,\n /**\n  * Free a memzone.\n  *\n- * Note: an IVSHMEM zone cannot be freed.\n- *\n  * @param mz\n  *   A pointer to the memzone\n  * @return\n- *  -EINVAL - invalid parameter, IVSHMEM memzone.\n+ *  -EINVAL - invalid parameter.\n  *  0 - success\n  */\n int rte_memzone_free(const struct rte_memzone *mz);\ndiff --git a/lib/librte_eal/common/malloc_heap.c b/lib/librte_eal/common/malloc_heap.c\nindex 763fa32..267a4c6 100644\n--- a/lib/librte_eal/common/malloc_heap.c\n+++ b/lib/librte_eal/common/malloc_heap.c\n@@ -221,14 +221,6 @@ rte_eal_malloc_heap_init(void)\n \tfor (ms = &mcfg->memseg[0], ms_cnt = 0;\n \t\t\t(ms_cnt < RTE_MAX_MEMSEG) && (ms->len > 0);\n \t\t\tms_cnt++, ms++) {\n-#ifdef RTE_LIBRTE_IVSHMEM\n-\t\t/*\n-\t\t * if segment has ioremap address set, it's an IVSHMEM segment and\n-\t\t * it is not memory to allocate from.\n-\t\t */\n-\t\tif (ms->ioremap_addr != 0)\n-\t\t\tcontinue;\n-#endif\n \t\tmalloc_heap_add_memseg(&mcfg->malloc_heaps[ms->socket_id], ms);\n \t}\n \ndiff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile\nindex 182729c..0baa571 100644\n--- a/lib/librte_eal/linuxapp/eal/Makefile\n+++ b/lib/librte_eal/linuxapp/eal/Makefile\n@@ -44,12 +44,6 @@ VPATH += $(RTE_SDK)/lib/librte_eal/common\n CFLAGS += -I$(SRCDIR)/include\n CFLAGS += -I$(RTE_SDK)/lib/librte_eal/common\n CFLAGS += -I$(RTE_SDK)/lib/librte_eal/common/include\n-ifeq ($(CONFIG_RTE_LIBRTE_IVSHMEM),y)\n-# workaround for circular dependency eal -> ivshmem -> ring/mempool -> eal\n-CFLAGS += -I$(RTE_SDK)/lib/librte_ring\n-CFLAGS += -I$(RTE_SDK)/lib/librte_mempool\n-CFLAGS += -I$(RTE_SDK)/lib/librte_ivshmem\n-endif\n CFLAGS += $(WERROR_FLAGS) -O3\n \n LDLIBS += -ldl\n@@ -76,9 +70,6 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_lcore.c\n SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_timer.c\n SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_interrupts.c\n SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_alarm.c\n-ifeq ($(CONFIG_RTE_LIBRTE_IVSHMEM),y)\n-SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_ivshmem.c\n-endif\n \n # from common dir\n SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_lcore.c\ndiff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c\nindex 3fb2188..d5b81a3 100644\n--- a/lib/librte_eal/linuxapp/eal/eal.c\n+++ b/lib/librte_eal/linuxapp/eal/eal.c\n@@ -797,11 +797,6 @@ rte_eal_init(int argc, char **argv)\n \t\trte_panic(\"Cannot init VFIO\\n\");\n #endif\n \n-#ifdef RTE_LIBRTE_IVSHMEM\n-\tif (rte_eal_ivshmem_init() < 0)\n-\t\trte_panic(\"Cannot init IVSHMEM\\n\");\n-#endif\n-\n \tif (rte_eal_memory_init() < 0)\n \t\trte_panic(\"Cannot init memory\\n\");\n \n@@ -814,11 +809,6 @@ rte_eal_init(int argc, char **argv)\n \tif (rte_eal_tailqs_init() < 0)\n \t\trte_panic(\"Cannot init tail queues for objects\\n\");\n \n-#ifdef RTE_LIBRTE_IVSHMEM\n-\tif (rte_eal_ivshmem_obj_init() < 0)\n-\t\trte_panic(\"Cannot init IVSHMEM objects\\n\");\n-#endif\n-\n \tif (rte_eal_log_init(logid, internal_config.syslog_facility) < 0)\n \t\trte_panic(\"Cannot init logs\\n\");\n \ndiff --git a/lib/librte_eal/linuxapp/eal/eal_ivshmem.c b/lib/librte_eal/linuxapp/eal/eal_ivshmem.c\ndeleted file mode 100644\nindex 67b3caf..0000000\n--- a/lib/librte_eal/linuxapp/eal/eal_ivshmem.c\n+++ /dev/null\n@@ -1,954 +0,0 @@\n-/*-\n- *   BSD LICENSE\n- *\n- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.\n- *   All rights reserved.\n- *\n- *   Redistribution and use in source and binary forms, with or without\n- *   modification, are permitted provided that the following conditions\n- *   are met:\n- *\n- *     * Redistributions of source code must retain the above copyright\n- *       notice, this list of conditions and the following disclaimer.\n- *     * Redistributions in binary form must reproduce the above copyright\n- *       notice, this list of conditions and the following disclaimer in\n- *       the documentation and/or other materials provided with the\n- *       distribution.\n- *     * Neither the name of Intel Corporation nor the names of its\n- *       contributors may be used to endorse or promote products derived\n- *       from this software without specific prior written permission.\n- *\n- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n- *   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n- */\n-\n-#ifdef RTE_LIBRTE_IVSHMEM /* hide it from coverage */\n-\n-#include <stdint.h>\n-#include <unistd.h>\n-#include <inttypes.h>\n-#include <sys/mman.h>\n-#include <sys/file.h>\n-#include <string.h>\n-#include <sys/queue.h>\n-\n-#include <rte_log.h>\n-#include <rte_pci.h>\n-#include <rte_memory.h>\n-#include <rte_eal.h>\n-#include <rte_eal_memconfig.h>\n-#include <rte_string_fns.h>\n-#include <rte_errno.h>\n-#include <rte_ring.h>\n-#include <rte_malloc.h>\n-#include <rte_common.h>\n-#include <rte_ivshmem.h>\n-\n-#include \"eal_internal_cfg.h\"\n-#include \"eal_private.h\"\n-\n-#define PCI_VENDOR_ID_IVSHMEM 0x1Af4\n-#define PCI_DEVICE_ID_IVSHMEM 0x1110\n-\n-#define IVSHMEM_MAGIC 0x0BADC0DE\n-\n-#define IVSHMEM_RESOURCE_PATH \"/sys/bus/pci/devices/%04x:%02x:%02x.%x/resource2\"\n-#define IVSHMEM_CONFIG_PATH \"/var/run/.%s_ivshmem_config\"\n-\n-#define PHYS 0x1\n-#define VIRT 0x2\n-#define IOREMAP 0x4\n-#define FULL (PHYS|VIRT|IOREMAP)\n-\n-#define METADATA_SIZE_ALIGNED \\\n-\t(RTE_ALIGN_CEIL(sizeof(struct rte_ivshmem_metadata),pagesz))\n-\n-#define CONTAINS(x,y)\\\n-\t(((y).addr_64 >= (x).addr_64) && ((y).addr_64 < (x).addr_64 + (x).len))\n-\n-#define DIM(x) (sizeof(x)/sizeof(x[0]))\n-\n-struct ivshmem_pci_device {\n-\tchar path[PATH_MAX];\n-\tphys_addr_t ioremap_addr;\n-};\n-\n-/* data type to store in config */\n-struct ivshmem_segment {\n-\tstruct rte_ivshmem_metadata_entry entry;\n-\tuint64_t align;\n-\tchar path[PATH_MAX];\n-};\n-struct ivshmem_shared_config {\n-\tstruct ivshmem_segment segment[RTE_MAX_MEMSEG];\n-\tuint32_t segment_idx;\n-\tstruct ivshmem_pci_device pci_devs[RTE_LIBRTE_IVSHMEM_MAX_PCI_DEVS];\n-\tuint32_t pci_devs_idx;\n-};\n-static struct ivshmem_shared_config * ivshmem_config;\n-static int memseg_idx;\n-static int pagesz;\n-\n-/* Tailq heads to add rings to */\n-TAILQ_HEAD(rte_ring_list, rte_tailq_entry);\n-\n-/*\n- * Utility functions\n- */\n-\n-static int\n-is_ivshmem_device(struct rte_pci_device * dev)\n-{\n-\treturn dev->id.vendor_id == PCI_VENDOR_ID_IVSHMEM\n-\t\t\t&& dev->id.device_id == PCI_DEVICE_ID_IVSHMEM;\n-}\n-\n-static void *\n-map_metadata(int fd, uint64_t len)\n-{\n-\tsize_t metadata_len = sizeof(struct rte_ivshmem_metadata);\n-\tsize_t aligned_len = METADATA_SIZE_ALIGNED;\n-\n-\treturn mmap(NULL, metadata_len, PROT_READ | PROT_WRITE,\n-\t\t\tMAP_SHARED, fd, len - aligned_len);\n-}\n-\n-static void\n-unmap_metadata(void * ptr)\n-{\n-\tmunmap(ptr, sizeof(struct rte_ivshmem_metadata));\n-}\n-\n-static int\n-has_ivshmem_metadata(int fd, uint64_t len)\n-{\n-\tstruct rte_ivshmem_metadata metadata;\n-\tvoid * ptr;\n-\n-\tptr = map_metadata(fd, len);\n-\n-\tif (ptr == MAP_FAILED)\n-\t\treturn -1;\n-\n-\tmetadata = *(struct rte_ivshmem_metadata*) (ptr);\n-\n-\tunmap_metadata(ptr);\n-\n-\treturn metadata.magic_number == IVSHMEM_MAGIC;\n-}\n-\n-static void\n-remove_segment(struct ivshmem_segment * ms, int len, int idx)\n-{\n-\tint i;\n-\n-\tfor (i = idx; i < len - 1; i++)\n-\t\tmemcpy(&ms[i], &ms[i+1], sizeof(struct ivshmem_segment));\n-\tmemset(&ms[len-1], 0, sizeof(struct ivshmem_segment));\n-}\n-\n-static int\n-overlap(const struct rte_memzone * mz1, const struct rte_memzone * mz2)\n-{\n-\tuint64_t start1, end1, start2, end2;\n-\tuint64_t p_start1, p_end1, p_start2, p_end2;\n-\tuint64_t i_start1, i_end1, i_start2, i_end2;\n-\tint result = 0;\n-\n-\t/* gather virtual addresses */\n-\tstart1 = mz1->addr_64;\n-\tend1 = mz1->addr_64 + mz1->len;\n-\tstart2 = mz2->addr_64;\n-\tend2 = mz2->addr_64 + mz2->len;\n-\n-\t/* gather physical addresses */\n-\tp_start1 = mz1->phys_addr;\n-\tp_end1 = mz1->phys_addr + mz1->len;\n-\tp_start2 = mz2->phys_addr;\n-\tp_end2 = mz2->phys_addr + mz2->len;\n-\n-\t/* gather ioremap addresses */\n-\ti_start1 = mz1->ioremap_addr;\n-\ti_end1 = mz1->ioremap_addr + mz1->len;\n-\ti_start2 = mz2->ioremap_addr;\n-\ti_end2 = mz2->ioremap_addr + mz2->len;\n-\n-\t/* check for overlap in virtual addresses */\n-\tif (start1 >= start2 && start1 < end2)\n-\t\tresult |= VIRT;\n-\tif (start2 >= start1 && start2 < end1)\n-\t\tresult |= VIRT;\n-\n-\t/* check for overlap in physical addresses */\n-\tif (p_start1 >= p_start2 && p_start1 < p_end2)\n-\t\tresult |= PHYS;\n-\tif (p_start2 >= p_start1 && p_start2 < p_end1)\n-\t\tresult |= PHYS;\n-\n-\t/* check for overlap in ioremap addresses */\n-\tif (i_start1 >= i_start2 && i_start1 < i_end2)\n-\t\tresult |= IOREMAP;\n-\tif (i_start2 >= i_start1 && i_start2 < i_end1)\n-\t\tresult |= IOREMAP;\n-\n-\treturn result;\n-}\n-\n-static int\n-adjacent(const struct rte_memzone * mz1, const struct rte_memzone * mz2)\n-{\n-\tuint64_t start1, end1, start2, end2;\n-\tuint64_t p_start1, p_end1, p_start2, p_end2;\n-\tuint64_t i_start1, i_end1, i_start2, i_end2;\n-\tint result = 0;\n-\n-\t/* gather virtual addresses */\n-\tstart1 = mz1->addr_64;\n-\tend1 = mz1->addr_64 + mz1->len;\n-\tstart2 = mz2->addr_64;\n-\tend2 = mz2->addr_64 + mz2->len;\n-\n-\t/* gather physical addresses */\n-\tp_start1 = mz1->phys_addr;\n-\tp_end1 = mz1->phys_addr + mz1->len;\n-\tp_start2 = mz2->phys_addr;\n-\tp_end2 = mz2->phys_addr + mz2->len;\n-\n-\t/* gather ioremap addresses */\n-\ti_start1 = mz1->ioremap_addr;\n-\ti_end1 = mz1->ioremap_addr + mz1->len;\n-\ti_start2 = mz2->ioremap_addr;\n-\ti_end2 = mz2->ioremap_addr + mz2->len;\n-\n-\t/* check if segments are virtually adjacent */\n-\tif (start1 == end2)\n-\t\tresult |= VIRT;\n-\tif (start2 == end1)\n-\t\tresult |= VIRT;\n-\n-\t/* check if segments are physically adjacent */\n-\tif (p_start1 == p_end2)\n-\t\tresult |= PHYS;\n-\tif (p_start2 == p_end1)\n-\t\tresult |= PHYS;\n-\n-\t/* check if segments are ioremap-adjacent */\n-\tif (i_start1 == i_end2)\n-\t\tresult |= IOREMAP;\n-\tif (i_start2 == i_end1)\n-\t\tresult |= IOREMAP;\n-\n-\treturn result;\n-}\n-\n-static int\n-has_adjacent_segments(struct ivshmem_segment * ms, int len)\n-{\n-\tint i, j;\n-\n-\tfor (i = 0; i < len; i++)\n-\t\tfor (j = i + 1; j < len; j++) {\n-\t\t\t/* we're only interested in fully adjacent segments; partially\n-\t\t\t * adjacent segments can coexist.\n-\t\t\t */\n-\t\t\tif (adjacent(&ms[i].entry.mz, &ms[j].entry.mz) == FULL)\n-\t\t\t\treturn 1;\n-\t\t}\n-\treturn 0;\n-}\n-\n-static int\n-has_overlapping_segments(struct ivshmem_segment * ms, int len)\n-{\n-\tint i, j;\n-\n-\tfor (i = 0; i < len; i++)\n-\t\tfor (j = i + 1; j < len; j++)\n-\t\t\tif (overlap(&ms[i].entry.mz, &ms[j].entry.mz))\n-\t\t\t\treturn 1;\n-\treturn 0;\n-}\n-\n-static int\n-seg_compare(const void * a, const void * b)\n-{\n-\tconst struct ivshmem_segment * s1 = (const struct ivshmem_segment*) a;\n-\tconst struct ivshmem_segment * s2 = (const struct ivshmem_segment*) b;\n-\n-\t/* move unallocated zones to the end */\n-\tif (s1->entry.mz.addr == NULL && s2->entry.mz.addr == NULL)\n-\t\treturn 0;\n-\tif (s1->entry.mz.addr == 0)\n-\t\treturn 1;\n-\tif (s2->entry.mz.addr == 0)\n-\t\treturn -1;\n-\n-\treturn s1->entry.mz.phys_addr > s2->entry.mz.phys_addr;\n-}\n-\n-#ifdef RTE_LIBRTE_IVSHMEM_DEBUG\n-static void\n-entry_dump(struct rte_ivshmem_metadata_entry *e)\n-{\n-\tRTE_LOG(DEBUG, EAL, \"\\tvirt: %p-%p\\n\", e->mz.addr,\n-\t\t\tRTE_PTR_ADD(e->mz.addr, e->mz.len));\n-\tRTE_LOG(DEBUG, EAL, \"\\tphys: 0x%\" PRIx64 \"-0x%\" PRIx64 \"\\n\",\n-\t\t\te->mz.phys_addr,\n-\t\t\te->mz.phys_addr + e->mz.len);\n-\tRTE_LOG(DEBUG, EAL, \"\\tio: 0x%\" PRIx64 \"-0x%\" PRIx64 \"\\n\",\n-\t\t\te->mz.ioremap_addr,\n-\t\t\te->mz.ioremap_addr + e->mz.len);\n-\tRTE_LOG(DEBUG, EAL, \"\\tlen: 0x%\" PRIx64 \"\\n\", e->mz.len);\n-\tRTE_LOG(DEBUG, EAL, \"\\toff: 0x%\" PRIx64 \"\\n\", e->offset);\n-}\n-#endif\n-\n-\n-\n-/*\n- * Actual useful code\n- */\n-\n-/* read through metadata mapped from the IVSHMEM device */\n-static int\n-read_metadata(char * path, int path_len, int fd, uint64_t flen)\n-{\n-\tstruct rte_ivshmem_metadata metadata;\n-\tstruct rte_ivshmem_metadata_entry * entry;\n-\tint idx, i;\n-\tvoid * ptr;\n-\n-\tptr = map_metadata(fd, flen);\n-\n-\tif (ptr == MAP_FAILED)\n-\t\treturn -1;\n-\n-\tmetadata = *(struct rte_ivshmem_metadata*) (ptr);\n-\n-\tunmap_metadata(ptr);\n-\n-\tRTE_LOG(DEBUG, EAL, \"Parsing metadata for \\\"%s\\\"\\n\", metadata.name);\n-\n-\tidx = ivshmem_config->segment_idx;\n-\n-\tfor (i = 0; i < RTE_LIBRTE_IVSHMEM_MAX_ENTRIES &&\n-\t\tidx <= RTE_MAX_MEMSEG; i++) {\n-\n-\t\tif (idx == RTE_MAX_MEMSEG) {\n-\t\t\tRTE_LOG(ERR, EAL, \"Not enough memory segments!\\n\");\n-\t\t\treturn -1;\n-\t\t}\n-\n-\t\tentry = &metadata.entry[i];\n-\n-\t\t/* stop on uninitialized memzone */\n-\t\tif (entry->mz.len == 0)\n-\t\t\tbreak;\n-\n-\t\t/* copy metadata entry */\n-\t\tmemcpy(&ivshmem_config->segment[idx].entry, entry,\n-\t\t\t\tsizeof(struct rte_ivshmem_metadata_entry));\n-\n-\t\t/* copy path */\n-\t\tsnprintf(ivshmem_config->segment[idx].path, path_len, \"%s\", path);\n-\n-\t\tidx++;\n-\t}\n-\tivshmem_config->segment_idx = idx;\n-\n-\treturn 0;\n-}\n-\n-/* check through each segment and look for adjacent or overlapping ones. */\n-static int\n-cleanup_segments(struct ivshmem_segment * ms, int tbl_len)\n-{\n-\tstruct ivshmem_segment * s, * tmp;\n-\tint i, j, concat, seg_adjacent, seg_overlapping;\n-\tuint64_t start1, start2, end1, end2, p_start1, p_start2, i_start1, i_start2;\n-\n-\tqsort(ms, tbl_len, sizeof(struct ivshmem_segment),\n-\t\t\t\tseg_compare);\n-\n-\twhile (has_overlapping_segments(ms, tbl_len) ||\n-\t\t\thas_adjacent_segments(ms, tbl_len)) {\n-\n-\t\tfor (i = 0; i < tbl_len; i++) {\n-\t\t\ts = &ms[i];\n-\n-\t\t\tconcat = 0;\n-\n-\t\t\tfor (j = i + 1; j < tbl_len; j++) {\n-\t\t\t\ttmp = &ms[j];\n-\n-\t\t\t\t/* check if this segment is overlapping with existing segment,\n-\t\t\t\t * or is adjacent to existing segment */\n-\t\t\t\tseg_overlapping = overlap(&s->entry.mz, &tmp->entry.mz);\n-\t\t\t\tseg_adjacent = adjacent(&s->entry.mz, &tmp->entry.mz);\n-\n-\t\t\t\t/* check if segments fully overlap or are fully adjacent */\n-\t\t\t\tif ((seg_adjacent == FULL) || (seg_overlapping == FULL)) {\n-\n-#ifdef RTE_LIBRTE_IVSHMEM_DEBUG\n-\t\t\t\t\tRTE_LOG(DEBUG, EAL, \"Concatenating segments\\n\");\n-\t\t\t\t\tRTE_LOG(DEBUG, EAL, \"Segment %i:\\n\", i);\n-\t\t\t\t\tentry_dump(&s->entry);\n-\t\t\t\t\tRTE_LOG(DEBUG, EAL, \"Segment %i:\\n\", j);\n-\t\t\t\t\tentry_dump(&tmp->entry);\n-#endif\n-\n-\t\t\t\t\tstart1 = s->entry.mz.addr_64;\n-\t\t\t\t\tstart2 = tmp->entry.mz.addr_64;\n-\t\t\t\t\tp_start1 = s->entry.mz.phys_addr;\n-\t\t\t\t\tp_start2 = tmp->entry.mz.phys_addr;\n-\t\t\t\t\ti_start1 = s->entry.mz.ioremap_addr;\n-\t\t\t\t\ti_start2 = tmp->entry.mz.ioremap_addr;\n-\t\t\t\t\tend1 = s->entry.mz.addr_64 + s->entry.mz.len;\n-\t\t\t\t\tend2 = tmp->entry.mz.addr_64 + tmp->entry.mz.len;\n-\n-\t\t\t\t\t/* settle for minimum start address and maximum length */\n-\t\t\t\t\ts->entry.mz.addr_64 = RTE_MIN(start1, start2);\n-\t\t\t\t\ts->entry.mz.phys_addr = RTE_MIN(p_start1, p_start2);\n-\t\t\t\t\ts->entry.mz.ioremap_addr = RTE_MIN(i_start1, i_start2);\n-\t\t\t\t\ts->entry.offset = RTE_MIN(s->entry.offset, tmp->entry.offset);\n-\t\t\t\t\ts->entry.mz.len = RTE_MAX(end1, end2) - s->entry.mz.addr_64;\n-\t\t\t\t\tconcat = 1;\n-\n-#ifdef RTE_LIBRTE_IVSHMEM_DEBUG\n-\t\t\t\t\tRTE_LOG(DEBUG, EAL, \"Resulting segment:\\n\");\n-\t\t\t\t\tentry_dump(&s->entry);\n-\n-#endif\n-\t\t\t\t}\n-\t\t\t\t/* if segments not fully overlap, we have an error condition.\n-\t\t\t\t * adjacent segments can coexist.\n-\t\t\t\t */\n-\t\t\t\telse if (seg_overlapping > 0) {\n-\t\t\t\t\tRTE_LOG(ERR, EAL, \"Segments %i and %i overlap!\\n\", i, j);\n-#ifdef RTE_LIBRTE_IVSHMEM_DEBUG\n-\t\t\t\t\tRTE_LOG(DEBUG, EAL, \"Segment %i:\\n\", i);\n-\t\t\t\t\tentry_dump(&s->entry);\n-\t\t\t\t\tRTE_LOG(DEBUG, EAL, \"Segment %i:\\n\", j);\n-\t\t\t\t\tentry_dump(&tmp->entry);\n-#endif\n-\t\t\t\t\treturn -1;\n-\t\t\t\t}\n-\t\t\t\tif (concat)\n-\t\t\t\t\tbreak;\n-\t\t\t}\n-\t\t\t/* if we concatenated, remove segment at j */\n-\t\t\tif (concat) {\n-\t\t\t\tremove_segment(ms, tbl_len, j);\n-\t\t\t\ttbl_len--;\n-\t\t\t\tbreak;\n-\t\t\t}\n-\t\t}\n-\t}\n-\n-\treturn tbl_len;\n-}\n-\n-static int\n-create_shared_config(void)\n-{\n-\tchar path[PATH_MAX];\n-\tint fd;\n-\n-\t/* build ivshmem config file path */\n-\tsnprintf(path, sizeof(path), IVSHMEM_CONFIG_PATH,\n-\t\t\tinternal_config.hugefile_prefix);\n-\n-\tfd = open(path, O_CREAT | O_RDWR, 0600);\n-\n-\tif (fd < 0) {\n-\t\tRTE_LOG(ERR, EAL, \"Could not open %s: %s\\n\", path, strerror(errno));\n-\t\treturn -1;\n-\t}\n-\n-\t/* try ex-locking first - if the file is locked, we have a problem */\n-\tif (flock(fd, LOCK_EX | LOCK_NB) == -1) {\n-\t\tRTE_LOG(ERR, EAL, \"Locking %s failed: %s\\n\", path, strerror(errno));\n-\t\tclose(fd);\n-\t\treturn -1;\n-\t}\n-\n-\tif (ftruncate(fd, sizeof(struct ivshmem_shared_config)) < 0) {\n-\t\tRTE_LOG(ERR, EAL, \"ftruncate failed: %s\\n\", strerror(errno));\n-\t\treturn -1;\n-\t}\n-\n-\tivshmem_config = mmap(NULL, sizeof(struct ivshmem_shared_config),\n-\t\t\tPROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);\n-\n-\tif (ivshmem_config == MAP_FAILED)\n-\t\treturn -1;\n-\n-\tmemset(ivshmem_config, 0, sizeof(struct ivshmem_shared_config));\n-\n-\t/* change the exclusive lock we got earlier to a shared lock */\n-\tif (flock(fd, LOCK_SH | LOCK_NB) == -1) {\n-\t\tRTE_LOG(ERR, EAL, \"Locking %s failed: %s \\n\", path, strerror(errno));\n-\t\treturn -1;\n-\t}\n-\n-\tclose(fd);\n-\n-\treturn 0;\n-}\n-\n-/* open shared config file and, if present, map the config.\n- * having no config file is not an error condition, as we later check if\n- * ivshmem_config is NULL (if it is, that means nothing was mapped). */\n-static int\n-open_shared_config(void)\n-{\n-\tchar path[PATH_MAX];\n-\tint fd;\n-\n-\t/* build ivshmem config file path */\n-\tsnprintf(path, sizeof(path), IVSHMEM_CONFIG_PATH,\n-\t\t\tinternal_config.hugefile_prefix);\n-\n-\tfd = open(path, O_RDONLY);\n-\n-\t/* if the file doesn't exist, just return success */\n-\tif (fd < 0 && errno == ENOENT)\n-\t\treturn 0;\n-\t/* else we have an error condition */\n-\telse if (fd < 0) {\n-\t\tRTE_LOG(ERR, EAL, \"Could not open %s: %s\\n\",\n-\t\t\t\tpath, strerror(errno));\n-\t\treturn -1;\n-\t}\n-\n-\t/* try ex-locking first - if the lock *does* succeed, this means it's a\n-\t * stray config file, so it should be deleted.\n-\t */\n-\tif (flock(fd, LOCK_EX | LOCK_NB) != -1) {\n-\n-\t\t/* if we can't remove the file, something is wrong */\n-\t\tif (unlink(path) < 0) {\n-\t\t\tRTE_LOG(ERR, EAL, \"Could not remove %s: %s\\n\", path,\n-\t\t\t\t\tstrerror(errno));\n-\t\t\treturn -1;\n-\t\t}\n-\n-\t\t/* release the lock */\n-\t\tflock(fd, LOCK_UN);\n-\t\tclose(fd);\n-\n-\t\t/* return success as having a stray config file is equivalent to not\n-\t\t * having config file at all.\n-\t\t */\n-\t\treturn 0;\n-\t}\n-\n-\tivshmem_config = mmap(NULL, sizeof(struct ivshmem_shared_config),\n-\t\t\tPROT_READ, MAP_SHARED, fd, 0);\n-\n-\tif (ivshmem_config == MAP_FAILED)\n-\t\treturn -1;\n-\n-\t/* place a shared lock on config file */\n-\tif (flock(fd, LOCK_SH | LOCK_NB) == -1) {\n-\t\tRTE_LOG(ERR, EAL, \"Locking %s failed: %s \\n\", path, strerror(errno));\n-\t\treturn -1;\n-\t}\n-\n-\tclose(fd);\n-\n-\treturn 0;\n-}\n-\n-/*\n- * This function does the following:\n- *\n- * 1) Builds a table of ivshmem_segments with proper offset alignment\n- * 2) Cleans up that table so that we don't have any overlapping or adjacent\n- *    memory segments\n- * 3) Creates memsegs from this table and maps them into memory.\n- */\n-static inline int\n-map_all_segments(void)\n-{\n-\tstruct ivshmem_segment ms_tbl[RTE_MAX_MEMSEG];\n-\tstruct ivshmem_pci_device * pci_dev;\n-\tstruct rte_mem_config * mcfg;\n-\tstruct ivshmem_segment * seg;\n-\tint fd, fd_zero;\n-\tunsigned i, j;\n-\tstruct rte_memzone mz;\n-\tstruct rte_memseg ms;\n-\tvoid * base_addr;\n-\tuint64_t align, len;\n-\tphys_addr_t ioremap_addr;\n-\n-\tioremap_addr = 0;\n-\n-\tmemset(ms_tbl, 0, sizeof(ms_tbl));\n-\tmemset(&mz, 0, sizeof(struct rte_memzone));\n-\tmemset(&ms, 0, sizeof(struct rte_memseg));\n-\n-\t/* first, build a table of memsegs to map, to avoid failed mmaps due to\n-\t * overlaps\n-\t */\n-\tfor (i = 0; i < ivshmem_config->segment_idx && i <= RTE_MAX_MEMSEG; i++) {\n-\t\tif (i == RTE_MAX_MEMSEG) {\n-\t\t\tRTE_LOG(ERR, EAL, \"Too many segments requested!\\n\");\n-\t\t\treturn -1;\n-\t\t}\n-\n-\t\tseg = &ivshmem_config->segment[i];\n-\n-\t\t/* copy segment to table */\n-\t\tmemcpy(&ms_tbl[i], seg, sizeof(struct ivshmem_segment));\n-\n-\t\t/* find ioremap addr */\n-\t\tfor (j = 0; j < DIM(ivshmem_config->pci_devs); j++) {\n-\t\t\tpci_dev = &ivshmem_config->pci_devs[j];\n-\t\t\tif (!strncmp(pci_dev->path, seg->path, sizeof(pci_dev->path))) {\n-\t\t\t\tioremap_addr = pci_dev->ioremap_addr;\n-\t\t\t\tbreak;\n-\t\t\t}\n-\t\t}\n-\t\tif (ioremap_addr == 0) {\n-\t\t\tRTE_LOG(ERR, EAL, \"Cannot find ioremap addr!\\n\");\n-\t\t\treturn -1;\n-\t\t}\n-\n-\t\t/* work out alignments */\n-\t\talign = seg->entry.mz.addr_64 -\n-\t\t\t\tRTE_ALIGN_FLOOR(seg->entry.mz.addr_64, 0x1000);\n-\t\tlen = RTE_ALIGN_CEIL(seg->entry.mz.len + align, 0x1000);\n-\n-\t\t/* save original alignments */\n-\t\tms_tbl[i].align = align;\n-\n-\t\t/* create a memory zone */\n-\t\tmz.addr_64 = seg->entry.mz.addr_64 - align;\n-\t\tmz.len = len;\n-\t\tmz.hugepage_sz = seg->entry.mz.hugepage_sz;\n-\t\tmz.phys_addr = seg->entry.mz.phys_addr - align;\n-\n-\t\t/* find true physical address */\n-\t\tmz.ioremap_addr = ioremap_addr + seg->entry.offset - align;\n-\n-\t\tms_tbl[i].entry.offset = seg->entry.offset - align;\n-\n-\t\tmemcpy(&ms_tbl[i].entry.mz, &mz, sizeof(struct rte_memzone));\n-\t}\n-\n-\t/* clean up the segments */\n-\tmemseg_idx = cleanup_segments(ms_tbl, ivshmem_config->segment_idx);\n-\n-\tif (memseg_idx < 0)\n-\t\treturn -1;\n-\n-\tmcfg = rte_eal_get_configuration()->mem_config;\n-\n-\tfd_zero = open(\"/dev/zero\", O_RDWR);\n-\n-\tif (fd_zero < 0) {\n-\t\tRTE_LOG(ERR, EAL, \"Cannot open /dev/zero: %s\\n\", strerror(errno));\n-\t\treturn -1;\n-\t}\n-\n-\t/* create memsegs and put them into DPDK memory */\n-\tfor (i = 0; i < (unsigned) memseg_idx; i++) {\n-\n-\t\tseg = &ms_tbl[i];\n-\n-\t\tms.addr_64 = seg->entry.mz.addr_64;\n-\t\tms.hugepage_sz = seg->entry.mz.hugepage_sz;\n-\t\tms.len = seg->entry.mz.len;\n-\t\tms.nchannel = rte_memory_get_nchannel();\n-\t\tms.nrank = rte_memory_get_nrank();\n-\t\tms.phys_addr = seg->entry.mz.phys_addr;\n-\t\tms.ioremap_addr = seg->entry.mz.ioremap_addr;\n-\t\tms.socket_id = seg->entry.mz.socket_id;\n-\n-\t\tbase_addr = mmap(ms.addr, ms.len,\n-\t\t\t\tPROT_READ | PROT_WRITE, MAP_PRIVATE, fd_zero, 0);\n-\n-\t\tif (base_addr == MAP_FAILED || base_addr != ms.addr) {\n-\t\t\tRTE_LOG(ERR, EAL, \"Cannot map /dev/zero!\\n\");\n-\t\t\treturn -1;\n-\t\t}\n-\n-\t\tfd = open(seg->path, O_RDWR);\n-\n-\t\tif (fd < 0) {\n-\t\t\tRTE_LOG(ERR, EAL, \"Cannot open %s: %s\\n\", seg->path,\n-\t\t\t\t\tstrerror(errno));\n-\t\t\treturn -1;\n-\t\t}\n-\n-\t\tmunmap(ms.addr, ms.len);\n-\n-\t\tbase_addr = mmap(ms.addr, ms.len,\n-\t\t\t\tPROT_READ | PROT_WRITE, MAP_SHARED, fd,\n-\t\t\t\tseg->entry.offset);\n-\n-\n-\t\tif (base_addr == MAP_FAILED || base_addr != ms.addr) {\n-\t\t\tRTE_LOG(ERR, EAL, \"Cannot map segment into memory: \"\n-\t\t\t\t\t\"expected %p got %p (%s)\\n\", ms.addr, base_addr,\n-\t\t\t\t\tstrerror(errno));\n-\t\t\treturn -1;\n-\t\t}\n-\n-\t\tRTE_LOG(DEBUG, EAL, \"Memory segment mapped: %p (len %\" PRIx64 \") at \"\n-\t\t\t\t\"offset 0x%\" PRIx64 \"\\n\",\n-\t\t\t\tms.addr, ms.len, seg->entry.offset);\n-\n-\t\t/* put the pointers back into their real positions using original\n-\t\t * alignment */\n-\t\tms.addr_64 += seg->align;\n-\t\tms.phys_addr += seg->align;\n-\t\tms.ioremap_addr += seg->align;\n-\t\tms.len -= seg->align;\n-\n-\t\t/* at this point, the rest of DPDK memory is not initialized, so we\n-\t\t * expect memsegs to be empty */\n-\t\tmemcpy(&mcfg->memseg[i], &ms,\n-\t\t\t\tsizeof(struct rte_memseg));\n-\n-\t\tclose(fd);\n-\n-\t\tRTE_LOG(DEBUG, EAL, \"IVSHMEM segment found, size: 0x%lx\\n\",\n-\t\t\t\tms.len);\n-\t}\n-\n-\treturn 0;\n-}\n-\n-/* this happens at a later stage, after general EAL memory initialization */\n-int\n-rte_eal_ivshmem_obj_init(void)\n-{\n-\tstruct rte_ring_list* ring_list = NULL;\n-\tstruct rte_mem_config * mcfg;\n-\tstruct ivshmem_segment * seg;\n-\tstruct rte_memzone * mz;\n-\tstruct rte_ring * r;\n-\tstruct rte_tailq_entry *te;\n-\tunsigned i, ms, idx;\n-\tuint64_t offset;\n-\n-\t/* secondary process would not need any object discovery - it'll all\n-\t * already be in shared config */\n-\tif (rte_eal_process_type() != RTE_PROC_PRIMARY || ivshmem_config == NULL)\n-\t\treturn 0;\n-\n-\t/* check that we have an initialised ring tail queue */\n-\tring_list = RTE_TAILQ_LOOKUP(RTE_TAILQ_RING_NAME, rte_ring_list);\n-\tif (ring_list == NULL) {\n-\t\tRTE_LOG(ERR, EAL, \"No rte_ring tailq found!\\n\");\n-\t\treturn -1;\n-\t}\n-\n-\tmcfg = rte_eal_get_configuration()->mem_config;\n-\n-\t/* create memzones */\n-\tfor (i = 0; i < ivshmem_config->segment_idx && i <= RTE_MAX_MEMZONE; i++) {\n-\n-\t\tseg = &ivshmem_config->segment[i];\n-\n-\t\t/* add memzone */\n-\t\tif (mcfg->memzone_cnt == RTE_MAX_MEMZONE) {\n-\t\t\tRTE_LOG(ERR, EAL, \"No more memory zones available!\\n\");\n-\t\t\treturn -1;\n-\t\t}\n-\n-\t\tidx = mcfg->memzone_cnt;\n-\n-\t\tRTE_LOG(DEBUG, EAL, \"Found memzone: '%s' at %p (len 0x%\" PRIx64 \")\\n\",\n-\t\t\t\tseg->entry.mz.name, seg->entry.mz.addr, seg->entry.mz.len);\n-\n-\t\tmemcpy(&mcfg->memzone[idx], &seg->entry.mz,\n-\t\t\t\tsizeof(struct rte_memzone));\n-\n-\t\t/* find ioremap address */\n-\t\tfor (ms = 0; ms <= RTE_MAX_MEMSEG; ms++) {\n-\t\t\tif (ms == RTE_MAX_MEMSEG) {\n-\t\t\t\tRTE_LOG(ERR, EAL, \"Physical address of segment not found!\\n\");\n-\t\t\t\treturn -1;\n-\t\t\t}\n-\t\t\tif (CONTAINS(mcfg->memseg[ms], mcfg->memzone[idx])) {\n-\t\t\t\toffset = mcfg->memzone[idx].addr_64 -\n-\t\t\t\t\t\t\t\tmcfg->memseg[ms].addr_64;\n-\t\t\t\tmcfg->memzone[idx].ioremap_addr = mcfg->memseg[ms].ioremap_addr +\n-\t\t\t\t\t\toffset;\n-\t\t\t\tbreak;\n-\t\t\t}\n-\t\t}\n-\n-\t\tmcfg->memzone_cnt++;\n-\t}\n-\n-\trte_rwlock_write_lock(RTE_EAL_TAILQ_RWLOCK);\n-\n-\t/* find rings */\n-\tfor (i = 0; i < mcfg->memzone_cnt; i++) {\n-\t\tmz = &mcfg->memzone[i];\n-\n-\t\t/* check if memzone has a ring prefix */\n-\t\tif (strncmp(mz->name, RTE_RING_MZ_PREFIX,\n-\t\t\t\tsizeof(RTE_RING_MZ_PREFIX) - 1) != 0)\n-\t\t\tcontinue;\n-\n-\t\tr = (struct rte_ring*) (mz->addr_64);\n-\n-\t\tte = rte_zmalloc(\"RING_TAILQ_ENTRY\", sizeof(*te), 0);\n-\t\tif (te == NULL) {\n-\t\t\tRTE_LOG(ERR, EAL, \"Cannot allocate ring tailq entry!\\n\");\n-\t\t\treturn -1;\n-\t\t}\n-\n-\t\tte->data = (void *) r;\n-\n-\t\tTAILQ_INSERT_TAIL(ring_list, te, next);\n-\n-\t\tRTE_LOG(DEBUG, EAL, \"Found ring: '%s' at %p\\n\", r->name, mz->addr);\n-\t}\n-\trte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK);\n-\n-#ifdef RTE_LIBRTE_IVSHMEM_DEBUG\n-\trte_memzone_dump(stdout);\n-\trte_ring_list_dump(stdout);\n-#endif\n-\n-\treturn 0;\n-}\n-\n-/* initialize ivshmem structures */\n-int rte_eal_ivshmem_init(void)\n-{\n-\tstruct rte_pci_device * dev;\n-\tstruct rte_pci_resource * res;\n-\tint fd, ret;\n-\tchar path[PATH_MAX];\n-\n-\t/* initialize everything to 0 */\n-\tmemset(path, 0, sizeof(path));\n-\tivshmem_config = NULL;\n-\n-\tpagesz = getpagesize();\n-\n-\tRTE_LOG(DEBUG, EAL, \"Searching for IVSHMEM devices...\\n\");\n-\n-\tif (rte_eal_process_type() == RTE_PROC_SECONDARY) {\n-\n-\t\tif (open_shared_config() < 0) {\n-\t\t\tRTE_LOG(ERR, EAL, \"Could not open IVSHMEM config!\\n\");\n-\t\t\treturn -1;\n-\t\t}\n-\t}\n-\telse {\n-\n-\t\tTAILQ_FOREACH(dev, &pci_device_list, next) {\n-\n-\t\t\tif (is_ivshmem_device(dev)) {\n-\n-\t\t\t\t/* IVSHMEM memory is always on BAR2 */\n-\t\t\t\tres = &dev->mem_resource[2];\n-\n-\t\t\t\t/* if we don't have a BAR2 */\n-\t\t\t\tif (res->len == 0)\n-\t\t\t\t\tcontinue;\n-\n-\t\t\t\t/* construct pci device path */\n-\t\t\t\tsnprintf(path, sizeof(path), IVSHMEM_RESOURCE_PATH,\n-\t\t\t\t\t\tdev->addr.domain, dev->addr.bus, dev->addr.devid,\n-\t\t\t\t\t\tdev->addr.function);\n-\n-\t\t\t\t/* try to find memseg */\n-\t\t\t\tfd = open(path, O_RDWR);\n-\t\t\t\tif (fd < 0) {\n-\t\t\t\t\tRTE_LOG(ERR, EAL, \"Could not open %s\\n\", path);\n-\t\t\t\t\treturn -1;\n-\t\t\t\t}\n-\n-\t\t\t\t/* check if it's a DPDK IVSHMEM device */\n-\t\t\t\tret = has_ivshmem_metadata(fd, res->len);\n-\n-\t\t\t\t/* is DPDK device */\n-\t\t\t\tif (ret == 1) {\n-\n-\t\t\t\t\t/* config file creation is deferred until the first\n-\t\t\t\t\t * DPDK device is found. then, it has to be created\n-\t\t\t\t\t * only once. */\n-\t\t\t\t\tif (ivshmem_config == NULL &&\n-\t\t\t\t\t\t\tcreate_shared_config() < 0) {\n-\t\t\t\t\t\tRTE_LOG(ERR, EAL, \"Could not create IVSHMEM config!\\n\");\n-\t\t\t\t\t\tclose(fd);\n-\t\t\t\t\t\treturn -1;\n-\t\t\t\t\t}\n-\n-\t\t\t\t\tif (read_metadata(path, sizeof(path), fd, res->len) < 0) {\n-\t\t\t\t\t\tRTE_LOG(ERR, EAL, \"Could not read metadata from\"\n-\t\t\t\t\t\t\t\t\" device %02x:%02x.%x!\\n\", dev->addr.bus,\n-\t\t\t\t\t\t\t\tdev->addr.devid, dev->addr.function);\n-\t\t\t\t\t\tclose(fd);\n-\t\t\t\t\t\treturn -1;\n-\t\t\t\t\t}\n-\n-\t\t\t\t\tif (ivshmem_config->pci_devs_idx == RTE_LIBRTE_IVSHMEM_MAX_PCI_DEVS) {\n-\t\t\t\t\t\tRTE_LOG(WARNING, EAL,\n-\t\t\t\t\t\t\t\t\"IVSHMEM PCI device limit exceeded. Increase \"\n-\t\t\t\t\t\t\t\t\"CONFIG_RTE_LIBRTE_IVSHMEM_MAX_PCI_DEVS  in \"\n-\t\t\t\t\t\t\t\t\"your config file.\\n\");\n-\t\t\t\t\t\tbreak;\n-\t\t\t\t\t}\n-\n-\t\t\t\t\tRTE_LOG(INFO, EAL, \"Found IVSHMEM device %02x:%02x.%x\\n\",\n-\t\t\t\t\t\t\tdev->addr.bus, dev->addr.devid, dev->addr.function);\n-\n-\t\t\t\t\tivshmem_config->pci_devs[ivshmem_config->pci_devs_idx].ioremap_addr = res->phys_addr;\n-\t\t\t\t\tsnprintf(ivshmem_config->pci_devs[ivshmem_config->pci_devs_idx].path,\n-\t\t\t\t\t\t\tsizeof(ivshmem_config->pci_devs[ivshmem_config->pci_devs_idx].path),\n-\t\t\t\t\t\t\t\"%s\", path);\n-\n-\t\t\t\t\tivshmem_config->pci_devs_idx++;\n-\t\t\t\t}\n-\t\t\t\t/* failed to read */\n-\t\t\t\telse if (ret < 0) {\n-\t\t\t\t\tRTE_LOG(ERR, EAL, \"Could not read IVSHMEM device: %s\\n\",\n-\t\t\t\t\t\t\tstrerror(errno));\n-\t\t\t\t\tclose(fd);\n-\t\t\t\t\treturn -1;\n-\t\t\t\t}\n-\t\t\t\t/* not a DPDK device */\n-\t\t\t\telse\n-\t\t\t\t\tRTE_LOG(DEBUG, EAL, \"Skipping non-DPDK IVSHMEM device\\n\");\n-\n-\t\t\t\t/* close the BAR fd */\n-\t\t\t\tclose(fd);\n-\t\t\t}\n-\t\t}\n-\t}\n-\n-\t/* ivshmem_config is not NULL only if config was created and/or mapped */\n-\tif (ivshmem_config) {\n-\t\tif (map_all_segments() < 0) {\n-\t\t\tRTE_LOG(ERR, EAL, \"Mapping IVSHMEM segments failed!\\n\");\n-\t\t\treturn -1;\n-\t\t}\n-\t}\n-\telse {\n-\t\tRTE_LOG(DEBUG, EAL, \"No IVSHMEM configuration found! \\n\");\n-\t}\n-\n-\treturn 0;\n-}\n-\n-#endif\ndiff --git a/lib/librte_eal/linuxapp/eal/eal_memory.c b/lib/librte_eal/linuxapp/eal/eal_memory.c\nindex 41e0a92..992a1b1 100644\n--- a/lib/librte_eal/linuxapp/eal/eal_memory.c\n+++ b/lib/librte_eal/linuxapp/eal/eal_memory.c\n@@ -1436,15 +1436,8 @@ rte_eal_hugepage_init(void)\n \tfree(tmp_hp);\n \ttmp_hp = NULL;\n \n-\t/* find earliest free memseg - this is needed because in case of IVSHMEM,\n-\t * segments might have already been initialized */\n-\tfor (j = 0; j < RTE_MAX_MEMSEG; j++)\n-\t\tif (mcfg->memseg[j].addr == NULL) {\n-\t\t\t/* move to previous segment and exit loop */\n-\t\t\tj--;\n-\t\t\tbreak;\n-\t\t}\n-\n+\t/* first memseg index shall be 0 after incrementing it below */\n+\tj = -1;\n \tfor (i = 0; i < nr_hugefiles; i++) {\n \t\tnew_memseg = 0;\n \n@@ -1597,15 +1590,6 @@ rte_eal_hugepage_attach(void)\n \t\tif (mcfg->memseg[s].len == 0)\n \t\t\tbreak;\n \n-#ifdef RTE_LIBRTE_IVSHMEM\n-\t\t/*\n-\t\t * if segment has ioremap address set, it's an IVSHMEM segment and\n-\t\t * doesn't need mapping as it was already mapped earlier\n-\t\t */\n-\t\tif (mcfg->memseg[s].ioremap_addr != 0)\n-\t\t\tcontinue;\n-#endif\n-\n \t\t/*\n \t\t * fdzero is mmapped to get a contiguous block of virtual\n \t\t * addresses of the appropriate memseg size.\n@@ -1644,16 +1628,6 @@ rte_eal_hugepage_attach(void)\n \t\tvoid *addr, *base_addr;\n \t\tuintptr_t offset = 0;\n \t\tsize_t mapping_size;\n-#ifdef RTE_LIBRTE_IVSHMEM\n-\t\t/*\n-\t\t * if segment has ioremap address set, it's an IVSHMEM segment and\n-\t\t * doesn't need mapping as it was already mapped earlier\n-\t\t */\n-\t\tif (mcfg->memseg[s].ioremap_addr != 0) {\n-\t\t\ts++;\n-\t\t\tcontinue;\n-\t\t}\n-#endif\n \t\t/*\n \t\t * free previously mapped memory so we can map the\n \t\t * hugepages into the space\ndiff --git a/lib/librte_ivshmem/Makefile b/lib/librte_ivshmem/Makefile\ndeleted file mode 100644\nindex c099438..0000000\n--- a/lib/librte_ivshmem/Makefile\n+++ /dev/null\n@@ -1,54 +0,0 @@\n-#   BSD LICENSE\n-#\n-#   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.\n-#   All rights reserved.\n-#\n-#   Redistribution and use in source and binary forms, with or without\n-#   modification, are permitted provided that the following conditions\n-#   are met:\n-#\n-#     * Redistributions of source code must retain the above copyright\n-#       notice, this list of conditions and the following disclaimer.\n-#     * Redistributions in binary form must reproduce the above copyright\n-#       notice, this list of conditions and the following disclaimer in\n-#       the documentation and/or other materials provided with the\n-#       distribution.\n-#     * Neither the name of Intel Corporation nor the names of its\n-#       contributors may be used to endorse or promote products derived\n-#       from this software without specific prior written permission.\n-#\n-#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n-#   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n-#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n-#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n-#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n-#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n-#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n-#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n-#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n-#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n-#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n-\n-include $(RTE_SDK)/mk/rte.vars.mk\n-\n-# library name\n-LIB = librte_ivshmem.a\n-\n-CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR) -O3\n-\n-EXPORT_MAP := rte_ivshmem_version.map\n-\n-LIBABIVER := 1\n-\n-# all source are stored in SRCS-y\n-SRCS-$(CONFIG_RTE_LIBRTE_IVSHMEM) := rte_ivshmem.c\n-\n-# install includes\n-SYMLINK-$(CONFIG_RTE_LIBRTE_IVSHMEM)-include := rte_ivshmem.h\n-\n-# this lib needs EAL, ring and mempool\n-DEPDIRS-$(CONFIG_RTE_LIBRTE_IVSHMEM) += lib/librte_eal\n-DEPDIRS-$(CONFIG_RTE_LIBRTE_IVSHMEM) += lib/librte_ring\n-DEPDIRS-$(CONFIG_RTE_LIBRTE_IVSHMEM) += lib/librte_mempool\n-\n-include $(RTE_SDK)/mk/rte.lib.mk\ndiff --git a/lib/librte_ivshmem/rte_ivshmem.c b/lib/librte_ivshmem/rte_ivshmem.c\ndeleted file mode 100644\nindex c26edb6..0000000\n--- a/lib/librte_ivshmem/rte_ivshmem.c\n+++ /dev/null\n@@ -1,919 +0,0 @@\n-/*-\n- *   BSD LICENSE\n- *\n- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.\n- *   All rights reserved.\n- *\n- *   Redistribution and use in source and binary forms, with or without\n- *   modification, are permitted provided that the following conditions\n- *   are met:\n- *\n- *     * Redistributions of source code must retain the above copyright\n- *       notice, this list of conditions and the following disclaimer.\n- *     * Redistributions in binary form must reproduce the above copyright\n- *       notice, this list of conditions and the following disclaimer in\n- *       the documentation and/or other materials provided with the\n- *       distribution.\n- *     * Neither the name of Intel Corporation nor the names of its\n- *       contributors may be used to endorse or promote products derived\n- *       from this software without specific prior written permission.\n- *\n- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n- *   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n- */\n-#include <fcntl.h>\n-#include <limits.h>\n-#include <unistd.h>\n-#include <sys/mman.h>\n-#include <string.h>\n-#include <stdio.h>\n-\n-#include <rte_eal_memconfig.h>\n-#include <rte_memory.h>\n-#include <rte_ivshmem.h>\n-#include <rte_string_fns.h>\n-#include <rte_common.h>\n-#include <rte_log.h>\n-#include <rte_debug.h>\n-#include <rte_spinlock.h>\n-#include <rte_common.h>\n-#include <rte_malloc.h>\n-\n-#include \"rte_ivshmem.h\"\n-\n-#define IVSHMEM_CONFIG_FILE_FMT \"/var/run/.dpdk_ivshmem_metadata_%s\"\n-#define IVSHMEM_QEMU_CMD_LINE_HEADER_FMT \"-device ivshmem,size=%\" PRIu64 \"M,shm=fd%s\"\n-#define IVSHMEM_QEMU_CMD_FD_FMT \":%s:0x%\" PRIx64 \":0x%\" PRIx64\n-#define IVSHMEM_QEMU_CMDLINE_BUFSIZE 1024\n-#define IVSHMEM_MAX_PAGES (1 << 12)\n-#define adjacent(x,y) (((x).phys_addr+(x).len)==(y).phys_addr)\n-#define METADATA_SIZE_ALIGNED \\\n-\t(RTE_ALIGN_CEIL(sizeof(struct rte_ivshmem_metadata),pagesz))\n-\n-#define GET_PAGEMAP_ADDR(in,addr,dlm,err)    \\\n-{                                      \\\n-\tchar *end;                         \\\n-\terrno = 0;                         \\\n-\taddr = strtoull((in), &end, 16);   \\\n-\tif (errno != 0 || *end != (dlm)) { \\\n-\t\tRTE_LOG(ERR, EAL, err);        \\\n-\t\tgoto error;                    \\\n-\t}                                  \\\n-\t(in) = end + 1;                    \\\n-}\n-\n-static int pagesz;\n-\n-struct memseg_cache_entry {\n-\tchar filepath[PATH_MAX];\n-\tuint64_t offset;\n-\tuint64_t len;\n-};\n-\n-struct ivshmem_config {\n-\tstruct rte_ivshmem_metadata * metadata;\n-\tstruct memseg_cache_entry memseg_cache[IVSHMEM_MAX_PAGES];\n-\t\t/**< account for multiple files per segment case */\n-\tstruct flock lock;\n-\trte_spinlock_t sl;\n-};\n-\n-static struct ivshmem_config\n-ivshmem_global_config[RTE_LIBRTE_IVSHMEM_MAX_METADATA_FILES];\n-\n-static rte_spinlock_t global_cfg_sl;\n-\n-static struct ivshmem_config *\n-get_config_by_name(const char * name)\n-{\n-\tstruct rte_ivshmem_metadata * config;\n-\tunsigned i;\n-\n-\tfor (i = 0; i < RTE_DIM(ivshmem_global_config); i++) {\n-\t\tconfig = ivshmem_global_config[i].metadata;\n-\t\tif (config == NULL)\n-\t\t\treturn NULL;\n-\t\tif (strncmp(name, config->name, IVSHMEM_NAME_LEN) == 0)\n-\t\t\treturn &ivshmem_global_config[i];\n-\t}\n-\n-\treturn NULL;\n-}\n-\n-static int\n-overlap(const struct rte_memzone * s1, const struct rte_memzone * s2)\n-{\n-\tuint64_t start1, end1, start2, end2;\n-\n-\tstart1 = s1->addr_64;\n-\tend1 = s1->addr_64 + s1->len;\n-\tstart2 = s2->addr_64;\n-\tend2 = s2->addr_64 + s2->len;\n-\n-\tif (start1 >= start2 && start1 < end2)\n-\t\treturn 1;\n-\tif (start2 >= start1 && start2 < end1)\n-\t\treturn 1;\n-\n-\treturn 0;\n-}\n-\n-static struct rte_memzone *\n-get_memzone_by_addr(const void * addr)\n-{\n-\tstruct rte_memzone * tmp, * mz;\n-\tstruct rte_mem_config * mcfg;\n-\tint i;\n-\n-\tmcfg = rte_eal_get_configuration()->mem_config;\n-\tmz = NULL;\n-\n-\t/* find memzone for the ring */\n-\tfor (i = 0; i < RTE_MAX_MEMZONE; i++) {\n-\t\ttmp = &mcfg->memzone[i];\n-\n-\t\tif (tmp->addr_64 == (uint64_t) addr) {\n-\t\t\tmz = tmp;\n-\t\t\tbreak;\n-\t\t}\n-\t}\n-\n-\treturn mz;\n-}\n-\n-static int\n-entry_compare(const void * a, const void * b)\n-{\n-\tconst struct rte_ivshmem_metadata_entry * e1 =\n-\t\t\t(const struct rte_ivshmem_metadata_entry*) a;\n-\tconst struct rte_ivshmem_metadata_entry * e2 =\n-\t\t\t(const struct rte_ivshmem_metadata_entry*) b;\n-\n-\t/* move unallocated zones to the end */\n-\tif (e1->mz.addr == NULL && e2->mz.addr == NULL)\n-\t\treturn 0;\n-\tif (e1->mz.addr == 0)\n-\t\treturn 1;\n-\tif (e2->mz.addr == 0)\n-\t\treturn -1;\n-\n-\treturn e1->mz.phys_addr > e2->mz.phys_addr;\n-}\n-\n-/* fills hugepage cache entry for a given start virt_addr */\n-static int\n-get_hugefile_by_virt_addr(uint64_t virt_addr, struct memseg_cache_entry * e)\n-{\n-\tuint64_t start_addr, end_addr;\n-\tchar *start,*path_end;\n-\tchar buf[PATH_MAX*2];\n-\tFILE *f;\n-\n-\tstart = NULL;\n-\tpath_end = NULL;\n-\tstart_addr = 0;\n-\n-\tmemset(e->filepath, 0, sizeof(e->filepath));\n-\n-\t/* open /proc/self/maps */\n-\tf = fopen(\"/proc/self/maps\", \"r\");\n-\tif (f == NULL) {\n-\t\tRTE_LOG(ERR, EAL, \"cannot open /proc/self/maps!\\n\");\n-\t\treturn -1;\n-\t}\n-\n-\t/* parse maps */\n-\twhile (fgets(buf, sizeof(buf), f) != NULL) {\n-\n-\t\t/* get endptr to end of start addr */\n-\t\tstart = buf;\n-\n-\t\tGET_PAGEMAP_ADDR(start,start_addr,'-',\n-\t\t\t\t\"Cannot find start address in maps!\\n\");\n-\n-\t\t/* if start address is bigger than our address, skip */\n-\t\tif (start_addr > virt_addr)\n-\t\t\tcontinue;\n-\n-\t\tGET_PAGEMAP_ADDR(start,end_addr,' ',\n-\t\t\t\t\"Cannot find end address in maps!\\n\");\n-\n-\t\t/* if end address is less than our address, skip */\n-\t\tif (end_addr <= virt_addr)\n-\t\t\tcontinue;\n-\n-\t\t/* find where the path starts */\n-\t\tstart = strstr(start, \"/\");\n-\n-\t\tif (start == NULL)\n-\t\t\tcontinue;\n-\n-\t\t/* at this point, we know that this is our map.\n-\t\t * now let's find the file */\n-\t\tpath_end = strstr(start, \"\\n\");\n-\t\tbreak;\n-\t}\n-\n-\tif (path_end == NULL) {\n-\t\tRTE_LOG(ERR, EAL, \"Hugefile path not found!\\n\");\n-\t\tgoto error;\n-\t}\n-\n-\t/* calculate offset and copy the file path */\n-\tsnprintf(e->filepath, RTE_PTR_DIFF(path_end, start) + 1, \"%s\", start);\n-\n-\te->offset = virt_addr - start_addr;\n-\n-\tfclose(f);\n-\n-\treturn 0;\n-error:\n-\tfclose(f);\n-\treturn -1;\n-}\n-\n-/*\n- * This is a complex function. What it does is the following:\n- *  1. Goes through metadata and gets list of hugepages involved\n- *  2. Sorts the hugepages by size (1G first)\n- *  3. Goes through metadata again and writes correct offsets\n- *  4. Goes through pages and finds out their filenames, offsets etc.\n- */\n-static int\n-build_config(struct rte_ivshmem_metadata * metadata)\n-{\n-\tstruct rte_ivshmem_metadata_entry * e_local;\n-\tstruct memseg_cache_entry * ms_local;\n-\tstruct rte_memseg pages[IVSHMEM_MAX_PAGES];\n-\tstruct rte_ivshmem_metadata_entry *entry;\n-\tstruct memseg_cache_entry * c_entry, * prev_entry;\n-\tstruct ivshmem_config * config;\n-\tunsigned i, j, mz_iter, ms_iter;\n-\tuint64_t biggest_len;\n-\tint biggest_idx;\n-\n-\t/* return error if we try to use an unknown config file */\n-\tconfig = get_config_by_name(metadata->name);\n-\tif (config == NULL) {\n-\t\tRTE_LOG(ERR, EAL, \"Cannot find IVSHMEM config %s!\\n\", metadata->name);\n-\t\tgoto fail_e;\n-\t}\n-\n-\tmemset(pages, 0, sizeof(pages));\n-\n-\te_local = malloc(sizeof(config->metadata->entry));\n-\tif (e_local == NULL)\n-\t\tgoto fail_e;\n-\tms_local = malloc(sizeof(config->memseg_cache));\n-\tif (ms_local == NULL)\n-\t\tgoto fail_ms;\n-\n-\n-\t/* make local copies before doing anything */\n-\tmemcpy(e_local, config->metadata->entry, sizeof(config->metadata->entry));\n-\tmemcpy(ms_local, config->memseg_cache, sizeof(config->memseg_cache));\n-\n-\tqsort(e_local, RTE_DIM(config->metadata->entry), sizeof(struct rte_ivshmem_metadata_entry),\n-\t\t\tentry_compare);\n-\n-\t/* first pass - collect all huge pages */\n-\tfor (mz_iter = 0; mz_iter < RTE_DIM(config->metadata->entry); mz_iter++) {\n-\n-\t\tentry = &e_local[mz_iter];\n-\n-\t\tuint64_t start_addr = RTE_ALIGN_FLOOR(entry->mz.addr_64,\n-\t\t\t\tentry->mz.hugepage_sz);\n-\t\tuint64_t offset = entry->mz.addr_64 - start_addr;\n-\t\tuint64_t len = RTE_ALIGN_CEIL(entry->mz.len + offset,\n-\t\t\t\tentry->mz.hugepage_sz);\n-\n-\t\tif (entry->mz.addr_64 == 0 || start_addr == 0 || len == 0)\n-\t\t\tcontinue;\n-\n-\t\tint start_page;\n-\n-\t\t/* find first unused page - mz are phys_addr sorted so we don't have to\n-\t\t * look out for holes */\n-\t\tfor (i = 0; i < RTE_DIM(pages); i++) {\n-\n-\t\t\t/* skip if we already have this page */\n-\t\t\tif (pages[i].addr_64 == start_addr) {\n-\t\t\t\tstart_addr += entry->mz.hugepage_sz;\n-\t\t\t\tlen -= entry->mz.hugepage_sz;\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\t/* we found a new page */\n-\t\t\telse if (pages[i].addr_64 == 0) {\n-\t\t\t\tstart_page = i;\n-\t\t\t\tbreak;\n-\t\t\t}\n-\t\t}\n-\t\tif (i == RTE_DIM(pages)) {\n-\t\t\tRTE_LOG(ERR, EAL, \"Cannot find unused page!\\n\");\n-\t\t\tgoto fail;\n-\t\t}\n-\n-\t\t/* populate however many pages the memzone has */\n-\t\tfor (i = start_page; i < RTE_DIM(pages) && len != 0; i++) {\n-\n-\t\t\tpages[i].addr_64 = start_addr;\n-\t\t\tpages[i].len = entry->mz.hugepage_sz;\n-\t\t\tstart_addr += entry->mz.hugepage_sz;\n-\t\t\tlen -= entry->mz.hugepage_sz;\n-\t\t}\n-\t\t/* if there's still length left */\n-\t\tif (len != 0) {\n-\t\t\tRTE_LOG(ERR, EAL, \"Not enough space for pages!\\n\");\n-\t\t\tgoto fail;\n-\t\t}\n-\t}\n-\n-\t/* second pass - sort pages by size */\n-\tfor (i = 0; i < RTE_DIM(pages); i++) {\n-\n-\t\tif (pages[i].addr == NULL)\n-\t\t\tbreak;\n-\n-\t\tbiggest_len = 0;\n-\t\tbiggest_idx = -1;\n-\n-\t\t/*\n-\t\t * browse all entries starting at 'i', and find the\n-\t\t * entry with the smallest addr\n-\t\t */\n-\t\tfor (j=i; j< RTE_DIM(pages); j++) {\n-\t\t\tif (pages[j].addr == NULL)\n-\t\t\t\t\tbreak;\n-\t\t\tif (biggest_len == 0 ||\n-\t\t\t\tpages[j].len > biggest_len) {\n-\t\t\t\tbiggest_len = pages[j].len;\n-\t\t\t\tbiggest_idx = j;\n-\t\t\t}\n-\t\t}\n-\n-\t\t/* should not happen */\n-\t\tif (biggest_idx == -1) {\n-\t\t\tRTE_LOG(ERR, EAL, \"Error sorting by size!\\n\");\n-\t\t\tgoto fail;\n-\t\t}\n-\t\tif (i != (unsigned) biggest_idx) {\n-\t\t\tstruct rte_memseg tmp;\n-\n-\t\t\tmemcpy(&tmp, &pages[biggest_idx], sizeof(struct rte_memseg));\n-\n-\t\t\t/* we don't want to break contiguousness, so instead of just\n-\t\t\t * swapping segments, we move all the preceding segments to the\n-\t\t\t * right and then put the old segment @ biggest_idx in place of\n-\t\t\t * segment @ i */\n-\t\t\tfor (j = biggest_idx - 1; j >= i; j--) {\n-\t\t\t\tmemcpy(&pages[j+1], &pages[j], sizeof(struct rte_memseg));\n-\t\t\t\tmemset(&pages[j], 0, sizeof(struct rte_memseg));\n-\t\t\t\tif (j == 0)\n-\t\t\t\t\tbreak;\n-\t\t\t}\n-\n-\t\t\t/* put old biggest segment to its new place */\n-\t\t\tmemcpy(&pages[i], &tmp, sizeof(struct rte_memseg));\n-\t\t}\n-\t}\n-\n-\t/* third pass - write correct offsets */\n-\tfor (mz_iter = 0; mz_iter < RTE_DIM(config->metadata->entry); mz_iter++) {\n-\n-\t\tuint64_t offset = 0;\n-\n-\t\tentry = &e_local[mz_iter];\n-\n-\t\tif (entry->mz.addr_64 == 0)\n-\t\t\tbreak;\n-\n-\t\t/* find page for current memzone */\n-\t\tfor (i = 0; i < RTE_DIM(pages); i++) {\n-\t\t\t/* we found our page */\n-\t\t\tif (entry->mz.addr_64 >= pages[i].addr_64 &&\n-\t\t\t\t\tentry->mz.addr_64 < pages[i].addr_64 + pages[i].len) {\n-\t\t\t\tentry->offset = (entry->mz.addr_64 - pages[i].addr_64) +\n-\t\t\t\t\t\toffset;\n-\t\t\t\tbreak;\n-\t\t\t}\n-\t\t\toffset += pages[i].len;\n-\t\t}\n-\t\tif (i == RTE_DIM(pages)) {\n-\t\t\tRTE_LOG(ERR, EAL, \"Page not found!\\n\");\n-\t\t\tgoto fail;\n-\t\t}\n-\t}\n-\n-\tms_iter = 0;\n-\tprev_entry = NULL;\n-\n-\t/* fourth pass - create proper memseg cache */\n-\tfor (i = 0; i < RTE_DIM(pages) &&\n-\t\t\tms_iter <= RTE_DIM(config->memseg_cache); i++) {\n-\t\tif (pages[i].addr_64 == 0)\n-\t\t\tbreak;\n-\n-\n-\t\tif (ms_iter == RTE_DIM(pages)) {\n-\t\t\tRTE_LOG(ERR, EAL, \"The universe has collapsed!\\n\");\n-\t\t\tgoto fail;\n-\t\t}\n-\n-\t\tc_entry = &ms_local[ms_iter];\n-\t\tc_entry->len = pages[i].len;\n-\n-\t\tif (get_hugefile_by_virt_addr(pages[i].addr_64, c_entry) < 0)\n-\t\t\tgoto fail;\n-\n-\t\t/* if previous entry has the same filename and is contiguous,\n-\t\t * clear current entry and increase previous entry's length\n-\t\t */\n-\t\tif (prev_entry != NULL &&\n-\t\t\t\tstrncmp(c_entry->filepath, prev_entry->filepath,\n-\t\t\t\tsizeof(c_entry->filepath)) == 0 &&\n-\t\t\t\tprev_entry->offset + prev_entry->len == c_entry->offset) {\n-\t\t\tprev_entry->len += pages[i].len;\n-\t\t\tmemset(c_entry, 0, sizeof(struct memseg_cache_entry));\n-\t\t}\n-\t\telse {\n-\t\t\tprev_entry = c_entry;\n-\t\t\tms_iter++;\n-\t\t}\n-\t}\n-\n-\t/* update current configuration with new valid data */\n-\tmemcpy(config->metadata->entry, e_local, sizeof(config->metadata->entry));\n-\tmemcpy(config->memseg_cache, ms_local, sizeof(config->memseg_cache));\n-\n-\tfree(ms_local);\n-\tfree(e_local);\n-\n-\treturn 0;\n-fail:\n-\tfree(ms_local);\n-fail_ms:\n-\tfree(e_local);\n-fail_e:\n-\treturn -1;\n-}\n-\n-static int\n-add_memzone_to_metadata(const struct rte_memzone * mz,\n-\t\tstruct ivshmem_config * config)\n-{\n-\tstruct rte_ivshmem_metadata_entry * entry;\n-\tunsigned i, idx;\n-\tstruct rte_mem_config *mcfg;\n-\n-\tif (mz->len == 0) {\n-\t\tRTE_LOG(ERR, EAL, \"Trying to add an empty memzone\\n\");\n-\t\treturn -1;\n-\t}\n-\n-\trte_spinlock_lock(&config->sl);\n-\n-\tmcfg = rte_eal_get_configuration()->mem_config;\n-\n-\t/* it prevents the memzone being freed while we add it to the metadata */\n-\trte_rwlock_write_lock(&mcfg->mlock);\n-\n-\t/* find free slot in this config */\n-\tfor (i = 0; i < RTE_DIM(config->metadata->entry); i++) {\n-\t\tentry = &config->metadata->entry[i];\n-\n-\t\tif (&entry->mz.addr_64 != 0 && overlap(mz, &entry->mz)) {\n-\t\t\tRTE_LOG(ERR, EAL, \"Overlapping memzones!\\n\");\n-\t\t\tgoto fail;\n-\t\t}\n-\n-\t\t/* if addr is zero, the memzone is probably free */\n-\t\tif (entry->mz.addr_64 == 0) {\n-\t\t\tRTE_LOG(DEBUG, EAL, \"Adding memzone '%s' at %p to metadata %s\\n\",\n-\t\t\t\t\tmz->name, mz->addr, config->metadata->name);\n-\t\t\tmemcpy(&entry->mz, mz, sizeof(struct rte_memzone));\n-\n-\t\t\t/* run config file parser */\n-\t\t\tif (build_config(config->metadata) < 0)\n-\t\t\t\tgoto fail;\n-\n-\t\t\tbreak;\n-\t\t}\n-\t}\n-\n-\t/* if we reached the maximum, that means we have no place in config */\n-\tif (i == RTE_DIM(config->metadata->entry)) {\n-\t\tRTE_LOG(ERR, EAL, \"No space left in IVSHMEM metadata %s!\\n\",\n-\t\t\t\tconfig->metadata->name);\n-\t\tgoto fail;\n-\t}\n-\n-\tidx = ((uintptr_t)mz - (uintptr_t)mcfg->memzone);\n-\tidx = idx / sizeof(struct rte_memzone);\n-\n-\t/* mark the memzone not freeable */\n-\tmcfg->memzone[idx].ioremap_addr = mz->phys_addr;\n-\n-\trte_rwlock_write_unlock(&mcfg->mlock);\n-\trte_spinlock_unlock(&config->sl);\n-\treturn 0;\n-fail:\n-\trte_rwlock_write_unlock(&mcfg->mlock);\n-\trte_spinlock_unlock(&config->sl);\n-\treturn -1;\n-}\n-\n-static int\n-add_ring_to_metadata(const struct rte_ring * r,\n-\t\tstruct ivshmem_config * config)\n-{\n-\tstruct rte_memzone * mz;\n-\n-\tmz = get_memzone_by_addr(r);\n-\n-\tif (!mz) {\n-\t\tRTE_LOG(ERR, EAL, \"Cannot find memzone for ring!\\n\");\n-\t\treturn -1;\n-\t}\n-\n-\treturn add_memzone_to_metadata(mz, config);\n-}\n-\n-static int\n-add_mempool_memzone_to_metadata(const void *addr,\n-\t\tstruct ivshmem_config *config)\n-{\n-\tstruct rte_memzone *mz;\n-\n-\tmz = get_memzone_by_addr(addr);\n-\n-\tif (!mz) {\n-\t\tRTE_LOG(ERR, EAL, \"Cannot find memzone for mempool!\\n\");\n-\t\treturn -1;\n-\t}\n-\n-\treturn add_memzone_to_metadata(mz, config);\n-}\n-\n-static int\n-add_mempool_to_metadata(const struct rte_mempool *mp,\n-\t\tstruct ivshmem_config *config)\n-{\n-\tstruct rte_mempool_memhdr *memhdr;\n-\tint ret;\n-\n-\tret = add_mempool_memzone_to_metadata(mp, config);\n-\tif (ret < 0)\n-\t\treturn -1;\n-\n-\tSTAILQ_FOREACH(memhdr, &mp->mem_list, next) {\n-\t\tret = add_mempool_memzone_to_metadata(memhdr->addr, config);\n-\t\tif (ret < 0)\n-\t\t\treturn -1;\n-\t}\n-\n-\t/* mempool consists of memzone and ring */\n-\treturn add_ring_to_metadata(mp->pool_data, config);\n-}\n-\n-int\n-rte_ivshmem_metadata_add_ring(const struct rte_ring * r, const char * name)\n-{\n-\tstruct ivshmem_config * config;\n-\n-\tif (name == NULL || r == NULL)\n-\t\treturn -1;\n-\n-\tconfig = get_config_by_name(name);\n-\n-\tif (config == NULL) {\n-\t\tRTE_LOG(ERR, EAL, \"Cannot find IVSHMEM config %s!\\n\", name);\n-\t\treturn -1;\n-\t}\n-\n-\treturn add_ring_to_metadata(r, config);\n-}\n-\n-int\n-rte_ivshmem_metadata_add_memzone(const struct rte_memzone * mz, const char * name)\n-{\n-\tstruct ivshmem_config * config;\n-\n-\tif (name == NULL || mz == NULL)\n-\t\treturn -1;\n-\n-\tconfig = get_config_by_name(name);\n-\n-\tif (config == NULL) {\n-\t\tRTE_LOG(ERR, EAL, \"Cannot find IVSHMEM config %s!\\n\", name);\n-\t\treturn -1;\n-\t}\n-\n-\treturn add_memzone_to_metadata(mz, config);\n-}\n-\n-int\n-rte_ivshmem_metadata_add_mempool(const struct rte_mempool * mp, const char * name)\n-{\n-\tstruct ivshmem_config * config;\n-\n-\tif (name == NULL || mp == NULL)\n-\t\treturn -1;\n-\n-\tconfig = get_config_by_name(name);\n-\n-\tif (config == NULL) {\n-\t\tRTE_LOG(ERR, EAL, \"Cannot find IVSHMEM config %s!\\n\", name);\n-\t\treturn -1;\n-\t}\n-\n-\treturn add_mempool_to_metadata(mp, config);\n-}\n-\n-static inline void\n-ivshmem_config_path(char *buffer, size_t bufflen, const char *name)\n-{\n-\tsnprintf(buffer, bufflen, IVSHMEM_CONFIG_FILE_FMT, name);\n-}\n-\n-\n-\n-static inline\n-void *ivshmem_metadata_create(const char *name, size_t size,\n-\t\tstruct flock *lock)\n-{\n-\tint retval, fd;\n-\tvoid *metadata_addr;\n-\tchar pathname[PATH_MAX];\n-\n-\tivshmem_config_path(pathname, sizeof(pathname), name);\n-\n-\tfd = open(pathname, O_RDWR | O_CREAT, 0660);\n-\tif (fd < 0) {\n-\t\tRTE_LOG(ERR, EAL, \"Cannot open '%s'\\n\", pathname);\n-\t\treturn NULL;\n-\t}\n-\n-\tsize = METADATA_SIZE_ALIGNED;\n-\n-\tretval = fcntl(fd, F_SETLK, lock);\n-\tif (retval < 0){\n-\t\tclose(fd);\n-\t\tRTE_LOG(ERR, EAL, \"Cannot create lock on '%s'. Is another \"\n-\t\t\t\t\"process using it?\\n\", pathname);\n-\t\treturn NULL;\n-\t}\n-\n-\tretval = ftruncate(fd, size);\n-\tif (retval < 0){\n-\t\tclose(fd);\n-\t\tRTE_LOG(ERR, EAL, \"Cannot resize '%s'\\n\", pathname);\n-\t\treturn NULL;\n-\t}\n-\n-\tmetadata_addr = mmap(NULL, size,\n-\t\t\t\tPROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);\n-\n-\tif (metadata_addr == MAP_FAILED){\n-\t\tRTE_LOG(ERR, EAL, \"Cannot mmap memory for '%s'\\n\", pathname);\n-\n-\t\t/* we don't care if we can't unlock */\n-\t\tfcntl(fd, F_UNLCK, lock);\n-\t\tclose(fd);\n-\n-\t\treturn NULL;\n-\t}\n-\n-\treturn metadata_addr;\n-}\n-\n-int rte_ivshmem_metadata_create(const char *name)\n-{\n-\tstruct ivshmem_config * ivshmem_config;\n-\tunsigned index;\n-\n-\tif (pagesz == 0)\n-\t\tpagesz = getpagesize();\n-\n-\tif (name == NULL)\n-\t\treturn -1;\n-\n-\trte_spinlock_lock(&global_cfg_sl);\n-\n-\tfor (index = 0; index < RTE_DIM(ivshmem_global_config); index++) {\n-\t\tif (ivshmem_global_config[index].metadata == NULL) {\n-\t\t\tivshmem_config = &ivshmem_global_config[index];\n-\t\t\tbreak;\n-\t\t}\n-\t}\n-\n-\tif (index == RTE_DIM(ivshmem_global_config)) {\n-\t\tRTE_LOG(ERR, EAL, \"Cannot create more ivshmem config files. \"\n-\t\t\"Maximum has been reached\\n\");\n-\t\trte_spinlock_unlock(&global_cfg_sl);\n-\t\treturn -1;\n-\t}\n-\n-\tivshmem_config->lock.l_type = F_WRLCK;\n-\tivshmem_config->lock.l_whence = SEEK_SET;\n-\n-\tivshmem_config->lock.l_start = 0;\n-\tivshmem_config->lock.l_len = METADATA_SIZE_ALIGNED;\n-\n-\tivshmem_global_config[index].metadata = ((struct rte_ivshmem_metadata *)\n-\t\t\tivshmem_metadata_create(\n-\t\t\t\t\tname,\n-\t\t\t\t\tsizeof(struct rte_ivshmem_metadata),\n-\t\t\t\t\t&ivshmem_config->lock));\n-\n-\tif (ivshmem_global_config[index].metadata == NULL) {\n-\t\trte_spinlock_unlock(&global_cfg_sl);\n-\t\treturn -1;\n-\t}\n-\n-\t/* Metadata setup */\n-\tmemset(ivshmem_config->metadata, 0, sizeof(struct rte_ivshmem_metadata));\n-\tivshmem_config->metadata->magic_number = IVSHMEM_MAGIC;\n-\tsnprintf(ivshmem_config->metadata->name,\n-\t\t\tsizeof(ivshmem_config->metadata->name), \"%s\", name);\n-\n-\trte_spinlock_unlock(&global_cfg_sl);\n-\n-\treturn 0;\n-}\n-\n-int\n-rte_ivshmem_metadata_cmdline_generate(char *buffer, unsigned size, const char *name)\n-{\n-\tconst struct memseg_cache_entry * ms_cache, *entry;\n-\tstruct ivshmem_config * config;\n-\tchar cmdline[IVSHMEM_QEMU_CMDLINE_BUFSIZE], *cmdline_ptr;\n-\tchar cfg_file_path[PATH_MAX];\n-\tunsigned remaining_len, tmplen, iter;\n-\tuint64_t shared_mem_size, zero_size, total_size;\n-\n-\tif (buffer == NULL || name == NULL)\n-\t\treturn -1;\n-\n-\tconfig = get_config_by_name(name);\n-\n-\tif (config == NULL) {\n-\t\tRTE_LOG(ERR, EAL, \"Config %s not found!\\n\", name);\n-\t\treturn -1;\n-\t}\n-\n-\trte_spinlock_lock(&config->sl);\n-\n-\t/* prepare metadata file path */\n-\tsnprintf(cfg_file_path, sizeof(cfg_file_path), IVSHMEM_CONFIG_FILE_FMT,\n-\t\t\tconfig->metadata->name);\n-\n-\tms_cache = config->memseg_cache;\n-\n-\tcmdline_ptr = cmdline;\n-\tremaining_len = sizeof(cmdline);\n-\n-\tshared_mem_size = 0;\n-\titer = 0;\n-\n-\twhile ((ms_cache[iter].len != 0) && (iter < RTE_DIM(config->metadata->entry))) {\n-\n-\t\tentry = &ms_cache[iter];\n-\n-\t\t/* Offset and sizes within the current pathname */\n-\t\ttmplen = snprintf(cmdline_ptr, remaining_len, IVSHMEM_QEMU_CMD_FD_FMT,\n-\t\t\t\tentry->filepath, entry->offset, entry->len);\n-\n-\t\tshared_mem_size += entry->len;\n-\n-\t\tcmdline_ptr = RTE_PTR_ADD(cmdline_ptr, tmplen);\n-\t\tremaining_len -= tmplen;\n-\n-\t\tif (remaining_len == 0) {\n-\t\t\tRTE_LOG(ERR, EAL, \"Command line too long!\\n\");\n-\t\t\trte_spinlock_unlock(&config->sl);\n-\t\t\treturn -1;\n-\t\t}\n-\n-\t\titer++;\n-\t}\n-\n-\ttotal_size = rte_align64pow2(shared_mem_size + METADATA_SIZE_ALIGNED);\n-\tzero_size = total_size - shared_mem_size - METADATA_SIZE_ALIGNED;\n-\n-\t/* add /dev/zero to command-line to fill the space */\n-\ttmplen = snprintf(cmdline_ptr, remaining_len, IVSHMEM_QEMU_CMD_FD_FMT,\n-\t\t\t\"/dev/zero\",\n-\t\t\t(uint64_t)0x0,\n-\t\t\tzero_size);\n-\n-\tcmdline_ptr = RTE_PTR_ADD(cmdline_ptr, tmplen);\n-\tremaining_len -= tmplen;\n-\n-\tif (remaining_len == 0) {\n-\t\tRTE_LOG(ERR, EAL, \"Command line too long!\\n\");\n-\t\trte_spinlock_unlock(&config->sl);\n-\t\treturn -1;\n-\t}\n-\n-\t/* add metadata file to the end of command-line */\n-\ttmplen = snprintf(cmdline_ptr, remaining_len, IVSHMEM_QEMU_CMD_FD_FMT,\n-\t\t\tcfg_file_path,\n-\t\t\t(uint64_t)0x0,\n-\t\t\tMETADATA_SIZE_ALIGNED);\n-\n-\tcmdline_ptr = RTE_PTR_ADD(cmdline_ptr, tmplen);\n-\tremaining_len -= tmplen;\n-\n-\tif (remaining_len == 0) {\n-\t\tRTE_LOG(ERR, EAL, \"Command line too long!\\n\");\n-\t\trte_spinlock_unlock(&config->sl);\n-\t\treturn -1;\n-\t}\n-\n-\t/* if current length of the command line is bigger than the buffer supplied\n-\t * by the user, or if command-line is bigger than what IVSHMEM accepts */\n-\tif ((sizeof(cmdline) - remaining_len) > size) {\n-\t\tRTE_LOG(ERR, EAL, \"Buffer is too short!\\n\");\n-\t\trte_spinlock_unlock(&config->sl);\n-\t\treturn -1;\n-\t}\n-\t/* complete the command-line */\n-\tsnprintf(buffer, size,\n-\t\t\tIVSHMEM_QEMU_CMD_LINE_HEADER_FMT,\n-\t\t\ttotal_size >> 20,\n-\t\t\tcmdline);\n-\n-\trte_spinlock_unlock(&config->sl);\n-\n-\treturn 0;\n-}\n-\n-void\n-rte_ivshmem_metadata_dump(FILE *f, const char *name)\n-{\n-\tunsigned i = 0;\n-\tstruct ivshmem_config * config;\n-\tstruct rte_ivshmem_metadata_entry *entry;\n-#ifdef RTE_LIBRTE_IVSHMEM_DEBUG\n-\tuint64_t addr;\n-\tuint64_t end, hugepage_sz;\n-\tstruct memseg_cache_entry e;\n-#endif\n-\n-\tif (name == NULL)\n-\t\treturn;\n-\n-\t/* return error if we try to use an unknown config file */\n-\tconfig = get_config_by_name(name);\n-\tif (config == NULL) {\n-\t\tRTE_LOG(ERR, EAL, \"Cannot find IVSHMEM config %s!\\n\", name);\n-\t\treturn;\n-\t}\n-\n-\trte_spinlock_lock(&config->sl);\n-\n-\tentry = &config->metadata->entry[0];\n-\n-\twhile (entry->mz.addr != NULL && i < RTE_DIM(config->metadata->entry)) {\n-\n-\t\tfprintf(f, \"Entry %u: name:<%-20s>, phys:0x%-15lx, len:0x%-15lx, \"\n-\t\t\t\"virt:%-15p, off:0x%-15lx\\n\",\n-\t\t\ti,\n-\t\t\tentry->mz.name,\n-\t\t\tentry->mz.phys_addr,\n-\t\t\tentry->mz.len,\n-\t\t\tentry->mz.addr,\n-\t\t\tentry->offset);\n-\t\ti++;\n-\n-#ifdef RTE_LIBRTE_IVSHMEM_DEBUG\n-\t\tfprintf(f, \"\\tHugepage files:\\n\");\n-\n-\t\thugepage_sz = entry->mz.hugepage_sz;\n-\t\taddr = RTE_ALIGN_FLOOR(entry->mz.addr_64, hugepage_sz);\n-\t\tend = addr + RTE_ALIGN_CEIL(entry->mz.len + (entry->mz.addr_64 - addr),\n-\t\t\t\thugepage_sz);\n-\n-\t\tfor (; addr < end; addr += hugepage_sz) {\n-\t\t\tmemset(&e, 0, sizeof(e));\n-\n-\t\t\tget_hugefile_by_virt_addr(addr, &e);\n-\n-\t\t\tfprintf(f, \"\\t0x%\"PRIx64 \"-0x%\" PRIx64 \" offset: 0x%\" PRIx64 \" %s\\n\",\n-\t\t\t\t\taddr, addr + hugepage_sz, e.offset, e.filepath);\n-\t\t}\n-#endif\n-\t\tentry++;\n-\t}\n-\n-\trte_spinlock_unlock(&config->sl);\n-}\ndiff --git a/lib/librte_ivshmem/rte_ivshmem.h b/lib/librte_ivshmem/rte_ivshmem.h\ndeleted file mode 100644\nindex a5d36d6..0000000\n--- a/lib/librte_ivshmem/rte_ivshmem.h\n+++ /dev/null\n@@ -1,165 +0,0 @@\n-/*-\n- *   BSD LICENSE\n- *\n- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.\n- *   All rights reserved.\n- *\n- *   Redistribution and use in source and binary forms, with or without\n- *   modification, are permitted provided that the following conditions\n- *   are met:\n- *\n- *     * Redistributions of source code must retain the above copyright\n- *       notice, this list of conditions and the following disclaimer.\n- *     * Redistributions in binary form must reproduce the above copyright\n- *       notice, this list of conditions and the following disclaimer in\n- *       the documentation and/or other materials provided with the\n- *       distribution.\n- *     * Neither the name of Intel Corporation nor the names of its\n- *       contributors may be used to endorse or promote products derived\n- *       from this software without specific prior written permission.\n- *\n- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n- *   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n- */\n-\n-#ifndef RTE_IVSHMEM_H_\n-#define RTE_IVSHMEM_H_\n-\n-#include <rte_memzone.h>\n-#include <rte_mempool.h>\n-\n-/**\n- * @file\n- *\n- * The RTE IVSHMEM interface provides functions to create metadata files\n- * describing memory segments to be shared via QEMU IVSHMEM.\n- */\n-\n-\n-#ifdef __cplusplus\n-extern \"C\" {\n-#endif\n-\n-#define IVSHMEM_MAGIC 0x0BADC0DE\n-#define IVSHMEM_NAME_LEN 32\n-\n-/**\n- * Structure that holds IVSHMEM shared metadata entry.\n- */\n-struct rte_ivshmem_metadata_entry {\n-\tstruct rte_memzone mz;\t/**< shared memzone */\n-\tuint64_t offset;\t/**< offset of memzone within IVSHMEM device */\n-};\n-\n-/**\n- * Structure that holds IVSHMEM metadata.\n- */\n-struct rte_ivshmem_metadata {\n-\tint magic_number;\t\t\t\t/**< magic number */\n-\tchar name[IVSHMEM_NAME_LEN];\t/**< name of the metadata file */\n-\tstruct rte_ivshmem_metadata_entry entry[RTE_LIBRTE_IVSHMEM_MAX_ENTRIES];\n-\t\t\t/**< metadata entries */\n-};\n-\n-/**\n- * Creates metadata file with a given name\n- *\n- * @param name\n- *  Name of metadata file to be created\n- *\n- * @return\n- *  - On success, zero\n- *  - On failure, a negative value\n- */\n-int rte_ivshmem_metadata_create(const char * name);\n-\n-/**\n- * Adds memzone to a specific metadata file\n- *\n- * @param mz\n- *  Memzone to be added\n- * @param md_name\n- *  Name of metadata file for the memzone to be added to\n- *\n- * @return\n- *  - On success, zero\n- *  - On failure, a negative value\n- */\n-int rte_ivshmem_metadata_add_memzone(const struct rte_memzone * mz,\n-\t\tconst char * md_name);\n-\n-/**\n- * Adds a ring descriptor to a specific metadata file\n- *\n- * @param r\n- *  Ring descriptor to be added\n- * @param md_name\n- *  Name of metadata file for the ring to be added to\n- *\n- * @return\n- *  - On success, zero\n- *  - On failure, a negative value\n- */\n-int rte_ivshmem_metadata_add_ring(const struct rte_ring * r,\n-\t\tconst char * md_name);\n-\n-/**\n- * Adds a mempool to a specific metadata file\n- *\n- * @param mp\n- *  Mempool to be added\n- * @param md_name\n- *  Name of metadata file for the mempool to be added to\n- *\n- * @return\n- *  - On success, zero\n- *  - On failure, a negative value\n- */\n-int rte_ivshmem_metadata_add_mempool(const struct rte_mempool * mp,\n-\t\tconst char * md_name);\n-\n-\n-/**\n- * Generates the QEMU command-line for IVSHMEM device for a given metadata file.\n- * This function is to be called after all the objects were added.\n- *\n- * @param buffer\n- *  Buffer to be filled with the command line arguments.\n- * @param size\n- *  Size of the buffer.\n- * @param name\n- *  Name of metadata file to generate QEMU command-line parameters for\n- *\n- * @return\n- *  - On success, zero\n- *  - On failure, a negative value\n- */\n-int rte_ivshmem_metadata_cmdline_generate(char *buffer, unsigned size,\n-\t\tconst char *name);\n-\n-\n-/**\n- * Dump all metadata entries from a given metadata file to the console.\n- *\n- * @param f\n- *   A pointer to a file for output\n- * @name\n- *  Name of the metadata file to be dumped to console.\n- */\n-void rte_ivshmem_metadata_dump(FILE *f, const char *name);\n-\n-\n-#ifdef __cplusplus\n-}\n-#endif\n-\n-#endif /* RTE_IVSHMEM_H_ */\ndiff --git a/lib/librte_ivshmem/rte_ivshmem_version.map b/lib/librte_ivshmem/rte_ivshmem_version.map\ndeleted file mode 100644\nindex 5a393dd..0000000\n--- a/lib/librte_ivshmem/rte_ivshmem_version.map\n+++ /dev/null\n@@ -1,12 +0,0 @@\n-DPDK_2.0 {\n-\tglobal:\n-\n-\trte_ivshmem_metadata_add_mempool;\n-\trte_ivshmem_metadata_add_memzone;\n-\trte_ivshmem_metadata_add_ring;\n-\trte_ivshmem_metadata_cmdline_generate;\n-\trte_ivshmem_metadata_create;\n-\trte_ivshmem_metadata_dump;\n-\n-\tlocal: *;\n-};\ndiff --git a/mk/rte.app.mk b/mk/rte.app.mk\nindex eb28e11..1a0095b 100644\n--- a/mk/rte.app.mk\n+++ b/mk/rte.app.mk\n@@ -62,7 +62,6 @@ _LDLIBS-y += -L$(RTE_SDK_BIN)/lib\n \n ifeq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)\n _LDLIBS-$(CONFIG_RTE_LIBRTE_KNI)            += -lrte_kni\n-_LDLIBS-$(CONFIG_RTE_LIBRTE_IVSHMEM)        += -lrte_ivshmem\n endif\n \n _LDLIBS-$(CONFIG_RTE_LIBRTE_PIPELINE)       += -lrte_pipeline\n",
    "prefixes": [
        "dpdk-dev"
    ]
}