get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 28085,
    "url": "https://patches.dpdk.org/api/patches/28085/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/1504116634-115687-2-git-send-email-jianfeng.tan@intel.com/",
    "project": {
        "id": 1,
        "url": "https://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": "<1504116634-115687-2-git-send-email-jianfeng.tan@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1504116634-115687-2-git-send-email-jianfeng.tan@intel.com",
    "date": "2017-08-30T18:10:29",
    "name": "[dpdk-dev,1/6] example/vhost_xen: remove",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "7bab11621d3f237ed7ce4cc8829351ec750c0777",
    "submitter": {
        "id": 313,
        "url": "https://patches.dpdk.org/api/people/313/?format=api",
        "name": "Jianfeng Tan",
        "email": "jianfeng.tan@intel.com"
    },
    "delegate": null,
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/1504116634-115687-2-git-send-email-jianfeng.tan@intel.com/mbox/",
    "series": [],
    "comments": "https://patches.dpdk.org/api/patches/28085/comments/",
    "check": "success",
    "checks": "https://patches.dpdk.org/api/patches/28085/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 183192C17;\n\tWed, 30 Aug 2017 20:09:46 +0200 (CEST)",
            "from mga07.intel.com (mga07.intel.com [134.134.136.100])\n\tby dpdk.org (Postfix) with ESMTP id 11C932C17\n\tfor <dev@dpdk.org>; Wed, 30 Aug 2017 20:09:42 +0200 (CEST)",
            "from orsmga002.jf.intel.com ([10.7.209.21])\n\tby orsmga105.jf.intel.com with ESMTP; 30 Aug 2017 11:09:42 -0700",
            "from dpdk06.sh.intel.com ([10.67.110.196])\n\tby orsmga002.jf.intel.com with ESMTP; 30 Aug 2017 11:09:40 -0700"
        ],
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.41,449,1498546800\"; d=\"scan'208\";a=\"130029469\"",
        "From": "Jianfeng Tan <jianfeng.tan@intel.com>",
        "To": "dev@dpdk.org",
        "Cc": "xen-devel@lists.xenproject.org, thomas@monjalon.net,\n\tjohn.mcnamara@intel.com, oao.m.martins@oracle.com,\n\tjerin.jacob@caviumnetworks.com, shahafs@mellanox.com,\n\tJianfeng Tan <jianfeng.tan@intel.com>",
        "Date": "Wed, 30 Aug 2017 18:10:29 +0000",
        "Message-Id": "<1504116634-115687-2-git-send-email-jianfeng.tan@intel.com>",
        "X-Mailer": "git-send-email 2.7.4",
        "In-Reply-To": "<1504116634-115687-1-git-send-email-jianfeng.tan@intel.com>",
        "References": "<1504116634-115687-1-git-send-email-jianfeng.tan@intel.com>",
        "Subject": "[dpdk-dev] [PATCH 1/6] example/vhost_xen: remove",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <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": "Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>\n---\n MAINTAINERS                         |    1 -\n examples/Makefile                   |    1 -\n examples/vhost_xen/Makefile         |   52 --\n examples/vhost_xen/main.c           | 1522 -----------------------------------\n examples/vhost_xen/main.h           |   66 --\n examples/vhost_xen/vhost_monitor.c  |  595 --------------\n examples/vhost_xen/virtio-net.h     |  113 ---\n examples/vhost_xen/xen_vhost.h      |  148 ----\n examples/vhost_xen/xenstore_parse.c |  775 ------------------\n 9 files changed, 3273 deletions(-)\n delete mode 100644 examples/vhost_xen/Makefile\n delete mode 100644 examples/vhost_xen/main.c\n delete mode 100644 examples/vhost_xen/main.h\n delete mode 100644 examples/vhost_xen/vhost_monitor.c\n delete mode 100644 examples/vhost_xen/virtio-net.h\n delete mode 100644 examples/vhost_xen/xen_vhost.h\n delete mode 100644 examples/vhost_xen/xenstore_parse.c",
    "diff": "diff --git a/MAINTAINERS b/MAINTAINERS\nindex a0cd75e..fe6c6db 100644\n--- a/MAINTAINERS\n+++ b/MAINTAINERS\n@@ -196,7 +196,6 @@ F: lib/librte_eal/linuxapp/eal/*xen*\n F: lib/librte_eal/linuxapp/eal/include/exec-env/rte_dom0_common.h\n F: drivers/net/xenvirt/\n F: doc/guides/xen/\n-F: examples/vhost_xen/\n F: doc/guides/nics/features/xenvirt.ini\n \n FreeBSD EAL (with overlaps)\ndiff --git a/examples/Makefile b/examples/Makefile\nindex 28354ff..d27eddd 100644\n--- a/examples/Makefile\n+++ b/examples/Makefile\n@@ -89,7 +89,6 @@ DIRS-$(CONFIG_RTE_LIBRTE_VHOST) += tep_termination\n endif\n DIRS-$(CONFIG_RTE_LIBRTE_TIMER) += timer\n DIRS-$(CONFIG_RTE_LIBRTE_VHOST) += vhost vhost_scsi\n-DIRS-$(CONFIG_RTE_LIBRTE_XEN_DOM0) += vhost_xen\n DIRS-y += vmdq\n DIRS-y += vmdq_dcb\n ifeq ($(CONFIG_RTE_LIBRTE_POWER), y)\ndiff --git a/examples/vhost_xen/Makefile b/examples/vhost_xen/Makefile\ndeleted file mode 100644\nindex ad2466a..0000000\n--- a/examples/vhost_xen/Makefile\n+++ /dev/null\n@@ -1,52 +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 overridden by command line or environment\n-RTE_TARGET ?= x86_64-native-linuxapp-gcc\n-\n-include $(RTE_SDK)/mk/rte.vars.mk\n-\n-# binary name\n-APP = vhost-switch\n-\n-# all source are stored in SRCS-y\n-SRCS-y := main.c vhost_monitor.c xenstore_parse.c\n-\n-CFLAGS += -O2 -I/usr/local/include -D_FILE_OFFSET_BITS=64 -Wno-unused-parameter\n-CFLAGS += $(WERROR_FLAGS)\n-CFLAGS += -D_GNU_SOURCE\n-LDFLAGS += -lxenstore\n-\n-include $(RTE_SDK)/mk/rte.extapp.mk\ndiff --git a/examples/vhost_xen/main.c b/examples/vhost_xen/main.c\ndeleted file mode 100644\nindex eba4d35..0000000\n--- a/examples/vhost_xen/main.c\n+++ /dev/null\n@@ -1,1522 +0,0 @@\n-/*-\n- *   BSD LICENSE\n- *\n- *   Copyright(c) 2010-2015 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 <arpa/inet.h>\n-#include <getopt.h>\n-#include <linux/if_ether.h>\n-#include <linux/if_vlan.h>\n-#include <linux/virtio_net.h>\n-#include <linux/virtio_ring.h>\n-#include <signal.h>\n-#include <stdint.h>\n-#include <sys/eventfd.h>\n-#include <sys/param.h>\n-#include <unistd.h>\n-\n-#include <rte_atomic.h>\n-#include <rte_cycles.h>\n-#include <rte_ethdev.h>\n-#include <rte_log.h>\n-#include <rte_string_fns.h>\n-#include <rte_pause.h>\n-\n-#include \"main.h\"\n-#include \"virtio-net.h\"\n-#include \"xen_vhost.h\"\n-\n-#define MAX_QUEUES 128\n-\n-/* the maximum number of external ports supported */\n-#define MAX_SUP_PORTS 1\n-\n-/*\n- * Calculate the number of buffers needed per port\n- */\n-#define NUM_MBUFS_PER_PORT ((MAX_QUEUES*RTE_TEST_RX_DESC_DEFAULT) +\t\t\\\n-\t\t\t\t\t\t\t(num_switching_cores*MAX_PKT_BURST) +  \t\t\t\\\n-\t\t\t\t\t\t\t(num_switching_cores*RTE_TEST_TX_DESC_DEFAULT) +\\\n-\t\t\t\t\t\t\t(num_switching_cores*MBUF_CACHE_SIZE))\n-\n-#define MBUF_CACHE_SIZE 64\n-\n-/*\n- * RX and TX Prefetch, Host, and Write-back threshold values should be\n- * carefully set for optimal performance. Consult the network\n- * controller's datasheet and supporting DPDK documentation for guidance\n- * on how these parameters should be set.\n- */\n-#define RX_PTHRESH 8 /* Default values of RX prefetch threshold reg. */\n-#define RX_HTHRESH 8 /* Default values of RX host threshold reg. */\n-#define RX_WTHRESH 4 /* Default values of RX write-back threshold reg. */\n-\n-/*\n- * These default values are optimized for use with the Intel(R) 82599 10 GbE\n- * Controller and the DPDK ixgbe PMD. Consider using other values for other\n- * network controllers and/or network drivers.\n- */\n-#define TX_PTHRESH 36 /* Default values of TX prefetch threshold reg. */\n-#define TX_HTHRESH 0  /* Default values of TX host threshold reg. */\n-#define TX_WTHRESH 0  /* Default values of TX write-back threshold reg. */\n-\n-#define MAX_PKT_BURST 32\t\t/* Max burst size for RX/TX */\n-#define MAX_MRG_PKT_BURST 16\t/* Max burst for merge buffers. Set to 1 due to performance issue. */\n-#define BURST_TX_DRAIN_US 100\t/* TX drain every ~100us */\n-\n-/* State of virtio device. */\n-#define DEVICE_NOT_READY     0\n-#define DEVICE_READY         1\n-#define DEVICE_SAFE_REMOVE   2\n-\n-/* Config_core_flag status definitions. */\n-#define REQUEST_DEV_REMOVAL 1\n-#define ACK_DEV_REMOVAL 0\n-\n-/* Configurable number of RX/TX ring descriptors */\n-#define RTE_TEST_RX_DESC_DEFAULT 128\n-#define RTE_TEST_TX_DESC_DEFAULT 512\n-\n-#define INVALID_PORT_ID 0xFF\n-\n-/* Max number of devices. Limited by vmdq. */\n-#define MAX_DEVICES 64\n-\n-/* Size of buffers used for snprintfs. */\n-#define MAX_PRINT_BUFF 6072\n-\n-\n-/* Maximum long option length for option parsing. */\n-#define MAX_LONG_OPT_SZ 64\n-\n-/* Used to compare MAC addresses. */\n-#define MAC_ADDR_CMP 0xFFFFFFFFFFFF\n-\n-/* mask of enabled ports */\n-static uint32_t enabled_port_mask = 0;\n-\n-/*Number of switching cores enabled*/\n-static uint32_t num_switching_cores = 0;\n-\n-/* number of devices/queues to support*/\n-static uint32_t num_queues = 0;\n-uint32_t num_devices = 0;\n-\n-/* Enable VM2VM communications. If this is disabled then the MAC address compare is skipped. */\n-static uint32_t enable_vm2vm = 1;\n-/* Enable stats. */\n-static uint32_t enable_stats = 0;\n-\n-/* empty vmdq configuration structure. Filled in programatically */\n-static const struct rte_eth_conf vmdq_conf_default = {\n-\t.rxmode = {\n-\t\t.mq_mode        = ETH_MQ_RX_VMDQ_ONLY,\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/*\n-\t\t * It is necessary for 1G NIC such as I350,\n-\t\t * this fixes bug of ipv4 forwarding in guest can't\n-\t\t * forward pakets from one virtio dev to another virtio dev.\n-\t\t */\n-\t\t.hw_vlan_strip  = 1, /**< VLAN strip enabled. */\n-\t\t.jumbo_frame    = 0, /**< Jumbo Frame Support disabled */\n-\t\t.hw_strip_crc   = 1, /**< CRC stripped by hardware */\n-\t},\n-\n-\t.txmode = {\n-\t\t.mq_mode = ETH_MQ_TX_NONE,\n-\t},\n-\t.rx_adv_conf = {\n-\t\t/*\n-\t\t * should be overridden separately in code with\n-\t\t * appropriate values\n-\t\t */\n-\t\t.vmdq_rx_conf = {\n-\t\t\t.nb_queue_pools = ETH_8_POOLS,\n-\t\t\t.enable_default_pool = 0,\n-\t\t\t.default_pool = 0,\n-\t\t\t.nb_pool_maps = 0,\n-\t\t\t.pool_map = {{0, 0},},\n-\t\t},\n-\t},\n-};\n-\n-static unsigned lcore_ids[RTE_MAX_LCORE];\n-static uint8_t ports[RTE_MAX_ETHPORTS];\n-static unsigned num_ports = 0; /**< The number of ports specified in command line */\n-\n-const uint16_t vlan_tags[] = {\n-\t1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007,\n-\t1008, 1009, 1010, 1011,\t1012, 1013, 1014, 1015,\n-\t1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023,\n-\t1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031,\n-\t1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039,\n-\t1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047,\n-\t1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055,\n-\t1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063,\n-};\n-\n-/* ethernet addresses of ports */\n-static struct ether_addr vmdq_ports_eth_addr[RTE_MAX_ETHPORTS];\n-\n-/* heads for the main used and free linked lists for the data path. */\n-static struct virtio_net_data_ll *ll_root_used = NULL;\n-static struct virtio_net_data_ll *ll_root_free = NULL;\n-\n-/* Array of data core structures containing information on individual core linked lists. */\n-static struct lcore_info lcore_info[RTE_MAX_LCORE];\n-\n-/* Used for queueing bursts of TX packets. */\n-struct mbuf_table {\n-\tunsigned len;\n-\tunsigned txq_id;\n-\tstruct rte_mbuf *m_table[MAX_PKT_BURST];\n-};\n-\n-/* TX queue for each data core. */\n-struct mbuf_table lcore_tx_queue[RTE_MAX_LCORE];\n-\n-/* Vlan header struct used to insert vlan tags on TX. */\n-struct vlan_ethhdr {\n-\tunsigned char   h_dest[ETH_ALEN];\n-\tunsigned char   h_source[ETH_ALEN];\n-\t__be16          h_vlan_proto;\n-\t__be16          h_vlan_TCI;\n-\t__be16          h_vlan_encapsulated_proto;\n-};\n-\n-/* Header lengths. */\n-#define VLAN_HLEN       4\n-#define VLAN_ETH_HLEN   18\n-\n-/* Per-device statistics struct */\n-struct device_statistics {\n-\tuint64_t tx_total;\n-\trte_atomic64_t rx_total;\n-\tuint64_t tx;\n-\trte_atomic64_t rx;\n-} __rte_cache_aligned;\n-struct device_statistics dev_statistics[MAX_DEVICES];\n-\n-/*\n- * Builds up the correct configuration for VMDQ VLAN pool map\n- * according to the pool & queue limits.\n- */\n-static inline int\n-get_eth_conf(struct rte_eth_conf *eth_conf, uint32_t num_devices)\n-{\n-\tstruct rte_eth_vmdq_rx_conf conf;\n-\tunsigned i;\n-\n-\tmemset(&conf, 0, sizeof(conf));\n-\tconf.nb_queue_pools = (enum rte_eth_nb_pools)num_devices;\n-\tconf.nb_pool_maps = num_devices;\n-\n-\tfor (i = 0; i < conf.nb_pool_maps; i++) {\n-\t\tconf.pool_map[i].vlan_id = vlan_tags[ i ];\n-\t\tconf.pool_map[i].pools = (1UL << i);\n-\t}\n-\n-\t(void)(rte_memcpy(eth_conf, &vmdq_conf_default, sizeof(*eth_conf)));\n-\t(void)(rte_memcpy(&eth_conf->rx_adv_conf.vmdq_rx_conf, &conf,\n-\t\t   sizeof(eth_conf->rx_adv_conf.vmdq_rx_conf)));\n-\treturn 0;\n-}\n-\n-/*\n- * Validate the device number according to the max pool number gotten form dev_info\n- * If the device number is invalid, give the error message and return -1.\n- * Each device must have its own pool.\n- */\n-static inline int\n-validate_num_devices(uint32_t max_nb_devices)\n-{\n-\tif (num_devices > max_nb_devices) {\n-\t\tRTE_LOG(ERR, VHOST_PORT, \"invalid number of devices\\n\");\n-\t\treturn -1;\n-\t}\n-\treturn 0;\n-}\n-\n-/*\n- * Initialises a given port using global settings and with the rx buffers\n- * coming from the mbuf_pool passed as parameter\n- */\n-static inline int\n-port_init(uint8_t port, struct rte_mempool *mbuf_pool)\n-{\n-\tstruct rte_eth_dev_info dev_info;\n-\tstruct rte_eth_rxconf *rxconf;\n-\tstruct rte_eth_conf port_conf;\n-\tuint16_t rx_rings, tx_rings = (uint16_t)rte_lcore_count();\n-\tuint16_t rx_ring_size = RTE_TEST_RX_DESC_DEFAULT;\n-\tuint16_t tx_ring_size = RTE_TEST_TX_DESC_DEFAULT;\n-\tint retval;\n-\tuint16_t q;\n-\n-\t/* The max pool number from dev_info will be used to validate the pool number specified in cmd line */\n-\trte_eth_dev_info_get (port, &dev_info);\n-\n-\t/*configure the number of supported virtio devices based on VMDQ limits */\n-\tnum_devices = dev_info.max_vmdq_pools;\n-\tnum_queues = dev_info.max_rx_queues;\n-\n-\tretval = validate_num_devices(MAX_DEVICES);\n-\tif (retval < 0)\n-\t\treturn retval;\n-\n-\t/* Get port configuration. */\n-\tretval = get_eth_conf(&port_conf, num_devices);\n-\tif (retval < 0)\n-\t\treturn retval;\n-\n-\tif (port >= rte_eth_dev_count()) return -1;\n-\n-\trx_rings = (uint16_t)num_queues,\n-\t/* Configure ethernet device. */\n-\tretval = rte_eth_dev_configure(port, rx_rings, tx_rings, &port_conf);\n-\tif (retval != 0)\n-\t\treturn retval;\n-\n-\tretval = rte_eth_dev_adjust_nb_rx_tx_desc(port, &rx_ring_size,\n-\t\t&tx_ring_size);\n-\tif (retval != 0)\n-\t\treturn retval;\n-\tif (rx_ring_size > RTE_TEST_RX_DESC_DEFAULT ||\n-\t\ttx_ring_size > RTE_TEST_TX_DESC_DEFAULT) {\n-\t\tRTE_LOG(ERR, VHOST_PORT, \"Mbuf pool has an insufficient size for \"\n-\t\t\t\"port %u.\\n\", port);\n-\t\treturn -1;\n-\t}\n-\n-\trte_eth_dev_info_get(port, &dev_info);\n-\trxconf = &dev_info.default_rxconf;\n-\trxconf->rx_drop_en = 1;\n-\t/* Setup the queues. */\n-\tfor (q = 0; q < rx_rings; q ++) {\n-\t\tretval = rte_eth_rx_queue_setup(port, q, rx_ring_size,\n-\t\t\t\t\t\trte_eth_dev_socket_id(port), rxconf,\n-\t\t\t\t\t\tmbuf_pool);\n-\t\tif (retval < 0)\n-\t\t\treturn retval;\n-\t}\n-\tfor (q = 0; q < tx_rings; q ++) {\n-\t\tretval = rte_eth_tx_queue_setup(port, q, tx_ring_size,\n-\t\t\t\t\t\trte_eth_dev_socket_id(port),\n-\t\t\t\t\t\tNULL);\n-\t\tif (retval < 0)\n-\t\t\treturn retval;\n-\t}\n-\n-\t/* Start the device. */\n-\tretval  = rte_eth_dev_start(port);\n-\tif (retval < 0)\n-\t\treturn retval;\n-\n-\trte_eth_macaddr_get(port, &vmdq_ports_eth_addr[port]);\n-\tRTE_LOG(INFO, VHOST_PORT, \"Max virtio devices supported: %u\\n\", num_devices);\n-\tRTE_LOG(INFO, VHOST_PORT, \"Port %u MAC: %02\"PRIx8\" %02\"PRIx8\" %02\"PRIx8\n-\t\t\t\" %02\"PRIx8\" %02\"PRIx8\" %02\"PRIx8\"\\n\",\n-\t\t\t(unsigned)port,\n-\t\t\tvmdq_ports_eth_addr[port].addr_bytes[0],\n-\t\t\tvmdq_ports_eth_addr[port].addr_bytes[1],\n-\t\t\tvmdq_ports_eth_addr[port].addr_bytes[2],\n-\t\t\tvmdq_ports_eth_addr[port].addr_bytes[3],\n-\t\t\tvmdq_ports_eth_addr[port].addr_bytes[4],\n-\t\t\tvmdq_ports_eth_addr[port].addr_bytes[5]);\n-\n-\treturn 0;\n-}\n-\n-/*\n- * Parse the portmask provided at run time.\n- */\n-static int\n-parse_portmask(const char *portmask)\n-{\n-\tchar *end = NULL;\n-\tunsigned long pm;\n-\n-\terrno = 0;\n-\n-\t/* parse hexadecimal string */\n-\tpm = strtoul(portmask, &end, 16);\n-\tif ((portmask[0] == '\\0') || (end == NULL) || (*end != '\\0') || (errno != 0))\n-\t\treturn -1;\n-\n-\tif (pm == 0)\n-\t\treturn -1;\n-\n-\treturn pm;\n-\n-}\n-\n-/*\n- * Parse num options at run time.\n- */\n-static int\n-parse_num_opt(const char *q_arg, uint32_t max_valid_value)\n-{\n-\tchar *end = NULL;\n-\tunsigned long num;\n-\n-\terrno = 0;\n-\n-\t/* parse unsigned int string */\n-\tnum = strtoul(q_arg, &end, 10);\n-\tif ((q_arg[0] == '\\0') || (end == NULL) || (*end != '\\0') || (errno != 0))\n-\t\treturn -1;\n-\n-\tif (num > max_valid_value)\n-\t\treturn -1;\n-\n-\treturn num;\n-\n-}\n-\n-/*\n- * Display usage\n- */\n-static void\n-us_vhost_usage(const char *prgname)\n-{\n-\tRTE_LOG(INFO, VHOST_CONFIG, \"%s [EAL options] -- -p PORTMASK --vm2vm [0|1] --stats [0-N] --nb-devices ND\\n\"\n-\t\"\t\t-p PORTMASK: Set mask for ports to be used by application\\n\"\n-\t\"\t\t--vm2vm [0|1]: disable/enable(default) vm2vm comms\\n\"\n-\t\"\t\t--stats [0-N]: 0: Disable stats, N: Time in seconds to print stats\\n\",\n-\t       prgname);\n-}\n-\n-/*\n- * Parse the arguments given in the command line of the application.\n- */\n-static int\n-us_vhost_parse_args(int argc, char **argv)\n-{\n-\tint opt, ret;\n-\tint option_index;\n-\tunsigned i;\n-\tconst char *prgname = argv[0];\n-\tstatic struct option long_option[] = {\n-\t\t{\"vm2vm\", required_argument, NULL, 0},\n-\t\t{\"stats\", required_argument, NULL, 0},\n-\t\t{NULL, 0, 0, 0}\n-\t};\n-\n-\t/* Parse command line */\n-\twhile ((opt = getopt_long(argc, argv, \"p:\",long_option, &option_index)) != EOF) {\n-\t\tswitch (opt) {\n-\t\t/* Portmask */\n-\t\tcase 'p':\n-\t\t\tenabled_port_mask = parse_portmask(optarg);\n-\t\t\tif (enabled_port_mask == 0) {\n-\t\t\t\tRTE_LOG(INFO, VHOST_CONFIG, \"Invalid portmask\\n\");\n-\t\t\t\tus_vhost_usage(prgname);\n-\t\t\t\treturn -1;\n-\t\t\t}\n-\t\t\tbreak;\n-\n-\t\tcase 0:\n-\t\t\t/* Enable/disable vm2vm comms. */\n-\t\t\tif (!strncmp(long_option[option_index].name, \"vm2vm\", MAX_LONG_OPT_SZ)) {\n-\t\t\t\tret = parse_num_opt(optarg, 1);\n-\t\t\t\tif (ret == -1) {\n-\t\t\t\t\tRTE_LOG(INFO, VHOST_CONFIG, \"Invalid argument for vm2vm [0|1]\\n\");\n-\t\t\t\t\tus_vhost_usage(prgname);\n-\t\t\t\t\treturn -1;\n-\t\t\t\t} else {\n-\t\t\t\t\tenable_vm2vm = ret;\n-\t\t\t\t}\n-\t\t\t}\n-\n-\t\t\t/* Enable/disable stats. */\n-\t\t\tif (!strncmp(long_option[option_index].name, \"stats\", MAX_LONG_OPT_SZ)) {\n-\t\t\t\tret = parse_num_opt(optarg, INT32_MAX);\n-\t\t\t\tif (ret == -1) {\n-\t\t\t\t\tRTE_LOG(INFO, VHOST_CONFIG, \"Invalid argument for stats [0..N]\\n\");\n-\t\t\t\t\tus_vhost_usage(prgname);\n-\t\t\t\t\treturn -1;\n-\t\t\t\t} else {\n-\t\t\t\t\tenable_stats = ret;\n-\t\t\t\t}\n-\t\t\t}\n-\t\t\tbreak;\n-\n-\t\t\t/* Invalid option - print options. */\n-\t\tdefault:\n-\t\t\tus_vhost_usage(prgname);\n-\t\t\treturn -1;\n-\t\t}\n-\t}\n-\n-\tfor (i = 0; i < RTE_MAX_ETHPORTS; i++) {\n-\t\tif (enabled_port_mask & (1 << i))\n-\t\t\tports[num_ports++] = (uint8_t)i;\n-\t}\n-\n-\tif ((num_ports ==  0) || (num_ports > MAX_SUP_PORTS)) {\n-\t\tRTE_LOG(INFO, VHOST_PORT, \"Current enabled port number is %u,\"\n-\t\t\t\"but only %u port can be enabled\\n\",num_ports, MAX_SUP_PORTS);\n-\t\treturn -1;\n-\t}\n-\n-\treturn 0;\n-}\n-\n-/*\n- * Update the global var NUM_PORTS and array PORTS according to system ports number\n- * and return valid ports number\n- */\n-static unsigned check_ports_num(unsigned nb_ports)\n-{\n-\tunsigned valid_num_ports = num_ports;\n-\tunsigned portid;\n-\n-\tif (num_ports > nb_ports) {\n-\t\tRTE_LOG(INFO, VHOST_PORT, \"\\nSpecified port number(%u) exceeds total system port number(%u)\\n\",\n-\t\t\tnum_ports, nb_ports);\n-\t\tnum_ports = nb_ports;\n-\t}\n-\n-\tfor (portid = 0; portid < num_ports; portid ++) {\n-\t\tif (ports[portid] >= nb_ports) {\n-\t\t\tRTE_LOG(INFO, VHOST_PORT, \"\\nSpecified port ID(%u) exceeds max system port ID(%u)\\n\",\n-\t\t\t\tports[portid], (nb_ports - 1));\n-\t\t\tports[portid] = INVALID_PORT_ID;\n-\t\t\tvalid_num_ports--;\n-\t\t}\n-\t}\n-\treturn valid_num_ports;\n-}\n-\n-/*\n- * Function to convert guest physical addresses to vhost virtual addresses. This\n- * is used to convert virtio buffer addresses.\n- */\n-static __rte_always_inline uint64_t\n-gpa_to_vva(struct virtio_net *dev, uint64_t guest_pa)\n-{\n-\tstruct virtio_memory_regions *region;\n-\tuint32_t regionidx;\n-\tuint64_t vhost_va = 0;\n-\n-\tfor (regionidx = 0; regionidx < dev->mem->nregions; regionidx++) {\n-\t\tregion = &dev->mem->regions[regionidx];\n-\t\tif ((guest_pa >= region->guest_phys_address) &&\n-\t\t\t(guest_pa <= region->guest_phys_address_end)) {\n-\t\t\tvhost_va = region->address_offset + guest_pa;\n-\t\t\tbreak;\n-\t\t}\n-\t}\n-\tRTE_LOG_DP(DEBUG, VHOST_DATA, \"(%\" PRIu64 \") GPA %p| VVA %p\\n\",\n-\t\tdev->device_fh, (void*)(uintptr_t)guest_pa, (void*)(uintptr_t)vhost_va);\n-\n-\treturn vhost_va;\n-}\n-\n-/*\n- * This function adds buffers to the virtio devices RX virtqueue. Buffers can\n- * be received from the physical port or from another virtio device. A packet\n- * count is returned to indicate the number of packets that were successfully\n- * added to the RX queue.\n- */\n-static __rte_always_inline uint32_t\n-virtio_dev_rx(struct virtio_net *dev, struct rte_mbuf **pkts, uint32_t count)\n-{\n-\tstruct vhost_virtqueue *vq;\n-\tstruct vring_desc *desc;\n-\tstruct rte_mbuf *buff;\n-\t/* The virtio_hdr is initialised to 0. */\n-\tstruct virtio_net_hdr_mrg_rxbuf virtio_hdr = {{0,0,0,0,0,0},0};\n-\tuint64_t buff_addr = 0;\n-\tuint64_t buff_hdr_addr = 0;\n-\tuint32_t head[MAX_PKT_BURST], packet_len = 0;\n-\tuint32_t head_idx, packet_success = 0;\n-\tuint16_t avail_idx, res_cur_idx;\n-\tuint16_t res_base_idx, res_end_idx;\n-\tuint16_t free_entries;\n-\tuint8_t success = 0;\n-\tvoid *userdata;\n-\n-\tRTE_LOG_DP(DEBUG, VHOST_DATA, \"(%\" PRIu64 \") virtio_dev_rx()\\n\", dev->device_fh);\n-\tvq = dev->virtqueue_rx;\n-\tcount = (count > MAX_PKT_BURST) ? MAX_PKT_BURST : count;\n-\t/* As many data cores may want access to available buffers, they need to be reserved. */\n-\tdo {\n-\n-\t\tres_base_idx = vq->last_used_idx_res;\n-\n-\t\tavail_idx = *((volatile uint16_t *)&vq->avail->idx);\n-\n-\t\tfree_entries = (avail_idx - res_base_idx);\n-\n-\t\t/*check that we have enough buffers*/\n-\t\tif (unlikely(count > free_entries))\n-\t\t\tcount = free_entries;\n-\n-\t\tif (count == 0)\n-\t\t\treturn 0;\n-\n-\t\tres_end_idx = res_base_idx + count;\n-\t\t/* vq->last_used_idx_res is atomically updated. */\n-\t\tsuccess = rte_atomic16_cmpset(&vq->last_used_idx_res, res_base_idx,\n-\t\t\t\t\t\t\t\t\tres_end_idx);\n-\t} while (unlikely(success == 0));\n-\tres_cur_idx = res_base_idx;\n-\tRTE_LOG_DP(DEBUG, VHOST_DATA, \"(%\" PRIu64 \") Current Index %d| End Index %d\\n\",\n-\t\tdev->device_fh, res_cur_idx, res_end_idx);\n-\n-\t/* Prefetch available ring to retrieve indexes. */\n-\trte_prefetch0(&vq->avail->ring[res_cur_idx & (vq->size - 1)]);\n-\n-\t/* Retrieve all of the head indexes first to avoid caching issues. */\n-\tfor (head_idx = 0; head_idx < count; head_idx++)\n-\t\thead[head_idx] = vq->avail->ring[(res_cur_idx + head_idx) & (vq->size - 1)];\n-\n-\t/*Prefetch descriptor index. */\n-\trte_prefetch0(&vq->desc[head[packet_success]]);\n-\n-\twhile (res_cur_idx != res_end_idx) {\n-\t\t/* Get descriptor from available ring */\n-\t\tdesc = &vq->desc[head[packet_success]];\n-\t\t/* Prefetch descriptor address. */\n-\t\trte_prefetch0(desc);\n-\n-\t\tbuff = pkts[packet_success];\n-\n-\t\t/* Convert from gpa to vva (guest physical addr -> vhost virtual addr) */\n-\t\tbuff_addr = gpa_to_vva(dev, desc->addr);\n-\t\t/* Prefetch buffer address. */\n-\t\trte_prefetch0((void*)(uintptr_t)buff_addr);\n-\n-\t\t{\n-\t\t\t/* Copy virtio_hdr to packet and increment buffer address */\n-\t\t\tbuff_hdr_addr = buff_addr;\n-\t\t\tpacket_len = rte_pktmbuf_data_len(buff) + vq->vhost_hlen;\n-\n-\t\t\t/*\n-\t\t\t * If the descriptors are chained the header and data are placed in\n-\t\t\t * separate buffers.\n-\t\t\t */\n-\t\t\tif (desc->flags & VRING_DESC_F_NEXT) {\n-\t\t\t\tdesc->len = vq->vhost_hlen;\n-\t\t\t\tdesc = &vq->desc[desc->next];\n-\t\t\t\t/* Buffer address translation. */\n-\t\t\t\tbuff_addr = gpa_to_vva(dev, desc->addr);\n-\t\t\t\tdesc->len = rte_pktmbuf_data_len(buff);\n-\t\t\t} else {\n-\t\t\t\tbuff_addr += vq->vhost_hlen;\n-\t\t\t\tdesc->len = packet_len;\n-\t\t\t}\n-\t\t}\n-\n-\t\t/* Update used ring with desc information */\n-\t\tvq->used->ring[res_cur_idx & (vq->size - 1)].id = head[packet_success];\n-\t\tvq->used->ring[res_cur_idx & (vq->size - 1)].len = packet_len;\n-\n-\t\t/* Copy mbuf data to buffer */\n-\t\tuserdata = rte_pktmbuf_mtod(buff, void *);\n-\t\trte_memcpy((void *)(uintptr_t)buff_addr, userdata, rte_pktmbuf_data_len(buff));\n-\n-\t\tres_cur_idx++;\n-\t\tpacket_success++;\n-\n-\t\t/* mergeable is disabled then a header is required per buffer. */\n-\t\trte_memcpy((void *)(uintptr_t)buff_hdr_addr, (const void *)&virtio_hdr, vq->vhost_hlen);\n-\t\tif (res_cur_idx < res_end_idx) {\n-\t\t\t/* Prefetch descriptor index. */\n-\t\t\trte_prefetch0(&vq->desc[head[packet_success]]);\n-\t\t}\n-\t}\n-\n-\trte_compiler_barrier();\n-\n-\t/* Wait until it's our turn to add our buffer to the used ring. */\n-\twhile (unlikely(vq->last_used_idx != res_base_idx))\n-\t\trte_pause();\n-\n-\t*(volatile uint16_t *)&vq->used->idx += count;\n-\n-\tvq->last_used_idx = res_end_idx;\n-\n-\treturn count;\n-}\n-\n-/*\n- * Compares a packet destination MAC address to a device MAC address.\n- */\n-static __rte_always_inline int\n-ether_addr_cmp(struct ether_addr *ea, struct ether_addr *eb)\n-{\n-\treturn ((*(uint64_t *)ea ^ *(uint64_t *)eb) & MAC_ADDR_CMP) == 0;\n-}\n-\n-/*\n- * This function registers mac along with a\n- * vlan tag to a VMDQ.\n- */\n-static int\n-link_vmdq(struct virtio_net *dev)\n-{\n-\tint ret;\n-\tstruct virtio_net_data_ll *dev_ll;\n-\n-\tdev_ll = ll_root_used;\n-\n-\twhile (dev_ll != NULL) {\n-\t\tif ((dev != dev_ll->dev) && ether_addr_cmp(&dev->mac_address, &dev_ll->dev->mac_address)) {\n-\t\t\tRTE_LOG(INFO, VHOST_DATA, \"(%\"PRIu64\") WARNING: This device is using an existing MAC address and has not been registered.\\n\", dev->device_fh);\n-\t\t\treturn -1;\n-\t\t}\n-\t\tdev_ll = dev_ll->next;\n-\t}\n-\n-\t/* vlan_tag currently uses the device_id. */\n-\tdev->vlan_tag = vlan_tags[dev->device_fh];\n-\tdev->vmdq_rx_q = dev->device_fh * (num_queues/num_devices);\n-\n-\t/* Print out VMDQ registration info. */\n-\tRTE_LOG(INFO, VHOST_DATA, \"(%\"PRIu64\") MAC_ADDRESS %02x:%02x:%02x:%02x:%02x:%02x and VLAN_TAG %d registered\\n\",\n-\t\tdev->device_fh,\n-\t\tdev->mac_address.addr_bytes[0], dev->mac_address.addr_bytes[1],\n-\t\tdev->mac_address.addr_bytes[2], dev->mac_address.addr_bytes[3],\n-\t\tdev->mac_address.addr_bytes[4], dev->mac_address.addr_bytes[5],\n-\t\tdev->vlan_tag);\n-\n-\t/* Register the MAC address. */\n-\tret = rte_eth_dev_mac_addr_add(ports[0], &dev->mac_address, (uint32_t)dev->device_fh);\n-\tif (ret) {\n-\t\tRTE_LOG(ERR, VHOST_DATA, \"(%\"PRIu64\") Failed to add device MAC address to VMDQ\\n\",\n-\t\t\t\t\t\t\t\t\t\tdev->device_fh);\n-\t\treturn -1;\n-\t}\n-\n-\t/* Enable stripping of the vlan tag as we handle routing. */\n-\trte_eth_dev_set_vlan_strip_on_queue(ports[0], dev->vmdq_rx_q, 1);\n-\n-\trte_compiler_barrier();\n-\t/* Set device as ready for RX. */\n-\tdev->ready = DEVICE_READY;\n-\n-\treturn 0;\n-}\n-\n-/*\n- * Removes MAC address and vlan tag from VMDQ. Ensures that nothing is adding buffers to the RX\n- * queue before disabling RX on the device.\n- */\n-static inline void\n-unlink_vmdq(struct virtio_net *dev)\n-{\n-\tunsigned i = 0;\n-\tunsigned rx_count;\n-\tstruct rte_mbuf *pkts_burst[MAX_PKT_BURST];\n-\n-\tif (dev->ready == DEVICE_READY) {\n-\t\t/*clear MAC and VLAN settings*/\n-\t\trte_eth_dev_mac_addr_remove(ports[0], &dev->mac_address);\n-\t\tfor (i = 0; i < 6; i++)\n-\t\t\tdev->mac_address.addr_bytes[i] = 0;\n-\n-\t\tdev->vlan_tag = 0;\n-\n-\t\t/*Clear out the receive buffers*/\n-\t\trx_count = rte_eth_rx_burst(ports[0],\n-\t\t\t\t\t(uint16_t)dev->vmdq_rx_q, pkts_burst, MAX_PKT_BURST);\n-\n-\t\twhile (rx_count) {\n-\t\t\tfor (i = 0; i < rx_count; i++)\n-\t\t\t\trte_pktmbuf_free(pkts_burst[i]);\n-\n-\t\t\trx_count = rte_eth_rx_burst(ports[0],\n-\t\t\t\t\t(uint16_t)dev->vmdq_rx_q, pkts_burst, MAX_PKT_BURST);\n-\t\t}\n-\n-\t\tdev->ready = DEVICE_NOT_READY;\n-\t}\n-}\n-\n-/*\n- * Check if the packet destination MAC address is for a local device. If so then put\n- * the packet on that devices RX queue. If not then return.\n- */\n-static __rte_always_inline unsigned\n-virtio_tx_local(struct virtio_net *dev, struct rte_mbuf *m)\n-{\n-\tstruct virtio_net_data_ll *dev_ll;\n-\tstruct ether_hdr *pkt_hdr;\n-\tuint64_t ret = 0;\n-\n-\tpkt_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);\n-\n-\t/*get the used devices list*/\n-\tdev_ll = ll_root_used;\n-\n-\twhile (dev_ll != NULL) {\n-\t\tif (likely(dev_ll->dev->ready == DEVICE_READY) && ether_addr_cmp(&(pkt_hdr->d_addr),\n-\t\t\t\t          &dev_ll->dev->mac_address)) {\n-\n-\t\t\t/* Drop the packet if the TX packet is destined for the TX device. */\n-\t\t\tif (dev_ll->dev->device_fh == dev->device_fh) {\n-\t\t\t\tRTE_LOG_DP(DEBUG, VHOST_DATA, \"(%\" PRIu64 \") TX: \"\n-\t\t\t\t\t\"Source and destination MAC addresses are the same. \"\n-\t\t\t\t\t\"Dropping packet.\\n\",\n-\t\t\t\t\tdev_ll->dev->device_fh);\n-\t\t\t\treturn 0;\n-\t\t\t}\n-\n-\n-\t\t\tRTE_LOG_DP(DEBUG, VHOST_DATA, \"(%\" PRIu64 \") TX: \"\n-\t\t\t\t\"MAC address is local\\n\", dev_ll->dev->device_fh);\n-\n-\t\t\tif (dev_ll->dev->remove) {\n-\t\t\t\t/*drop the packet if the device is marked for removal*/\n-\t\t\t\tRTE_LOG_DP(DEBUG, VHOST_DATA, \"(%\" PRIu64 \") \"\n-\t\t\t\t\t\"Device is marked for removal\\n\",\n-\t\t\t\t\tdev_ll->dev->device_fh);\n-\t\t\t} else {\n-\t\t\t\t/*send the packet to the local virtio device*/\n-\t\t\t\tret = virtio_dev_rx(dev_ll->dev, &m, 1);\n-\t\t\t\tif (enable_stats) {\n-\t\t\t\t\trte_atomic64_add(&dev_statistics[dev_ll->dev->device_fh].rx_total, 1);\n-\t\t\t\t\trte_atomic64_add(&dev_statistics[dev_ll->dev->device_fh].rx, ret);\n-\t\t\t\t\tdev_statistics[dev->device_fh].tx_total++;\n-\t\t\t\t\tdev_statistics[dev->device_fh].tx += ret;\n-\t\t\t\t}\n-\t\t\t}\n-\n-\t\t\treturn 0;\n-\t\t}\n-\t\tdev_ll = dev_ll->next;\n-\t}\n-\n-\treturn -1;\n-}\n-\n-/*\n- * This function routes the TX packet to the correct interface. This may be a local device\n- * or the physical port.\n- */\n-static __rte_always_inline void\n-virtio_tx_route(struct virtio_net* dev, struct rte_mbuf *m, struct rte_mempool *mbuf_pool, uint16_t vlan_tag)\n-{\n-\tstruct mbuf_table *tx_q;\n-\tstruct vlan_ethhdr *vlan_hdr;\n-\tstruct rte_mbuf **m_table;\n-\tstruct rte_mbuf *mbuf;\n-\tunsigned len, ret;\n-\tconst uint16_t lcore_id = rte_lcore_id();\n-\n-\t/*check if destination is local VM*/\n-\tif (enable_vm2vm && (virtio_tx_local(dev, m) == 0)) {\n-\t\treturn;\n-\t}\n-\n-\tRTE_LOG_DP(DEBUG, VHOST_DATA, \"(%\" PRIu64 \") TX: \"\n-\t\t\"MAC address is external\\n\", dev->device_fh);\n-\n-\t/*Add packet to the port tx queue*/\n-\ttx_q = &lcore_tx_queue[lcore_id];\n-\tlen = tx_q->len;\n-\n-\t/* Allocate an mbuf and populate the structure. */\n-\tmbuf = rte_pktmbuf_alloc(mbuf_pool);\n-\tif(!mbuf)\n-\t\treturn;\n-\n-\tmbuf->data_len = m->data_len + VLAN_HLEN;\n-\tmbuf->pkt_len = mbuf->data_len;\n-\n-\t/* Copy ethernet header to mbuf. */\n-\trte_memcpy(rte_pktmbuf_mtod(mbuf, void*),\n-\t\t\trte_pktmbuf_mtod(m, const void*), ETH_HLEN);\n-\n-\n-\t/* Setup vlan header. Bytes need to be re-ordered for network with htons()*/\n-\tvlan_hdr = rte_pktmbuf_mtod(mbuf, struct vlan_ethhdr *);\n-\tvlan_hdr->h_vlan_encapsulated_proto = vlan_hdr->h_vlan_proto;\n-\tvlan_hdr->h_vlan_proto = htons(ETH_P_8021Q);\n-\tvlan_hdr->h_vlan_TCI = htons(vlan_tag);\n-\n-\t/* Copy the remaining packet contents to the mbuf. */\n-\trte_memcpy(rte_pktmbuf_mtod_offset(mbuf, void *, VLAN_ETH_HLEN),\n-\t\trte_pktmbuf_mtod_offset(m, const void *, ETH_HLEN),\n-\t\t(m->data_len - ETH_HLEN));\n-\ttx_q->m_table[len] = mbuf;\n-\tlen++;\n-\tif (enable_stats) {\n-\t\tdev_statistics[dev->device_fh].tx_total++;\n-\t\tdev_statistics[dev->device_fh].tx++;\n-\t}\n-\n-\tif (unlikely(len == MAX_PKT_BURST)) {\n-\t\tm_table = (struct rte_mbuf **)tx_q->m_table;\n-\t\tret = rte_eth_tx_burst(ports[0], (uint16_t)tx_q->txq_id, m_table, (uint16_t) len);\n-\t\t/* Free any buffers not handled by TX and update the port stats. */\n-\t\tif (unlikely(ret < len)) {\n-\t\t\tdo {\n-\t\t\t\trte_pktmbuf_free(m_table[ret]);\n-\t\t\t} while (++ret < len);\n-\t\t}\n-\n-\t\tlen = 0;\n-\t}\n-\n-\ttx_q->len = len;\n-\treturn;\n-}\n-\n-static __rte_always_inline void\n-virtio_dev_tx(struct virtio_net* dev, struct rte_mempool *mbuf_pool)\n-{\n-\tstruct rte_mbuf m;\n-\tstruct vhost_virtqueue *vq;\n-\tstruct vring_desc *desc;\n-\tuint64_t buff_addr = 0;\n-\tuint32_t head[MAX_PKT_BURST];\n-\tuint32_t used_idx;\n-\tuint32_t i;\n-\tuint16_t free_entries, packet_success = 0;\n-\tuint16_t avail_idx;\n-\n-\tvq = dev->virtqueue_tx;\n-\tavail_idx = *((volatile uint16_t *)&vq->avail->idx);\n-\n-\t/* If there are no available buffers then return. */\n-\tif (vq->last_used_idx == avail_idx)\n-\t\treturn;\n-\n-\tRTE_LOG_DP(DEBUG, VHOST_DATA, \"(%\" PRIu64 \") virtio_dev_tx()\\n\",\n-\t\tdev->device_fh);\n-\n-\t/* Prefetch available ring to retrieve head indexes. */\n-\trte_prefetch0(&vq->avail->ring[vq->last_used_idx & (vq->size - 1)]);\n-\n-\t/*get the number of free entries in the ring*/\n-\tfree_entries = avail_idx - vq->last_used_idx;\n-\tfree_entries = unlikely(free_entries < MAX_PKT_BURST) ? free_entries : MAX_PKT_BURST;\n-\n-\tRTE_LOG_DP(DEBUG, VHOST_DATA, \"(%\" PRIu64 \") Buffers available %d\\n\",\n-\t\tdev->device_fh, free_entries);\n-\t/* Retrieve all of the head indexes first to avoid caching issues. */\n-\tfor (i = 0; i < free_entries; i++)\n-\t\thead[i] = vq->avail->ring[(vq->last_used_idx + i) & (vq->size - 1)];\n-\n-\t/* Prefetch descriptor index. */\n-\trte_prefetch0(&vq->desc[head[packet_success]]);\n-\n-\twhile (packet_success < free_entries) {\n-\t\tdesc = &vq->desc[head[packet_success]];\n-\t\t/* Prefetch descriptor address. */\n-\t\trte_prefetch0(desc);\n-\n-\t\tif (packet_success < (free_entries - 1)) {\n-\t\t\t/* Prefetch descriptor index. */\n-\t\t\trte_prefetch0(&vq->desc[head[packet_success+1]]);\n-\t\t}\n-\n-\t\t/* Update used index buffer information. */\n-\t\tused_idx = vq->last_used_idx & (vq->size - 1);\n-\t\tvq->used->ring[used_idx].id = head[packet_success];\n-\t\tvq->used->ring[used_idx].len = 0;\n-\n-\t\t/* Discard first buffer as it is the virtio header */\n-\t\tdesc = &vq->desc[desc->next];\n-\n-\t\t/* Buffer address translation. */\n-\t\tbuff_addr = gpa_to_vva(dev, desc->addr);\n-\t\t/* Prefetch buffer address. */\n-\t\trte_prefetch0((void*)(uintptr_t)buff_addr);\n-\n-\t\t/* Setup dummy mbuf. This is copied to a real mbuf if transmitted out the physical port. */\n-\t\tm.data_len = desc->len;\n-\t\tm.data_off = 0;\n-\t\tm.nb_segs = 1;\n-\n-\t\tvirtio_tx_route(dev, &m, mbuf_pool, 0);\n-\n-\t\tvq->last_used_idx++;\n-\t\tpacket_success++;\n-\t}\n-\n-\trte_compiler_barrier();\n-\tvq->used->idx += packet_success;\n-\t/* Kick guest if required. */\n-}\n-\n-/*\n- * This function is called by each data core. It handles all RX/TX registered with the\n- * core. For TX the specific lcore linked list is used. For RX, MAC addresses are compared\n- * with all devices in the main linked list.\n- */\n-static int\n-switch_worker(__attribute__((unused)) void *arg)\n-{\n-\tstruct rte_mempool *mbuf_pool = arg;\n-\tstruct virtio_net *dev = NULL;\n-\tstruct rte_mbuf *pkts_burst[MAX_PKT_BURST];\n-\tstruct virtio_net_data_ll *dev_ll;\n-\tstruct mbuf_table *tx_q;\n-\tvolatile struct lcore_ll_info *lcore_ll;\n-\tconst uint64_t drain_tsc = (rte_get_tsc_hz() + US_PER_S - 1) / US_PER_S * BURST_TX_DRAIN_US;\n-\tuint64_t prev_tsc, diff_tsc, cur_tsc, ret_count = 0;\n-\tunsigned ret, i;\n-\tconst uint16_t lcore_id = rte_lcore_id();\n-\tconst uint16_t num_cores = (uint16_t)rte_lcore_count();\n-\tuint16_t rx_count = 0;\n-\n-\tRTE_LOG(INFO, VHOST_DATA, \"Procesing on Core %u started \\n\", lcore_id);\n-\tlcore_ll = lcore_info[lcore_id].lcore_ll;\n-\tprev_tsc = 0;\n-\n-\ttx_q = &lcore_tx_queue[lcore_id];\n-\tfor (i = 0; i < num_cores; i ++) {\n-\t\tif (lcore_ids[i] == lcore_id) {\n-\t\t\ttx_q->txq_id = i;\n-\t\t\tbreak;\n-\t\t}\n-\t}\n-\n-\twhile(1) {\n-\t\tcur_tsc = rte_rdtsc();\n-\t\t/*\n-\t\t * TX 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\tif (tx_q->len) {\n-\t\t\t\tRTE_LOG_DP(DEBUG, VHOST_DATA,\n-\t\t\t\t\t\"TX queue drained after timeout with burst size %u\\n\",\n-\t\t\t\t\ttx_q->len);\n-\n-\t\t\t\t/*Tx any packets in the queue*/\n-\t\t\t\tret = rte_eth_tx_burst(ports[0], (uint16_t)tx_q->txq_id,\n-\t\t\t\t\t\t\t\t\t   (struct rte_mbuf **)tx_q->m_table,\n-\t\t\t\t\t\t\t\t\t   (uint16_t)tx_q->len);\n-\t\t\t\tif (unlikely(ret < tx_q->len)) {\n-\t\t\t\t\tdo {\n-\t\t\t\t\t\trte_pktmbuf_free(tx_q->m_table[ret]);\n-\t\t\t\t\t} while (++ret < tx_q->len);\n-\t\t\t\t}\n-\n-\t\t\t\ttx_q->len = 0;\n-\t\t\t}\n-\n-\t\t\tprev_tsc = cur_tsc;\n-\n-\t\t}\n-\n-\t\t/*\n-\t\t * Inform the configuration core that we have exited the linked list and that no devices are\n-\t\t * in use if requested.\n-\t\t */\n-\t\tif (lcore_ll->dev_removal_flag == REQUEST_DEV_REMOVAL)\n-\t\t\tlcore_ll->dev_removal_flag = ACK_DEV_REMOVAL;\n-\n-\t\t/*\n-\t\t * Process devices\n-\t \t */\n-\t\tdev_ll = lcore_ll->ll_root_used;\n-\n-\t\twhile (dev_ll != NULL) {\n-\t\t\t/*get virtio device ID*/\n-\t\t\tdev = dev_ll->dev;\n-\n-\t\t\tif (unlikely(dev->remove)) {\n-\t\t\t\tdev_ll = dev_ll->next;\n-\t\t\t\tunlink_vmdq(dev);\n-\t\t\t\tdev->ready = DEVICE_SAFE_REMOVE;\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (likely(dev->ready == DEVICE_READY)) {\n-\t\t\t\t/*Handle guest RX*/\n-\t\t\t\trx_count = rte_eth_rx_burst(ports[0],\n-\t\t\t\t\t(uint16_t)dev->vmdq_rx_q, pkts_burst, MAX_PKT_BURST);\n-\n-\t\t\t\tif (rx_count) {\n-\t\t\t\t\tret_count = virtio_dev_rx(dev, pkts_burst, rx_count);\n-\t\t\t\t\tif (enable_stats) {\n-\t\t\t\t\t\trte_atomic64_add(&dev_statistics[dev_ll->dev->device_fh].rx_total, rx_count);\n-\t\t\t\t\t\trte_atomic64_add(&dev_statistics[dev_ll->dev->device_fh].rx, ret_count);\n-\t\t\t\t\t}\n-\t\t\t\t\twhile (likely(rx_count)) {\n-\t\t\t\t\t\trx_count--;\n-\t\t\t\t\t\trte_pktmbuf_free_seg(pkts_burst[rx_count]);\n-\t\t\t\t\t}\n-\n-\t\t\t\t}\n-\t\t\t}\n-\n-\t\t\tif (likely(!dev->remove))\n-\t\t\t\t/*Handle guest TX*/\n-\t\t\t\tvirtio_dev_tx(dev, mbuf_pool);\n-\n-\t\t\t/*move to the next device in the list*/\n-\t\t\tdev_ll = dev_ll->next;\n-\t\t}\n-\t}\n-\n-\treturn 0;\n-}\n-\n-/*\n- * Add an entry to a used linked list. A free entry must first be found in the free linked list\n- * using get_data_ll_free_entry();\n- */\n-static void\n-add_data_ll_entry(struct virtio_net_data_ll **ll_root_addr, struct virtio_net_data_ll *ll_dev)\n-{\n-\tstruct virtio_net_data_ll *ll = *ll_root_addr;\n-\n-\t/* Set next as NULL and use a compiler barrier to avoid reordering. */\n-\tll_dev->next = NULL;\n-\trte_compiler_barrier();\n-\n-\t/* If ll == NULL then this is the first device. */\n-\tif (ll) {\n-\t\t/* Increment to the tail of the linked list. */\n-\t\twhile ((ll->next != NULL) )\n-\t\t\tll = ll->next;\n-\n-\t\tll->next = ll_dev;\n-\t} else {\n-\t\t*ll_root_addr = ll_dev;\n-\t}\n-}\n-\n-/*\n- * Remove an entry from a used linked list. The entry must then be added to the free linked list\n- * using put_data_ll_free_entry().\n- */\n-static void\n-rm_data_ll_entry(struct virtio_net_data_ll **ll_root_addr, struct virtio_net_data_ll *ll_dev, struct virtio_net_data_ll *ll_dev_last)\n-{\n-\tstruct virtio_net_data_ll *ll = *ll_root_addr;\n-\n-\tif (ll_dev == ll)\n-\t\t*ll_root_addr = ll_dev->next;\n-\telse\n-\t\tll_dev_last->next = ll_dev->next;\n-}\n-\n-/*\n- * Find and return an entry from the free linked list.\n- */\n-static struct virtio_net_data_ll *\n-get_data_ll_free_entry(struct virtio_net_data_ll **ll_root_addr)\n-{\n-\tstruct virtio_net_data_ll *ll_free = *ll_root_addr;\n-\tstruct virtio_net_data_ll *ll_dev;\n-\n-\tif (ll_free == NULL)\n-\t\treturn NULL;\n-\n-\tll_dev = ll_free;\n-\t*ll_root_addr = ll_free->next;\n-\n-\treturn ll_dev;\n-}\n-\n-/*\n- * Place an entry back on to the free linked list.\n- */\n-static void\n-put_data_ll_free_entry(struct virtio_net_data_ll **ll_root_addr, struct virtio_net_data_ll *ll_dev)\n-{\n-\tstruct virtio_net_data_ll *ll_free = *ll_root_addr;\n-\n-\tll_dev->next = ll_free;\n-\t*ll_root_addr = ll_dev;\n-}\n-\n-/*\n- * Creates a linked list of a given size.\n- */\n-static struct virtio_net_data_ll *\n-alloc_data_ll(uint32_t size)\n-{\n-\tstruct virtio_net_data_ll *ll_new;\n-\tuint32_t i;\n-\n-\t/* Malloc and then chain the linked list. */\n-\tll_new = malloc(size * sizeof(struct virtio_net_data_ll));\n-\tif (ll_new == NULL) {\n-\t\tRTE_LOG(ERR, VHOST_CONFIG, \"Failed to allocate memory for ll_new.\\n\");\n-\t\treturn NULL;\n-\t}\n-\n-\tfor (i = 0; i < size - 1; i++) {\n-\t\tll_new[i].dev = NULL;\n-\t\tll_new[i].next = &ll_new[i+1];\n-\t}\n-\tll_new[i].next = NULL;\n-\n-\treturn ll_new;\n-}\n-\n-/*\n- * Create the main linked list along with each individual cores linked list. A used and a free list\n- * are created to manage entries.\n- */\n-static int\n-init_data_ll (void)\n-{\n-\tint lcore;\n-\n-\tRTE_LCORE_FOREACH_SLAVE(lcore) {\n-\t\tlcore_info[lcore].lcore_ll = malloc(sizeof(struct lcore_ll_info));\n-\t\tif (lcore_info[lcore].lcore_ll == NULL) {\n-\t\t\tRTE_LOG(ERR, VHOST_CONFIG, \"Failed to allocate memory for lcore_ll.\\n\");\n-\t\t\treturn -1;\n-\t\t}\n-\n-\t\tlcore_info[lcore].lcore_ll->device_num = 0;\n-\t\tlcore_info[lcore].lcore_ll->dev_removal_flag = ACK_DEV_REMOVAL;\n-\t\tlcore_info[lcore].lcore_ll->ll_root_used = NULL;\n-\t\tif (num_devices % num_switching_cores)\n-\t\t\tlcore_info[lcore].lcore_ll->ll_root_free = alloc_data_ll((num_devices / num_switching_cores) + 1);\n-\t\telse\n-\t\t\tlcore_info[lcore].lcore_ll->ll_root_free = alloc_data_ll(num_devices / num_switching_cores);\n-\t}\n-\n-\t/* Allocate devices up to a maximum of MAX_DEVICES. */\n-\tll_root_free = alloc_data_ll(MIN((num_devices), MAX_DEVICES));\n-\n-\treturn 0;\n-}\n-/*\n- * Remove a device from the specific data core linked list and from the main linked list. The\n- * rx/tx thread must be set the flag to indicate that it is safe to remove the device.\n- * used.\n- */\n-static void\n-destroy_device (volatile struct virtio_net *dev)\n-{\n-\tstruct virtio_net_data_ll *ll_lcore_dev_cur;\n-\tstruct virtio_net_data_ll *ll_main_dev_cur;\n-\tstruct virtio_net_data_ll *ll_lcore_dev_last = NULL;\n-\tstruct virtio_net_data_ll *ll_main_dev_last = NULL;\n-\tint lcore;\n-\n-\tdev->flags &= ~VIRTIO_DEV_RUNNING;\n-\n-\t/*set the remove flag. */\n-\tdev->remove = 1;\n-\n-\twhile(dev->ready != DEVICE_SAFE_REMOVE) {\n-\t\trte_pause();\n-\t}\n-\n-\t/* Search for entry to be removed from lcore ll */\n-\tll_lcore_dev_cur = lcore_info[dev->coreid].lcore_ll->ll_root_used;\n-\twhile (ll_lcore_dev_cur != NULL) {\n-\t\tif (ll_lcore_dev_cur->dev == dev) {\n-\t\t\tbreak;\n-\t\t} else {\n-\t\t\tll_lcore_dev_last = ll_lcore_dev_cur;\n-\t\t\tll_lcore_dev_cur = ll_lcore_dev_cur->next;\n-\t\t}\n-\t}\n-\n-\t/* Search for entry to be removed from main ll */\n-\tll_main_dev_cur = ll_root_used;\n-\tll_main_dev_last = NULL;\n-\twhile (ll_main_dev_cur != NULL) {\n-\t\tif (ll_main_dev_cur->dev == dev) {\n-\t\t\tbreak;\n-\t\t} else {\n-\t\t\tll_main_dev_last = ll_main_dev_cur;\n-\t\t\tll_main_dev_cur = ll_main_dev_cur->next;\n-\t\t}\n-\t}\n-\n-\tif (ll_lcore_dev_cur == NULL || ll_main_dev_cur == NULL) {\n-\t\tRTE_LOG(ERR, XENHOST, \"%s: could find device in per_cpu list or main_list\\n\", __func__);\n-\t\treturn;\n-\t}\n-\n-\t/* Remove entries from the lcore and main ll. */\n-\trm_data_ll_entry(&lcore_info[ll_lcore_dev_cur->dev->coreid].lcore_ll->ll_root_used, ll_lcore_dev_cur, ll_lcore_dev_last);\n-\trm_data_ll_entry(&ll_root_used, ll_main_dev_cur, ll_main_dev_last);\n-\n-\t/* Set the dev_removal_flag on each lcore. */\n-\tRTE_LCORE_FOREACH_SLAVE(lcore) {\n-\t\tlcore_info[lcore].lcore_ll->dev_removal_flag = REQUEST_DEV_REMOVAL;\n-\t}\n-\n-\t/*\n-\t * Once each core has set the dev_removal_flag to ACK_DEV_REMOVAL we can be sure that\n-\t * they can no longer access the device removed from the linked lists and that the devices\n-\t * are no longer in use.\n-\t */\n-\tRTE_LCORE_FOREACH_SLAVE(lcore) {\n-\t\twhile (lcore_info[lcore].lcore_ll->dev_removal_flag != ACK_DEV_REMOVAL) {\n-\t\t\trte_pause();\n-\t\t}\n-\t}\n-\n-\t/* Add the entries back to the lcore and main free ll.*/\n-\tput_data_ll_free_entry(&lcore_info[ll_lcore_dev_cur->dev->coreid].lcore_ll->ll_root_free, ll_lcore_dev_cur);\n-\tput_data_ll_free_entry(&ll_root_free, ll_main_dev_cur);\n-\n-\t/* Decrement number of device on the lcore. */\n-\tlcore_info[ll_lcore_dev_cur->dev->coreid].lcore_ll->device_num--;\n-\n-\tRTE_LOG(INFO, VHOST_DATA, \"  #####(%\"PRIu64\") Device has been removed from data core\\n\", dev->device_fh);\n-}\n-\n-/*\n- * A new device is added to a data core. First the device is added to the main linked list\n- * and the allocated to a specific data core.\n- */\n-static int\n-new_device (struct virtio_net *dev)\n-{\n-\tstruct virtio_net_data_ll *ll_dev;\n-\tint lcore, core_add = 0;\n-\tuint32_t device_num_min = num_devices;\n-\n-\t/* Add device to main ll */\n-\tll_dev = get_data_ll_free_entry(&ll_root_free);\n-\tif (ll_dev == NULL) {\n-\t\tRTE_LOG(INFO, VHOST_DATA, \"(%\"PRIu64\") No free entry found in linked list. Device limit \"\n-\t\t\t\"of %d devices per core has been reached\\n\",\n-\t\t\tdev->device_fh, num_devices);\n-\t\treturn -1;\n-\t}\n-\tll_dev->dev = dev;\n-\tadd_data_ll_entry(&ll_root_used, ll_dev);\n-\n-\t/*reset ready flag*/\n-\tdev->ready = DEVICE_NOT_READY;\n-\tdev->remove = 0;\n-\n-\t/* Find a suitable lcore to add the device. */\n-\tRTE_LCORE_FOREACH_SLAVE(lcore) {\n-\t\tif (lcore_info[lcore].lcore_ll->device_num < device_num_min) {\n-\t\t\tdevice_num_min = lcore_info[lcore].lcore_ll->device_num;\n-\t\t\tcore_add = lcore;\n-\t\t}\n-\t}\n-\t/* Add device to lcore ll */\n-\tll_dev->dev->coreid = core_add;\n-\tll_dev = get_data_ll_free_entry(&lcore_info[ll_dev->dev->coreid].lcore_ll->ll_root_free);\n-\tif (ll_dev == NULL) {\n-\t\tRTE_LOG(INFO, VHOST_DATA, \"(%\"PRIu64\") Failed to add device to data core\\n\", dev->device_fh);\n-\t\tdestroy_device(dev);\n-\t\treturn -1;\n-\t}\n-\tll_dev->dev = dev;\n-\tadd_data_ll_entry(&lcore_info[ll_dev->dev->coreid].lcore_ll->ll_root_used, ll_dev);\n-\n-\t/* Initialize device stats */\n-\tmemset(&dev_statistics[dev->device_fh], 0, sizeof(struct device_statistics));\n-\n-\tlcore_info[ll_dev->dev->coreid].lcore_ll->device_num++;\n-\tdev->flags |= VIRTIO_DEV_RUNNING;\n-\n-\tRTE_LOG(INFO, VHOST_DATA, \"(%\"PRIu64\") Device has been added to data core %d\\n\", dev->device_fh, dev->coreid);\n-\n-\tlink_vmdq(dev);\n-\n-\treturn 0;\n-}\n-\n-/*\n- * These callback allow devices to be added to the data core when configuration\n- * has been fully complete.\n- */\n-static const struct virtio_net_device_ops virtio_net_device_ops =\n-{\n-\t.new_device =  new_device,\n-\t.destroy_device = destroy_device,\n-};\n-\n-/*\n- * This is a thread will wake up after a period to print stats if the user has\n- * enabled them.\n- */\n-static void\n-print_stats(void)\n-{\n-\tstruct virtio_net_data_ll *dev_ll;\n-\tuint64_t tx_dropped, rx_dropped;\n-\tuint64_t tx, tx_total, rx, rx_total;\n-\tuint32_t device_fh;\n-\tconst char clr[] = { 27, '[', '2', 'J', '\\0' };\n-\tconst char top_left[] = { 27, '[', '1', ';', '1', 'H','\\0' };\n-\n-\twhile(1) {\n-\t\tsleep(enable_stats);\n-\n-\t\t/* Clear screen and move to top left */\n-\t\tprintf(\"%s%s\", clr, top_left);\n-\n-\t\tprintf(\"\\nDevice statistics ====================================\");\n-\n-\t\tdev_ll = ll_root_used;\n-\t\twhile (dev_ll != NULL) {\n-\t\t\tdevice_fh = (uint32_t)dev_ll->dev->device_fh;\n-\t\t\ttx_total = dev_statistics[device_fh].tx_total;\n-\t\t\ttx = dev_statistics[device_fh].tx;\n-\t\t\ttx_dropped = tx_total - tx;\n-\t\t\trx_total = rte_atomic64_read(&dev_statistics[device_fh].rx_total);\n-\t\t\trx = rte_atomic64_read(&dev_statistics[device_fh].rx);\n-\t\t\trx_dropped = rx_total - rx;\n-\n-\t\t\tprintf(\"\\nStatistics for device %\"PRIu32\" ------------------------------\"\n-\t\t\t\t\t\"\\nTX total: \t\t%\"PRIu64\"\"\n-\t\t\t\t\t\"\\nTX dropped: \t\t%\"PRIu64\"\"\n-\t\t\t\t\t\"\\nTX successful: \t\t%\"PRIu64\"\"\n-\t\t\t\t\t\"\\nRX total: \t\t%\"PRIu64\"\"\n-\t\t\t\t\t\"\\nRX dropped: \t\t%\"PRIu64\"\"\n-\t\t\t\t\t\"\\nRX successful: \t\t%\"PRIu64\"\",\n-\t\t\t\t\tdevice_fh,\n-\t\t\t\t\ttx_total,\n-\t\t\t\t\ttx_dropped,\n-\t\t\t\t\ttx,\n-\t\t\t\t\trx_total,\n-\t\t\t\t\trx_dropped,\n-\t\t\t\t\trx);\n-\n-\t\t\tdev_ll = dev_ll->next;\n-\t\t}\n-\t\tprintf(\"\\n======================================================\\n\");\n-\t}\n-}\n-\n-\n-int init_virtio_net(struct virtio_net_device_ops const * const ops);\n-\n-/*\n- * Main function, does initialisation and calls the per-lcore functions.\n- */\n-int\n-main(int argc, char *argv[])\n-{\n-\tstruct rte_mempool *mbuf_pool;\n-\tunsigned lcore_id, core_id = 0;\n-\tunsigned nb_ports, valid_num_ports;\n-\tint ret;\n-\tuint8_t portid;\n-\tstatic pthread_t tid;\n-\tchar thread_name[RTE_MAX_THREAD_NAME_LEN];\n-\n-\t/* init EAL */\n-\tret = rte_eal_init(argc, argv);\n-\tif (ret < 0)\n-\t\trte_exit(EXIT_FAILURE, \"Error with EAL initialization\\n\");\n-\targc -= ret;\n-\targv += ret;\n-\n-\t/* parse app arguments */\n-\tret = us_vhost_parse_args(argc, argv);\n-\tif (ret < 0)\n-\t\trte_exit(EXIT_FAILURE, \"Invalid argument\\n\");\n-\n-\tfor (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id ++)\n-\t\tif (rte_lcore_is_enabled(lcore_id))\n-\t\t\tlcore_ids[core_id ++] = lcore_id;\n-\n-\tif (rte_lcore_count() > RTE_MAX_LCORE)\n-\t\trte_exit(EXIT_FAILURE,\"Not enough cores\\n\");\n-\n-\t/*set the number of swithcing cores available*/\n-\tnum_switching_cores = rte_lcore_count()-1;\n-\n-\t/* Get the number of physical ports. */\n-\tnb_ports = rte_eth_dev_count();\n-\n-\t/*\n-\t * Update the global var NUM_PORTS and global array PORTS\n-\t * and get value of var VALID_NUM_PORTS according to system ports number\n-\t */\n-\tvalid_num_ports = check_ports_num(nb_ports);\n-\n-\tif ((valid_num_ports ==  0) || (valid_num_ports > MAX_SUP_PORTS)) {\n-\t\tRTE_LOG(INFO, VHOST_PORT, \"Current enabled port number is %u,\"\n-\t\t\t\"but only %u port can be enabled\\n\",num_ports, MAX_SUP_PORTS);\n-\t\treturn -1;\n-\t}\n-\n-\t/* Create the mbuf pool. */\n-\tmbuf_pool = rte_pktmbuf_pool_create(\"MBUF_POOL\",\n-\t\tNUM_MBUFS_PER_PORT * valid_num_ports, MBUF_CACHE_SIZE, 0,\n-\t\tRTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());\n-\tif (mbuf_pool == NULL)\n-\t\trte_exit(EXIT_FAILURE, \"Cannot create mbuf pool\\n\");\n-\n-\t/* initialize all ports */\n-\tfor (portid = 0; portid < nb_ports; portid++) {\n-\t\t/* skip ports that are not enabled */\n-\t\tif ((enabled_port_mask & (1 << portid)) == 0) {\n-\t\t\tRTE_LOG(INFO, VHOST_PORT, \"Skipping disabled port %d\\n\", portid);\n-\t\t\tcontinue;\n-\t\t}\n-\t\tif (port_init(portid, mbuf_pool) != 0)\n-\t\t\trte_exit(EXIT_FAILURE, \"Cannot initialize network ports\\n\");\n-\t}\n-\n-\t/* Initialise all linked lists. */\n-\tif (init_data_ll() == -1)\n-\t\trte_exit(EXIT_FAILURE, \"Failed to initialize linked list\\n\");\n-\n-\t/* Initialize device stats */\n-\tmemset(&dev_statistics, 0, sizeof(dev_statistics));\n-\n-\t/* Enable stats if the user option is set. */\n-\tif (enable_stats) {\n-\t\tret = pthread_create(&tid, NULL, (void *)print_stats, NULL);\n-\t\tif (ret != 0)\n-\t\t\trte_exit(EXIT_FAILURE,\n-\t\t\t\t\"Cannot create print-stats thread\\n\");\n-\n-\t\t/* Set thread_name for aid in debugging. */\n-\t\tsnprintf(thread_name, RTE_MAX_THREAD_NAME_LEN, \"print-xen-stats\");\n-\t\tret = rte_thread_setname(tid, thread_name);\n-\t\tif (ret != 0)\n-\t\t\tRTE_LOG(DEBUG, VHOST_CONFIG,\n-\t\t\t\t\"Cannot set print-stats name\\n\");\n-\t}\n-\n-\t/* Launch all data cores. */\n-\tRTE_LCORE_FOREACH_SLAVE(lcore_id) {\n-\t\trte_eal_remote_launch(switch_worker, mbuf_pool, lcore_id);\n-\t}\n-\n-\tinit_virtio_xen(&virtio_net_device_ops);\n-\n-\tvirtio_monitor_loop();\n-\treturn 0;\n-}\ndiff --git a/examples/vhost_xen/main.h b/examples/vhost_xen/main.h\ndeleted file mode 100644\nindex 5ff48fd..0000000\n--- a/examples/vhost_xen/main.h\n+++ /dev/null\n@@ -1,66 +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 _MAIN_H_\n-#define _MAIN_H_\n-\n-/* Macros for printing using RTE_LOG */\n-#define RTE_LOGTYPE_VHOST_CONFIG RTE_LOGTYPE_USER1\n-#define RTE_LOGTYPE_VHOST_DATA   RTE_LOGTYPE_USER2\n-#define RTE_LOGTYPE_VHOST_PORT   RTE_LOGTYPE_USER3\n-\n-/*\n- * Device linked list structure for data path.\n- */\n-struct virtio_net_data_ll\n-{\n-\tstruct virtio_net          *dev;   /* Pointer to device created by configuration core. */\n-\tstruct virtio_net_data_ll  *next;  /* Pointer to next device in linked list. */\n-};\n-\n-/*\n- * Structure containing data core specific information.\n- */\n-struct lcore_ll_info\n-{\n-\tstruct virtio_net_data_ll    *ll_root_free; \t/* Pointer to head in free linked list. */\n-\tstruct virtio_net_data_ll    *ll_root_used;\t    /* Pointer to head of used linked list. */\n-\tuint32_t                      device_num;       /* Number of devices on lcore. */\n-\tvolatile  uint8_t             dev_removal_flag; /* Flag to synchronize device removal. */\n-};\n-\n-struct lcore_info\n-{\n-\tstruct lcore_ll_info\t*lcore_ll;\t/* Pointer to data core specific lcore_ll_info struct */\n-};\n-#endif /* _MAIN_H_ */\ndiff --git a/examples/vhost_xen/vhost_monitor.c b/examples/vhost_xen/vhost_monitor.c\ndeleted file mode 100644\nindex fb9606b..0000000\n--- a/examples/vhost_xen/vhost_monitor.c\n+++ /dev/null\n@@ -1,595 +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 <stdlib.h>\n-#include <stdio.h>\n-#include <dirent.h>\n-#include <unistd.h>\n-#include <sys/eventfd.h>\n-#include <sys/ioctl.h>\n-#include <sys/mman.h>\n-#include <xen/xen-compat.h>\n-#if __XEN_LATEST_INTERFACE_VERSION__ < 0x00040200\n-#include <xs.h>\n-#else\n-#include <xenstore.h>\n-#endif\n-#include <linux/virtio_ring.h>\n-#include <linux/virtio_pci.h>\n-#include <linux/virtio_net.h>\n-\n-#include <rte_ethdev.h>\n-#include <rte_log.h>\n-#include <rte_malloc.h>\n-#include <rte_string_fns.h>\n-\n-#include \"virtio-net.h\"\n-#include \"xen_vhost.h\"\n-\n-struct virtio_watch {\n-\tstruct xs_handle *xs;\n-\tint watch_fd;\n-};\n-\n-\n-/* device ops to add/remove device to/from data core. */\n-static struct virtio_net_device_ops const *notify_ops;\n-\n-/* root address of the linked list in the configuration core. */\n-static struct virtio_net_config_ll *ll_root = NULL;\n-\n-/* root address of VM. */\n-static struct xen_guestlist guest_root;\n-\n-static struct virtio_watch watch;\n-\n-static void\n-vq_vring_init(struct vhost_virtqueue *vq, unsigned int num, uint8_t *p,\n-\tunsigned long align)\n-{\n-\tvq->size = num;\n-\tvq->desc = (struct vring_desc *) p;\n-\tvq->avail = (struct vring_avail *) (p +\n-\t\tnum * sizeof(struct vring_desc));\n-\tvq->used = (void *)\n-\t\tRTE_ALIGN_CEIL( (uintptr_t)(&vq->avail->ring[num]), align);\n-\n-}\n-\n-static int\n-init_watch(void)\n-{\n-\tstruct xs_handle *xs;\n-\tint ret;\n-\tint fd;\n-\n-\t/* get a connection to the daemon */\n-\txs = xs_daemon_open();\n-\tif (xs == NULL) {\n-\t\tRTE_LOG(ERR, XENHOST, \"xs_daemon_open failed\\n\");\n-\t\treturn -1;\n-\t}\n-\n-\tret = xs_watch(xs, \"/local/domain\", \"mytoken\");\n-\tif (ret == 0) {\n-\t\tRTE_LOG(ERR, XENHOST, \"%s: xs_watch failed\\n\", __func__);\n-\t\txs_daemon_close(xs);\n-\t\treturn -1;\n-\t}\n-\n-\t/* We are notified of read availability on the watch via the file descriptor. */\n-\tfd = xs_fileno(xs);\n-\twatch.xs = xs;\n-\twatch.watch_fd = fd;\n-\n-\tTAILQ_INIT(&guest_root);\n-\treturn 0;\n-}\n-\n-static struct xen_guest *\n-get_xen_guest(int dom_id)\n-{\n-\tstruct xen_guest *guest = NULL;\n-\n-\tTAILQ_FOREACH(guest, &guest_root, next) {\n-\t\tif(guest->dom_id == dom_id)\n-\t\t\treturn guest;\n-\t}\n-\n-\treturn NULL;\n-}\n-\n-\n-static struct xen_guest *\n-add_xen_guest(int32_t dom_id)\n-{\n-\tstruct xen_guest *guest = NULL;\n-\n-\tif ((guest = get_xen_guest(dom_id)) != NULL)\n-\t\treturn guest;\n-\n-\tguest = calloc(1, sizeof(struct xen_guest));\n-\tif (guest) {\n-\t\tRTE_LOG(ERR, XENHOST, \"  %s: return newly created guest with %d rings\\n\", __func__, guest->vring_num);\n-\t\tTAILQ_INSERT_TAIL(&guest_root, guest, next);\n-\t\tguest->dom_id = dom_id;\n-\t}\n-\n-\treturn guest;\n-}\n-\n-static void\n-cleanup_device(struct virtio_net_config_ll *ll_dev)\n-{\n-\tif (ll_dev == NULL)\n-\t\treturn;\n-\tif (ll_dev->dev.virtqueue_rx) {\n-\t\trte_free(ll_dev->dev.virtqueue_rx);\n-\t\tll_dev->dev.virtqueue_rx = NULL;\n-\t}\n-\tif (ll_dev->dev.virtqueue_tx) {\n-\t\trte_free(ll_dev->dev.virtqueue_tx);\n-\t\tll_dev->dev.virtqueue_tx = NULL;\n-\t}\n-\tfree(ll_dev);\n-}\n-\n-/*\n- * Add entry containing a device to the device configuration linked list.\n- */\n-static void\n-add_config_ll_entry(struct virtio_net_config_ll *new_ll_dev)\n-{\n-\tstruct virtio_net_config_ll *ll_dev = ll_root;\n-\n-\t/* If ll_dev == NULL then this is the first device so go to else */\n-\tif (ll_dev) {\n-\t\t/* If the 1st device_id != 0 then we insert our device here. */\n-\t\tif (ll_dev->dev.device_fh != 0)\t{\n-\t\t\tnew_ll_dev->dev.device_fh = 0;\n-\t\t\tnew_ll_dev->next = ll_dev;\n-\t\t\tll_root = new_ll_dev;\n-\t\t} else {\n-\t\t\t/* increment through the ll until we find un unused device_id,\n-\t\t\t * insert the device at that entry\n-\t\t\t */\n-\t\t\twhile ((ll_dev->next != NULL) && (ll_dev->dev.device_fh == (ll_dev->next->dev.device_fh - 1)))\n-\t\t\t\tll_dev = ll_dev->next;\n-\n-\t\t\tnew_ll_dev->dev.device_fh = ll_dev->dev.device_fh + 1;\n-\t\t\tnew_ll_dev->next = ll_dev->next;\n-\t\t\tll_dev->next = new_ll_dev;\n-\t\t}\n-\t} else {\n-\t\tll_root = new_ll_dev;\n-\t\tll_root->dev.device_fh = 0;\n-\t}\n-}\n-\n-\n-/*\n- * Remove an entry from the device configuration linked list.\n- */\n-static struct virtio_net_config_ll *\n-rm_config_ll_entry(struct virtio_net_config_ll *ll_dev, struct virtio_net_config_ll *ll_dev_last)\n-{\n-\t/* First remove the device and then clean it up. */\n-\tif (ll_dev == ll_root) {\n-\t\tll_root = ll_dev->next;\n-\t\tcleanup_device(ll_dev);\n-\t\treturn ll_root;\n-\t} else {\n-\t\tll_dev_last->next = ll_dev->next;\n-\t\tcleanup_device(ll_dev);\n-\t\treturn ll_dev_last->next;\n-\t}\n-}\n-\n-/*\n- * Retrieves an entry from the devices configuration linked list.\n- */\n-static struct virtio_net_config_ll *\n-get_config_ll_entry(unsigned int virtio_idx, unsigned int dom_id)\n-{\n-\tstruct virtio_net_config_ll *ll_dev = ll_root;\n-\n-\t/* Loop through linked list until the dom_id is found. */\n-\twhile (ll_dev != NULL) {\n-\t\tif (ll_dev->dev.dom_id == dom_id && ll_dev->dev.virtio_idx == virtio_idx)\n-\t\t\treturn ll_dev;\n-\t\tll_dev = ll_dev->next;\n-\t}\n-\n-\treturn NULL;\n-}\n-\n-/*\n- * Initialise all variables in device structure.\n- */\n-static void\n-init_dev(struct virtio_net *dev)\n-{\n-\tRTE_SET_USED(dev);\n-}\n-\n-\n-static struct\n-virtio_net_config_ll *new_device(unsigned int virtio_idx, struct xen_guest *guest)\n-{\n-\tstruct virtio_net_config_ll *new_ll_dev;\n-\tstruct vhost_virtqueue *virtqueue_rx, *virtqueue_tx;\n-\tsize_t size, vq_ring_size, vq_size = VQ_DESC_NUM;\n-\tvoid *vq_ring_virt_mem;\n-\tuint64_t gpa;\n-\tuint32_t i;\n-\n-\t/* Setup device and virtqueues. */\n-\tnew_ll_dev   = calloc(1, sizeof(struct virtio_net_config_ll));\n-\tvirtqueue_rx = rte_zmalloc(NULL, sizeof(struct vhost_virtqueue), RTE_CACHE_LINE_SIZE);\n-\tvirtqueue_tx = rte_zmalloc(NULL, sizeof(struct vhost_virtqueue), RTE_CACHE_LINE_SIZE);\n-\tif (new_ll_dev == NULL || virtqueue_rx == NULL || virtqueue_tx == NULL)\n-\t\tgoto err;\n-\n-\tnew_ll_dev->dev.virtqueue_rx = virtqueue_rx;\n-\tnew_ll_dev->dev.virtqueue_tx = virtqueue_tx;\n-\tnew_ll_dev->dev.dom_id       = guest->dom_id;\n-\tnew_ll_dev->dev.virtio_idx   = virtio_idx;\n-\t/* Initialise device and virtqueues. */\n-\tinit_dev(&new_ll_dev->dev);\n-\n-\tsize = vring_size(vq_size, VIRTIO_PCI_VRING_ALIGN);\n-\tvq_ring_size = RTE_ALIGN_CEIL(size, VIRTIO_PCI_VRING_ALIGN);\n-\t(void)vq_ring_size;\n-\n-\tvq_ring_virt_mem = guest->vring[virtio_idx].rxvring_addr;\n-\tvq_vring_init(virtqueue_rx, vq_size, vq_ring_virt_mem, VIRTIO_PCI_VRING_ALIGN);\n-\tvirtqueue_rx->size = vq_size;\n-\tvirtqueue_rx->vhost_hlen = sizeof(struct virtio_net_hdr);\n-\n-\tvq_ring_virt_mem = guest->vring[virtio_idx].txvring_addr;\n-\tvq_vring_init(virtqueue_tx, vq_size, vq_ring_virt_mem, VIRTIO_PCI_VRING_ALIGN);\n-\tvirtqueue_tx->size = vq_size;\n-\tmemcpy(&new_ll_dev->dev.mac_address, &guest->vring[virtio_idx].addr, sizeof(struct ether_addr));\n-\n-\t/* virtio_memory has to be one per domid */\n-\tnew_ll_dev->dev.mem = malloc(sizeof(struct virtio_memory) + sizeof(struct virtio_memory_regions) * MAX_XENVIRT_MEMPOOL);\n-\tnew_ll_dev->dev.mem->nregions = guest->pool_num;\n-\tfor (i = 0; i < guest->pool_num; i++) {\n-\t\tgpa = new_ll_dev->dev.mem->regions[i].guest_phys_address =\n-\t\t\t\t(uint64_t)((uintptr_t)guest->mempool[i].gva);\n-\t\tnew_ll_dev->dev.mem->regions[i].guest_phys_address_end =\n-\t\t\t\tgpa + guest->mempool[i].mempfn_num * getpagesize();\n-\t\tnew_ll_dev->dev.mem->regions[i].address_offset =\n-\t\t\t\t(uint64_t)((uintptr_t)guest->mempool[i].hva -\n-\t\t\t\t\t(uintptr_t)gpa);\n-\t}\n-\n-\tnew_ll_dev->next = NULL;\n-\n-\t/* Add entry to device configuration linked list. */\n-\tadd_config_ll_entry(new_ll_dev);\n-\treturn new_ll_dev;\n-err:\n-\tfree(new_ll_dev);\n-\trte_free(virtqueue_rx);\n-\trte_free(virtqueue_tx);\n-\n-\treturn NULL;\n-}\n-\n-static void\n-destroy_guest(struct xen_guest *guest)\n-{\n-\tuint32_t i;\n-\n-\tfor (i = 0; i < guest->vring_num; i++)\n-\t\tcleanup_vring(&guest->vring[i]);\n-\t/* clean mempool */\n-\tfor (i = 0; i < guest->pool_num; i++)\n-\t\tcleanup_mempool(&guest->mempool[i]);\n-\tfree(guest);\n-\n-\treturn;\n-}\n-\n-/*\n- * This function will cleanup the device and remove it from device configuration linked list.\n- */\n-static void\n-destroy_device(unsigned int virtio_idx, unsigned int dom_id)\n-{\n-\tstruct virtio_net_config_ll *ll_dev_cur_ctx, *ll_dev_last = NULL;\n-\tstruct virtio_net_config_ll *ll_dev_cur = ll_root;\n-\n-\t/* clean virtio device */\n-\tstruct xen_guest *guest = NULL;\n-\tguest = get_xen_guest(dom_id);\n-\tif (guest == NULL)\n-\t\treturn;\n-\n-\t/* Find the linked list entry for the device to be removed. */\n-\tll_dev_cur_ctx = get_config_ll_entry(virtio_idx, dom_id);\n-\twhile (ll_dev_cur != NULL) {\n-\t\t/* If the device is found or a device that doesn't exist is found then it is removed. */\n-\t\tif  (ll_dev_cur == ll_dev_cur_ctx) {\n-\t\t\tif ((ll_dev_cur->dev.flags & VIRTIO_DEV_RUNNING))\n-\t\t\t\tnotify_ops->destroy_device(&(ll_dev_cur->dev));\n-\t\t\tll_dev_cur = rm_config_ll_entry(ll_dev_cur, ll_dev_last);\n-\t\t} else {\n-\t\t\tll_dev_last = ll_dev_cur;\n-\t\t\tll_dev_cur = ll_dev_cur->next;\n-\t\t}\n-\t}\n-\tRTE_LOG(INFO, XENHOST, \"  %s guest:%p vring:%p rxvring:%p txvring:%p flag:%p\\n\",\n-\t\t__func__, guest, &guest->vring[virtio_idx], guest->vring[virtio_idx].rxvring_addr, guest->vring[virtio_idx].txvring_addr, guest->vring[virtio_idx].flag);\n-\tcleanup_vring(&guest->vring[virtio_idx]);\n-\tguest->vring[virtio_idx].removed = 1;\n-\tguest->vring_num -= 1;\n-}\n-\n-\n-\n-\n-static void\n-watch_unmap_event(void)\n-{\n-\tint i;\n-\tstruct xen_guest *guest  = NULL;\n-\tbool remove_request;\n-\n-\tTAILQ_FOREACH(guest, &guest_root, next) {\n-\t\tfor (i = 0; i < MAX_VIRTIO; i++) {\n-\t\t\tif (guest->vring[i].dom_id && guest->vring[i].removed == 0 && *guest->vring[i].flag == 0) {\n-\t\t\t\tRTE_LOG(INFO, XENHOST, \"\\n\\n\");\n-\t\t\t\tRTE_LOG(INFO, XENHOST, \"  #####%s:  (%d, %d) to be removed\\n\",\n-\t\t\t\t\t__func__,\n-\t\t\t\t\tguest->vring[i].dom_id,\n-\t\t\t\t\ti);\n-\t\t\t\tdestroy_device(i, guest->dom_id);\n-\t\t\t\tRTE_LOG(INFO, XENHOST, \"  %s: DOM %u, vring num: %d\\n\",\n-\t\t\t\t\t__func__,\n-\t\t\t\t\tguest->dom_id,\n-\t\t\t\t\tguest->vring_num);\n-\t\t\t}\n-\t\t}\n-\t}\n-\n-_find_next_remove:\n-\tguest = NULL;\n-\tremove_request = false;\n-\tTAILQ_FOREACH(guest, &guest_root, next) {\n-\t\tif (guest->vring_num == 0) {\n-\t\t\tremove_request = true;\n-\t\t\tbreak;\n-\t\t}\n-\t}\n-\tif (remove_request == true) {\n-\t\tTAILQ_REMOVE(&guest_root, guest, next);\n-\t\tRTE_LOG(INFO, XENHOST, \"  #####%s: destroy guest (%d)\\n\", __func__, guest->dom_id);\n-\t\tdestroy_guest(guest);\n-\t\tgoto _find_next_remove;\n-\t}\n-\treturn;\n-}\n-\n-/*\n- * OK, if the guest starts first, it is ok.\n- * if host starts first, it is ok.\n- * if guest starts, and has run for sometime, and host stops and restarts,\n- * then last_used_idx  0? how to solve this. */\n-\n-static void virtio_init(void)\n-{\n-\tuint32_t len, e_num;\n-\tuint32_t i,j;\n-\tchar **dom;\n-\tchar *status;\n-\tint dom_id;\n-\tchar path[PATH_MAX];\n-\tchar node[PATH_MAX];\n-\txs_transaction_t th;\n-\tstruct xen_guest *guest;\n-\tstruct virtio_net_config_ll *net_config;\n-\tchar *end;\n-\tint val;\n-\n-\t/* init env for watch the node */\n-\tif (init_watch() < 0)\n-\t\treturn;\n-\n-\tdom = xs_directory(watch.xs, XBT_NULL, \"/local/domain\", &e_num);\n-\n-\tfor (i = 0; i < e_num; i++) {\n-\t\terrno = 0;\n-\t\tdom_id = strtol(dom[i], &end, 0);\n-\t\tif (errno != 0 || end == NULL || dom_id == 0)\n-\t\t\tcontinue;\n-\n-\t\tfor (j = 0; j < RTE_MAX_ETHPORTS; j++) {\n-\t\t\tsnprintf(node, PATH_MAX, \"%s%d\", VIRTIO_START, j);\n-\t\t\tsnprintf(path, PATH_MAX, XEN_VM_NODE_FMT,\n-\t\t\t\t\tdom_id, node);\n-\n-\t\t\tth = xs_transaction_start(watch.xs);\n-\t\t\tstatus = xs_read(watch.xs, th, path, &len);\n-\t\t\txs_transaction_end(watch.xs, th, false);\n-\n-\t\t\tif (status == NULL)\n-\t\t\t\tbreak;\n-\n-\t\t\t/* if there's any valid virtio device */\n-\t\t\terrno = 0;\n-\t\t\tval = strtol(status, &end, 0);\n-\t\t\tif (errno != 0 || end == NULL || dom_id == 0)\n-\t\t\t\tval = 0;\n-\t\t\tif (val == 1) {\n-\t\t\t\tguest = add_xen_guest(dom_id);\n-\t\t\t\tif (guest == NULL)\n-\t\t\t\t\tcontinue;\n-\t\t\t\tRTE_LOG(INFO, XENHOST, \"  there's a new virtio existed, new a virtio device\\n\\n\");\n-\n-\t\t\t\tRTE_LOG(INFO, XENHOST, \"  parse_vringnode dom_id %d virtioidx %d\\n\",dom_id,j);\n-\t\t\t\tif (parse_vringnode(guest, j)) {\n-\t\t\t\t\tRTE_LOG(ERR, XENHOST, \"  there is invalid information in xenstore\\n\");\n-\t\t\t\t\tTAILQ_REMOVE(&guest_root, guest, next);\n-\t\t\t\t\tdestroy_guest(guest);\n-\n-\t\t\t\t\tcontinue;\n-\t\t\t\t}\n-\n-\t\t\t\t/*if pool_num > 0, then mempool has already been parsed*/\n-\t\t\t\tif (guest->pool_num == 0 && parse_mempoolnode(guest)) {\n-\t\t\t\t\tRTE_LOG(ERR, XENHOST, \"  there is error information in xenstore\\n\");\n-\t\t\t\t\tTAILQ_REMOVE(&guest_root, guest, next);\n-\t\t\t\t\tdestroy_guest(guest);\n-\t\t\t\t\tcontinue;\n-\t\t\t\t}\n-\n-\t\t\t\tnet_config = new_device(j, guest);\n-\t\t\t\t/* every thing is ready now, added into data core */\n-\t\t\t\tnotify_ops->new_device(&net_config->dev);\n-\t\t\t}\n-\t\t}\n-\t}\n-\n-\tfree(dom);\n-\treturn;\n-}\n-\n-void\n-virtio_monitor_loop(void)\n-{\n-\tchar **vec;\n-\txs_transaction_t th;\n-\tchar *buf;\n-\tunsigned int len;\n-\tunsigned int dom_id;\n-\tuint32_t virtio_idx;\n-\tstruct xen_guest *guest;\n-\tstruct virtio_net_config_ll *net_config;\n-\tenum fieldnames {\n-\t\tFLD_NULL = 0,\n-\t\tFLD_LOCAL,\n-\t\tFLD_DOMAIN,\n-\t\tFLD_ID,\n-\t\tFLD_CONTROL,\n-\t\tFLD_DPDK,\n-\t\tFLD_NODE,\n-\t\t_NUM_FLD\n-\t};\n-\tchar *str_fld[_NUM_FLD];\n-\tchar *str;\n-\tchar *end;\n-\n-\tvirtio_init();\n-\twhile (1) {\n-\t\twatch_unmap_event();\n-\n-\t\tusleep(50);\n-\t\tvec = xs_check_watch(watch.xs);\n-\n-\t\tif (vec == NULL)\n-\t\t\tcontinue;\n-\n-\t\tth = xs_transaction_start(watch.xs);\n-\n-\t\tbuf = xs_read(watch.xs, th, vec[XS_WATCH_PATH],&len);\n-\t\txs_transaction_end(watch.xs, th, false);\n-\n-\t\tif (buf) {\n-\t\t\t/* theres' some node for vhost existed */\n-\t\t\tif (rte_strsplit(vec[XS_WATCH_PATH], strnlen(vec[XS_WATCH_PATH], PATH_MAX),\n-\t\t\t\t\t\tstr_fld, _NUM_FLD, '/') == _NUM_FLD) {\n-\t\t\t\tif (strstr(str_fld[FLD_NODE], VIRTIO_START)) {\n-\t\t\t\t\terrno = 0;\n-\t\t\t\t\tstr = str_fld[FLD_ID];\n-\t\t\t\t\tdom_id = strtoul(str, &end, 0);\n-\t\t\t\t\tif (errno != 0 || end == NULL || end == str ) {\n-\t\t\t\t\t\tRTE_LOG(INFO, XENHOST, \"invalid domain id\\n\");\n-\t\t\t\t\t\tcontinue;\n-\t\t\t\t\t}\n-\n-\t\t\t\t\terrno = 0;\n-\t\t\t\t\tstr = str_fld[FLD_NODE] + sizeof(VIRTIO_START) - 1;\n-\t\t\t\t\tvirtio_idx = strtoul(str, &end, 0);\n-\t\t\t\t\tif (errno != 0 || end == NULL || end == str\n-\t\t\t\t\t\t\t|| virtio_idx > MAX_VIRTIO) {\n-\t\t\t\t\t\tRTE_LOG(INFO, XENHOST, \"invalid virtio idx\\n\");\n-\t\t\t\t\t\tcontinue;\n-\t\t\t\t\t}\n-\t\t\t\t\tRTE_LOG(INFO, XENHOST, \"  #####virtio dev (%d, %d) is started\\n\", dom_id, virtio_idx);\n-\n-\t\t\t\t\tguest = add_xen_guest(dom_id);\n-\t\t\t\t\tif (guest == NULL)\n-\t\t\t\t\t\tcontinue;\n-\t\t\t\t\tguest->dom_id = dom_id;\n-\t\t\t\t\tif (parse_vringnode(guest, virtio_idx)) {\n-\t\t\t\t\t\tRTE_LOG(ERR, XENHOST, \"  there is invalid information in xenstore\\n\");\n-\t\t\t\t\t\t/*guest newly created? guest existed ?*/\n-\t\t\t\t\t\tTAILQ_REMOVE(&guest_root, guest, next);\n-\t\t\t\t\t\tdestroy_guest(guest);\n-\t\t\t\t\t\tcontinue;\n-\t\t\t\t\t}\n-\t\t\t\t\t/*if pool_num > 0, then mempool has already been parsed*/\n-\t\t\t\t\tif (guest->pool_num == 0 && parse_mempoolnode(guest)) {\n-\t\t\t\t\t\tRTE_LOG(ERR, XENHOST, \"  there is error information in xenstore\\n\");\n-\t\t\t\t\t\tTAILQ_REMOVE(&guest_root, guest, next);\n-\t\t\t\t\t\tdestroy_guest(guest);\n-\t\t\t\t\t\tcontinue;\n-\t\t\t\t\t}\n-\n-\n-\t\t\t\t\tnet_config = new_device(virtio_idx, guest);\n-\t\t\t\t\tRTE_LOG(INFO, XENHOST, \"  Add to dataplane core\\n\");\n-\t\t\t\t\tnotify_ops->new_device(&net_config->dev);\n-\n-\t\t\t\t}\n-\t\t\t}\n-\t\t}\n-\n-\t\tfree(vec);\n-\t}\n-\treturn;\n-}\n-\n-/*\n- * Register ops so that we can add/remove device to data core.\n- */\n-int\n-init_virtio_xen(struct virtio_net_device_ops const *const ops)\n-{\n-\tnotify_ops = ops;\n-\tif (xenhost_init())\n-\t\treturn -1;\n-\treturn 0;\n-}\ndiff --git a/examples/vhost_xen/virtio-net.h b/examples/vhost_xen/virtio-net.h\ndeleted file mode 100644\nindex ab69726..0000000\n--- a/examples/vhost_xen/virtio-net.h\n+++ /dev/null\n@@ -1,113 +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 _VIRTIO_NET_H_\n-#define _VIRTIO_NET_H_\n-\n-#include <stdint.h>\n-\n-#define VQ_DESC_NUM 256\n-/* Used to indicate that the device is running on a data core */\n-#define VIRTIO_DEV_RUNNING 1\n-\n-/*\n- * Structure contains variables relevant to TX/RX virtqueues.\n- */\n-struct vhost_virtqueue\n-{\n-\tstruct vring_desc  *desc;             /* Virtqueue descriptor ring. */\n-\tstruct vring_avail *avail;            /* Virtqueue available ring. */\n-\tstruct vring_used  *used;             /* Virtqueue used ring. */\n-\tuint32_t           size;              /* Size of descriptor ring. */\n-\tuint32_t           vhost_hlen;        /* Vhost header length (varies depending on RX merge buffers. */\n-\tvolatile uint16_t  last_used_idx;     /* Last index used on the available ring */\n-\tvolatile uint16_t  last_used_idx_res; /* Used for multiple devices reserving buffers. */\n-} __rte_cache_aligned;\n-\n-/*\n- * Device structure contains all configuration information relating to the device.\n- */\n-struct virtio_net\n-{\n-\tstruct vhost_virtqueue\t*virtqueue_tx;\t/* Contains all TX virtqueue information. */\n-\tstruct vhost_virtqueue\t*virtqueue_rx;\t/* Contains all RX virtqueue information. */\n-\tstruct virtio_memory    *mem;           /* QEMU memory and memory region information. */\n-\tstruct ether_addr       mac_address;    /* Device MAC address (Obtained on first TX packet). */\n-\tuint32_t                flags;          /* Device flags. Only used to check if device is running on data core. */\n-\tuint32_t                vlan_tag;       /* Vlan tag for device. Currently set to device_id (0-63). */\n-\tuint32_t                vmdq_rx_q;\n-\tuint64_t                device_fh;      /* device identifier. */\n-\tuint16_t                coreid;\n-\tvolatile uint8_t        ready;          /* A device is set as ready if the MAC address has been set. */\n-\tvolatile uint8_t        remove;         /* Device is marked for removal from the data core. */\n-\tuint32_t                virtio_idx;     /* Index of virtio device */\n-\tuint32_t                dom_id;         /* Domain id of xen guest */\n-} ___rte_cache_aligned;\n-\n-/*\n- * Device linked list structure for configuration.\n- */\n-struct virtio_net_config_ll\n-{\n-\tstruct virtio_net\t\tdev;\t/* Virtio device. */\n-\tstruct virtio_net_config_ll\t*next; /* Next entry on linked list. */\n-};\n-\n-/*\n- * Information relating to memory regions including offsets to addresses in QEMUs memory file.\n- */\n-struct virtio_memory_regions {\n-\tuint64_t\tguest_phys_address;     /* Base guest physical address of region. */\n-\tuint64_t\tguest_phys_address_end;\t/* End guest physical address of region. */\n-\tuint64_t\tmemory_size;\t\t/* Size of region. */\n-\tuint64_t\tuserspace_address;      /* Base userspace address of region. */\n-\tuint64_t\taddress_offset;         /* Offset of region for address translation. */\n-};\n-\n-/*\n- * Memory structure includes region and mapping information.\n- */\n-struct virtio_memory {\n-\tuint32_t\t\t\tnregions;\t/* Number of memory regions. */\n-\tstruct virtio_memory_regions \tregions[0];\t/* Memory region information. */\n-};\n-\n-/*\n- * Device operations to add/remove device.\n- */\n-struct virtio_net_device_ops {\n-\tint (* new_device)(struct virtio_net *);\t/* Add device. */\n-\tvoid (* destroy_device)\t(volatile struct virtio_net *);\t/* Remove device. */\n-};\n-\n-#endif\ndiff --git a/examples/vhost_xen/xen_vhost.h b/examples/vhost_xen/xen_vhost.h\ndeleted file mode 100644\nindex 2fc304c..0000000\n--- a/examples/vhost_xen/xen_vhost.h\n+++ /dev/null\n@@ -1,148 +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 _XEN_VHOST_H_\n-#define _XEN_VHOST_H_\n-\n-#include <stdint.h>\n-\n-#include <rte_ether.h>\n-\n-#include \"virtio-net.h\"\n-\n-#define RTE_LOGTYPE_XENHOST RTE_LOGTYPE_USER1\n-\n-#define XEN_VM_ROOTNODE_FMT  \"/local/domain/%d/control/dpdk\"\n-#define XEN_VM_NODE_FMT      \"/local/domain/%d/control/dpdk/%s\"\n-#define XEN_MEMPOOL_SUFFIX   \"mempool_gref\"\n-#define XEN_RXVRING_SUFFIX   \"rx_vring_gref\"\n-#define XEN_TXVRING_SUFFIX   \"tx_vring_gref\"\n-#define XEN_GVA_SUFFIX       \"mempool_va\"\n-#define XEN_VRINGFLAG_SUFFIX \"vring_flag\"\n-#define XEN_ADDR_SUFFIX      \"ether_addr\"\n-#define VIRTIO_START         \"event_type_start_\"\n-\n-#define XEN_GREF_SPLITTOKEN  ','\n-\n-#define MAX_XENVIRT_MEMPOOL 16\n-#define MAX_VIRTIO  32\n-#define MAX_GREF_PER_NODE 64  /* 128 MB memory */\n-\n-#define PAGE_SIZE   4096\n-#define PAGE_PFNNUM (PAGE_SIZE / sizeof(uint32_t))\n-\n-#define XEN_GNTDEV_FNAME \"/dev/xen/gntdev\"\n-\n-/* xen grant reference info in one grant node */\n-struct xen_gnt {\n-\tuint32_t gref;\t/* grant reference for this node */\n-\tunion {\n-\t\tint gref;\t\t/* grant reference */\n-\t\tuint32_t pfn_num;\t/* guest pfn number of grant reference */\n-\t} gref_pfn[PAGE_PFNNUM];\n-}__attribute__((__packed__));\n-\n-\n-/* structure for mempool or vring node list */\n-struct xen_gntnode {\n-\tuint32_t gnt_num;           /* grant reference number */\n-\tstruct xen_gnt *gnt_info;   /* grant reference info */\n-};\n-\n-\n-struct xen_vring {\n-\tuint32_t dom_id;\n-\tuint32_t virtio_idx;    /* index of virtio device */\n-\tvoid *rxvring_addr;     /* mapped virtual address of rxvring */\n-\tvoid *txvring_addr;     /* mapped virtual address of txvring */\n-\tuint32_t rxpfn_num;     /* number of gpfn for rxvring */\n-\tuint32_t txpfn_num;\t/* number of gpfn for txvring */\n-\tuint32_t *rxpfn_tbl;    /* array of rxvring gpfn */\n-\tuint32_t *txpfn_tbl;\t/* array of txvring gpfn */\n-\tuint64_t *rx_pindex;    /* index used to release rx grefs */\n-\tuint64_t *tx_pindex;    /* index used to release tx grefs */\n-\tuint64_t  flag_index;\n-\tuint8_t  *flag; \t/* cleared to zero on guest unmap */\n-\tstruct ether_addr addr; /* ethernet address of virtio device */\n-\tuint8_t   removed;\n-\n-};\n-\n-struct xen_mempool {\n-\tuint32_t dom_id;      /* guest domain id */\n-\tuint32_t pool_idx;    /* index of memory pool */\n-\tvoid *gva;            /* guest virtual address of mbuf pool */\n-\tvoid *hva;            /* host virtual address of mbuf pool */\n-\tuint32_t mempfn_num;  /* number of gpfn for mbuf pool */\n-\tuint32_t *mempfn_tbl; /* array of mbuf pool gpfn */\n-\tuint64_t *pindex;     /* index used to release grefs */\n-};\n-\n-struct xen_guest {\n-\tTAILQ_ENTRY(xen_guest) next;\n-\tint32_t dom_id;       /* guest domain id */\n-\tuint32_t pool_num;    /* number of mbuf pool of the guest */\n-\tuint32_t vring_num;   /* number of virtio ports of the guest */\n-\t/* array contain the guest mbuf pool info */\n-\tstruct xen_mempool mempool[MAX_XENVIRT_MEMPOOL];\n-\t/* array contain the guest rx/tx vring info */\n-\tstruct xen_vring vring[MAX_VIRTIO];\n-};\n-\n-TAILQ_HEAD(xen_guestlist, xen_guest);\n-\n-int\n-parse_mempoolnode(struct xen_guest *guest);\n-\n-int\n-xenhost_init(void);\n-\n-int\n-parse_vringnode(struct xen_guest *guest, uint32_t virtio_idx);\n-\n-int\n-parse_mempoolnode(struct xen_guest *guest);\n-\n-void\n-cleanup_mempool(struct xen_mempool *mempool);\n-\n-void\n-cleanup_vring(struct xen_vring *vring);\n-\n-void\n-virtio_monitor_loop(void);\n-\n-int\n-init_virtio_xen(struct virtio_net_device_ops const * const);\n-\n-#endif\ndiff --git a/examples/vhost_xen/xenstore_parse.c b/examples/vhost_xen/xenstore_parse.c\ndeleted file mode 100644\nindex ab089f1..0000000\n--- a/examples/vhost_xen/xenstore_parse.c\n+++ /dev/null\n@@ -1,775 +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 <stdint.h>\n-#include <unistd.h>\n-#include <inttypes.h>\n-#include <errno.h>\n-#include <fcntl.h>\n-#include <sys/ioctl.h>\n-#include <sys/mman.h>\n-#include <xen/sys/gntalloc.h>\n-#include <xen/sys/gntdev.h>\n-#include <xen/xen-compat.h>\n-#if __XEN_LATEST_INTERFACE_VERSION__ < 0x00040200\n-#include <xs.h>\n-#else\n-#include <xenstore.h>\n-#endif\n-\n-#include <rte_common.h>\n-#include <rte_memory.h>\n-#include <rte_eal.h>\n-#include <rte_malloc.h>\n-#include <rte_string_fns.h>\n-#include <rte_log.h>\n-#include <rte_debug.h>\n-\n-#include \"xen_vhost.h\"\n-\n-/* xenstore handle */\n-static struct xs_handle *xs = NULL;\n-\n-/* gntdev file descriptor to map grant pages */\n-static int d_fd = -1;\n-\n-/*\n- *  The grant node format in xenstore for vring/mpool is like:\n- *  idx#_rx_vring_gref = \"gref1#, gref2#, gref3#\"\n- *  idx#_mempool_gref  = \"gref1#, gref2#, gref3#\"\n- *  each gref# is the grant reference for a shared page.\n- *  In each shared page, we store the grant_node_item items.\n- */\n-struct grant_node_item {\n-\tuint32_t gref;\n-\tuint32_t pfn;\n-} __attribute__((packed));\n-\n-int cmdline_parse_etheraddr(void *tk, const char *srcbuf,\n-\tvoid *res, unsigned ressize);\n-\n-/* Map grant ref refid at addr_ori*/\n-static void *\n-xen_grant_mmap(void *addr_ori, int domid, int refid, uint64_t *pindex)\n-{\n-\tstruct ioctl_gntdev_map_grant_ref arg;\n-\tvoid *addr = NULL;\n-\tint pg_sz = getpagesize();\n-\n-\targ.count = 1;\n-\targ.refs[0].domid = domid;\n-\targ.refs[0].ref = refid;\n-\n-\tint rv = ioctl(d_fd, IOCTL_GNTDEV_MAP_GRANT_REF, &arg);\n-\tif (rv) {\n-\t\tRTE_LOG(ERR, XENHOST, \"  %s: (%d,%d) %s (ioctl failed)\\n\", __func__,\n-\t\t\t\tdomid, refid, strerror(errno));\n-\t\treturn NULL;\n-\t}\n-\n-\tif (addr_ori == NULL)\n-\t\taddr = mmap(addr_ori, pg_sz, PROT_READ|PROT_WRITE, MAP_SHARED,\n-\t\t\t\td_fd, arg.index);\n-\telse\n-\t\taddr = mmap(addr_ori, pg_sz, PROT_READ|PROT_WRITE, MAP_SHARED | MAP_FIXED,\n-\t\t\t\td_fd, arg.index);\n-\n-\tif (addr == MAP_FAILED) {\n-\t\tRTE_LOG(ERR, XENHOST, \"  %s: (%d, %d) %s (map failed)\\n\", __func__,\n-\t\t\t\tdomid, refid, strerror(errno));\n-\t\treturn NULL;\n-\t}\n-\n-\tif (pindex)\n-\t\t*pindex = arg.index;\n-\n-\treturn addr;\n-}\n-\n-/* Unmap one grant ref, and munmap must be called before this */\n-static int\n-xen_unmap_grant_ref(uint64_t index)\n-{\n-\tstruct ioctl_gntdev_unmap_grant_ref arg;\n-\tint rv;\n-\n-\targ.count = 1;\n-\targ.index = index;\n-\trv = ioctl(d_fd, IOCTL_GNTDEV_UNMAP_GRANT_REF, &arg);\n-\tif (rv) {\n-\t\tRTE_LOG(ERR, XENHOST, \"  %s: index 0x%\" PRIx64 \"unmap failed\\n\", __func__, index);\n-\t\treturn -1;\n-\t}\n-\treturn 0;\n-}\n-\n-/*\n- * Reserve a virtual address space.\n- * On success, returns the pointer. On failure, returns NULL.\n- */\n-static void *\n-get_xen_virtual(size_t size, size_t page_sz)\n-{\n-\tvoid *addr;\n-\tuintptr_t aligned_addr;\n-\n-\taddr = mmap(NULL, size + page_sz, PROT_READ, MAP_SHARED | MAP_ANONYMOUS, -1, 0);\n-\tif (addr == MAP_FAILED) {\n-\t\tRTE_LOG(ERR, XENHOST, \"failed get a virtual area\\n\");\n-\t\treturn NULL;\n-\t}\n-\n-\taligned_addr = RTE_ALIGN_CEIL((uintptr_t)addr, page_sz);\n-\tmunmap(addr, aligned_addr - (uintptr_t)addr);\n-\tmunmap((void *)(aligned_addr + size), page_sz + (uintptr_t)addr - aligned_addr);\n-\taddr = (void *)(aligned_addr);\n-\n-\treturn addr;\n-}\n-\n-static void\n-free_xen_virtual(void *addr, size_t size, size_t page_sz __rte_unused)\n-{\n-\tif (addr)\n-\t\tmunmap(addr, size);\n-}\n-\n-/*\n- * Returns val str in xenstore.\n- * @param path\n- *  Full path string for key\n- * @return\n- *  Pointer to Val str, NULL on failure\n- */\n-static char *\n-xen_read_node(char *path, uint32_t *len)\n-{\n-\tchar *buf;\n-\n-\tbuf = xs_read(xs, XBT_NULL, path, len);\n-\treturn buf;\n-}\n-\n-static int\n-cal_pagenum(struct xen_gnt *gnt)\n-{\n-\tunsigned int i;\n-\t/*\n-\t * the items in the page are in the format of\n-\t * gref#,pfn#,...,gref#,pfn#\n-\t * FIXME, 0 is reserved by system, use it as terminator.\n-\t */\n-\tfor (i = 0; i < (PAGE_PFNNUM) / 2; i++) {\n-\t\tif (gnt->gref_pfn[i * 2].gref <= 0)\n-\t\t\tbreak;\n-\t}\n-\n-\treturn i;\n-}\n-\n-/* Frees memory allocated to a grant node */\n-static void\n-xen_free_gntnode(struct xen_gntnode *gntnode)\n-{\n-\tif (gntnode == NULL)\n-\t\treturn;\n-\tfree(gntnode->gnt_info);\n-\tfree(gntnode);\n-}\n-\n-/*\n- * Parse a grant node.\n- * @param domid\n- *  Guest domain id.\n- * @param path\n- *  Full path string for a grant node, like for the following (key, val) pair\n- *  idx#_mempool_gref = \"gref#, gref#, gref#\"\n- *  path = 'local/domain/domid/control/dpdk/idx#_mempool_gref'\n- *  gref# is a shared page contain packed (gref,pfn) entries\n- * @return\n- *  Returns the pointer to xen_gntnode\n- */\n-static struct xen_gntnode *\n-parse_gntnode(int dom_id, char *path)\n-{\n-\tchar **gref_list = NULL;\n-\tuint32_t i, len, gref_num;\n-\tvoid *addr = NULL;\n-\tchar *buf = NULL;\n-\tstruct xen_gntnode *gntnode = NULL;\n-\tstruct xen_gnt *gnt = NULL;\n-\tint pg_sz = getpagesize();\n-\tchar *end;\n-\tuint64_t index;\n-\n-\tif ((buf = xen_read_node(path, &len)) == NULL)\n-\t\tgoto err;\n-\n-\tgref_list = malloc(MAX_GREF_PER_NODE * sizeof(char *));\n-\tif (gref_list == NULL)\n-\t\tgoto err;\n-\n-\tgref_num = rte_strsplit(buf, len, gref_list, MAX_GREF_PER_NODE,\n-\t\t\tXEN_GREF_SPLITTOKEN);\n-\tif (gref_num == 0) {\n-\t\tRTE_LOG(ERR, XENHOST, \"  %s: invalid grant node format\\n\", __func__);\n-\t\tgoto err;\n-\t}\n-\n-\tgntnode = calloc(1, sizeof(struct xen_gntnode));\n-\tgnt = calloc(gref_num, sizeof(struct xen_gnt));\n-\tif (gnt == NULL || gntnode == NULL)\n-\t\tgoto err;\n-\n-\tfor (i = 0; i < gref_num; i++) {\n-\t\terrno = 0;\n-\t\tgnt[i].gref = strtol(gref_list[i], &end, 0);\n-\t\tif (errno != 0 || end == NULL || end == gref_list[i] ||\n-\t\t\t(*end != '\\0' &&  *end != XEN_GREF_SPLITTOKEN)) {\n-\t\t\tRTE_LOG(ERR, XENHOST, \"  %s: parse grant node item failed\\n\", __func__);\n-\t\t\tgoto err;\n-\t\t}\n-\t\taddr = xen_grant_mmap(NULL, dom_id, gnt[i].gref, &index);\n-\t\tif (addr == NULL) {\n-\t\t\tRTE_LOG(ERR, XENHOST, \"  %s: map gref %u failed\\n\", __func__, gnt[i].gref);\n-\t\t\tgoto err;\n-\t\t}\n-\t\tRTE_LOG(INFO, XENHOST, \"      %s: map gref %u to %p\\n\", __func__, gnt[i].gref, addr);\n-\t\tmemcpy(gnt[i].gref_pfn, addr, pg_sz);\n-\t\tif (munmap(addr, pg_sz)) {\n-\t\t\tRTE_LOG(INFO, XENHOST, \"  %s: unmap gref %u failed\\n\", __func__, gnt[i].gref);\n-\t\t\tgoto err;\n-\t\t}\n-\t\tif (xen_unmap_grant_ref(index)) {\n-\t\t\tRTE_LOG(INFO, XENHOST, \"  %s: release gref %u failed\\n\", __func__, gnt[i].gref);\n-\t\t\tgoto err;\n-\t\t}\n-\n-\t}\n-\n-\tgntnode->gnt_num  = gref_num;\n-\tgntnode->gnt_info = gnt;\n-\n-\tfree(buf);\n-\tfree(gref_list);\n-\treturn gntnode;\n-\n-err:\n-\tfree(gnt);\n-\tfree(gntnode);\n-\tfree(gref_list);\n-\tfree(buf);\n-\treturn NULL;\n-}\n-\n-/*\n- * This function maps grant node of vring or mbuf pool to a continuous virtual address space,\n- * and returns mapped address, pfn array, index array\n- * @param gntnode\n- *  Pointer to grant node\n- * @param domid\n- *  Guest domain id\n- * @param ppfn\n- *  Pointer to pfn array, caller should free this array\n- * @param pgs\n- *  Pointer to number of pages\n- * @param ppindex\n- *  Pointer to index array, used to release grefs when to free this node\n- * @return\n- *  Pointer to mapped virtual address, NULL on failure\n- */\n-static void *\n-map_gntnode(struct xen_gntnode *gntnode, int domid, uint32_t **ppfn, uint32_t *pgs, uint64_t **ppindex)\n-{\n-\tstruct xen_gnt *gnt;\n-\tuint32_t i, j;\n-\tsize_t total_pages = 0;\n-\tvoid *addr;\n-\tuint32_t *pfn;\n-\tuint64_t *pindex;\n-\tuint32_t pfn_num = 0;\n-\tint pg_sz;\n-\n-\tif (gntnode == NULL)\n-\t\treturn NULL;\n-\n-\tpg_sz = getpagesize();\n-\tfor (i = 0; i < gntnode->gnt_num; i++) {\n-\t\tgnt = gntnode->gnt_info + i;\n-\t\ttotal_pages += cal_pagenum(gnt);\n-\t}\n-\tif ((addr = get_xen_virtual(total_pages * pg_sz, pg_sz)) == NULL) {\n-\t\tRTE_LOG(ERR, XENHOST, \"  %s: failed get_xen_virtual\\n\", __func__);\n-\t\treturn NULL;\n-\t}\n-\tpfn = calloc(total_pages, (size_t)sizeof(uint32_t));\n-\tpindex = calloc(total_pages, (size_t)sizeof(uint64_t));\n-\tif (pfn == NULL || pindex == NULL) {\n-\t\tfree_xen_virtual(addr, total_pages * pg_sz, pg_sz);\n-\t\tfree(pfn);\n-\t\tfree(pindex);\n-\t\treturn NULL;\n-\t}\n-\n-\tRTE_LOG(INFO, XENHOST, \"    %s: total pages:%zu, map to [%p, %p]\\n\", __func__, total_pages, addr, RTE_PTR_ADD(addr, total_pages * pg_sz - 1));\n-\tfor (i = 0; i < gntnode->gnt_num; i++) {\n-\t\tgnt = gntnode->gnt_info + i;\n-\t\tfor (j = 0; j < (PAGE_PFNNUM) / 2; j++) {\n-\t\t\tif ((gnt->gref_pfn[j * 2].gref) <= 0)\n-\t\t\t\tgoto _end;\n-\t\t\t/*alternative: batch map, or through libxc*/\n-\t\t\tif (xen_grant_mmap(RTE_PTR_ADD(addr, pfn_num * pg_sz),\n-\t\t\t\t\tdomid,\n-\t\t\t\t\tgnt->gref_pfn[j * 2].gref,\n-\t\t\t\t\t&pindex[pfn_num]) == NULL) {\n-\t\t\t\tgoto mmap_failed;\n-\t\t\t}\n-\t\t\tpfn[pfn_num] = gnt->gref_pfn[j * 2 + 1].pfn_num;\n-\t\t\tpfn_num++;\n-\t\t}\n-\t}\n-\n-mmap_failed:\n-\tif (pfn_num)\n-\t\tmunmap(addr, pfn_num * pg_sz);\n-\tfor (i = 0; i < pfn_num; i++) {\n-\t\txen_unmap_grant_ref(pindex[i]);\n-\t}\n-\tfree(pindex);\n-\tfree(pfn);\n-\treturn NULL;\n-\n-_end:\n-\tif (ppindex)\n-\t\t*ppindex = pindex;\n-\telse\n-\t\tfree(pindex);\n-\tif (ppfn)\n-\t\t*ppfn = pfn;\n-\telse\n-\t\tfree(pfn);\n-\tif (pgs)\n-\t\t*pgs = total_pages;\n-\n-\treturn addr;\n-}\n-\n-static int\n-parse_mpool_va(struct xen_mempool *mempool)\n-{\n-\tchar path[PATH_MAX] = {0};\n-\tchar *buf;\n-\tuint32_t len;\n-\tchar *end;\n-\tint ret = -1;\n-\n-\terrno = 0;\n-\tsnprintf(path, sizeof(path),\n-\t\tXEN_VM_ROOTNODE_FMT\"/%d_\"XEN_GVA_SUFFIX,\n-\t\tmempool->dom_id, mempool->pool_idx);\n-\n-\tif((buf = xen_read_node(path, &len)) == NULL)\n-\t\tgoto out;\n-\tmempool->gva = (void *)strtoul(buf, &end, 16);\n-\tif (errno != 0 || end == NULL || end == buf || *end != '\\0') {\n-\t\tmempool->gva = NULL;\n-\t\tgoto out;\n-\t}\n-\tret = 0;\n-out:\n-\tfree(buf);\n-\treturn ret;\n-}\n-\n-/*\n- * map mbuf pool\n- */\n-static int\n-map_mempoolnode(struct xen_gntnode *gntnode,\n-\t\t\tstruct xen_mempool *mempool)\n-{\n-\tif (gntnode == NULL || mempool == NULL)\n-\t\treturn -1;\n-\n-\tmempool->hva =\n-\t\tmap_gntnode(gntnode, mempool->dom_id, &mempool->mempfn_tbl, &mempool->mempfn_num, &mempool->pindex);\n-\n-\tRTE_LOG(INFO, XENHOST, \"  %s: map mempool at %p\\n\", __func__, (void *)mempool->hva);\n-\tif (mempool->hva)\n-\t\treturn 0;\n-\telse {\n-\t\treturn -1;\n-\t}\n-}\n-\n-void\n-cleanup_mempool(struct xen_mempool *mempool)\n-{\n-\tint pg_sz = getpagesize();\n-\tuint32_t i;\n-\n-\tif (mempool->hva)\n-\t\tmunmap(mempool->hva, mempool->mempfn_num * pg_sz);\n-\tmempool->hva = NULL;\n-\n-\tif (mempool->pindex) {\n-\t\tRTE_LOG(INFO, XENHOST, \"  %s: unmap dom %02u mempool%02u %u grefs\\n\",\n-\t\t\t__func__,\n-\t\t\tmempool->dom_id,\n-\t\t\tmempool->pool_idx,\n-\t\t\tmempool->mempfn_num);\n-\t\tfor (i = 0; i < mempool->mempfn_num; i ++) {\n-\t\t\txen_unmap_grant_ref(mempool->pindex[i]);\n-\t\t}\n-\t}\n-\tmempool->pindex = NULL;\n-\n-\tfree(mempool->mempfn_tbl);\n-\tmempool->mempfn_tbl = NULL;\n-}\n-\n-/*\n- * process mempool node idx#_mempool_gref, idx = 0, 1, 2...\n- * until we encounter a node that doesn't exist.\n- */\n-int\n-parse_mempoolnode(struct xen_guest *guest)\n-{\n-\tuint32_t i, len;\n-\tchar path[PATH_MAX] = {0};\n-\tstruct xen_gntnode *gntnode = NULL;\n-\tstruct xen_mempool *mempool = NULL;\n-\tchar *buf;\n-\n-\tbzero(&guest->mempool, MAX_XENVIRT_MEMPOOL * sizeof(guest->mempool[0]));\n-\tguest->pool_num = 0;\n-\n-\twhile (1) {\n-\t\t/* check if null terminated */\n-\t\tsnprintf(path, sizeof(path),\n-\t\t\tXEN_VM_ROOTNODE_FMT\"/%d_\"XEN_MEMPOOL_SUFFIX,\n-\t\t\tguest->dom_id,\n-\t\t\tguest->pool_num);\n-\n-\t\tif ((buf = xen_read_node(path, &len)) != NULL) {\n-\t\t\t/* this node exists */\n-\t\t\tfree(buf);\n-\t\t} else {\n-\t\t\tif (guest->pool_num == 0) {\n-\t\t\t\tRTE_LOG(ERR, PMD, \"no mempool found\\n\");\n-\t\t\t\treturn -1;\n-\t\t\t}\n-\t\t\tbreak;\n-\t\t}\n-\n-\t\tmempool = &guest->mempool[guest->pool_num];\n-\t\tmempool->dom_id = guest->dom_id;\n-\t\tmempool->pool_idx = guest->pool_num;\n-\n-\t\tRTE_LOG(INFO, XENHOST, \"  %s: mempool %u parse gntnode %s\\n\", __func__, guest->pool_num, path);\n-\t\tgntnode = parse_gntnode(guest->dom_id, path);\n-\t\tif (gntnode == NULL)\n-\t\t\tgoto err;\n-\n-\t\tif (parse_mpool_va(mempool))\n-\t\t\tgoto err;\n-\n-\t\tRTE_LOG(INFO, XENHOST, \"  %s: mempool %u map gntnode %s\\n\", __func__, guest->pool_num, path);\n-\t\tif (map_mempoolnode(gntnode, mempool))\n-\t\t\tgoto err;\n-\n-\t\txen_free_gntnode(gntnode);\n-\t\tguest->pool_num++;\n-\t}\n-\n-\treturn 0;\n-err:\n-\tif (gntnode)\n-\t\txen_free_gntnode(gntnode);\n-\tfor (i = 0; i <  MAX_XENVIRT_MEMPOOL ; i++) {\n-\t\tcleanup_mempool(&guest->mempool[i]);\n-\t}\n-\t/* reinitialise mempool */\n-\tbzero(&guest->mempool, MAX_XENVIRT_MEMPOOL * sizeof(guest->mempool[0]));\n-\treturn -1;\n-}\n-\n-static int\n-xen_map_vringflag(struct xen_vring *vring)\n-{\n-\tchar path[PATH_MAX] = {0};\n-\tchar *buf;\n-\tuint32_t len,gref;\n-\tint pg_sz = getpagesize();\n-\tchar *end;\n-\n-\tsnprintf(path, sizeof(path),\n-\t\tXEN_VM_ROOTNODE_FMT\"/%d_\"XEN_VRINGFLAG_SUFFIX,\n-\t\tvring->dom_id, vring->virtio_idx);\n-\n-\tif((buf = xen_read_node(path, &len)) == NULL)\n-\t\tgoto err;\n-\n-\terrno = 0;\n-\tgref = strtol(buf, &end, 0);\n-\tif (errno != 0 || end == NULL || end == buf) {\n-\t\tgoto err;\n-\t}\n-\tvring->flag = xen_grant_mmap(0, vring->dom_id, gref, &vring->flag_index);\n-\tif (vring->flag == NULL || *vring->flag == 0)\n-\t\tgoto err;\n-\n-\tfree(buf);\n-\treturn 0;\n-err:\n-\tfree(buf);\n-\tif (vring->flag) {\n-\t\tmunmap(vring->flag, pg_sz);\n-\t\tvring->flag = NULL;\n-\t\txen_unmap_grant_ref(vring->flag_index);\n-\t}\n-\treturn -1;\n-}\n-\n-\n-static int\n-xen_map_rxvringnode(struct xen_gntnode *gntnode,\n-\t\t\t\tstruct xen_vring *vring)\n-{\n-\tvring->rxvring_addr =\n-\t\tmap_gntnode(gntnode, vring->dom_id, &vring->rxpfn_tbl, &vring->rxpfn_num, &vring->rx_pindex);\n-\tRTE_LOG(INFO, XENHOST, \"  %s: map rx vring at %p\\n\", __func__, (void *)vring->rxvring_addr);\n-\tif (vring->rxvring_addr)\n-\t\treturn 0;\n-\telse\n-\t\treturn -1;\n-}\n-\n-static int\n-xen_map_txvringnode(struct xen_gntnode *gntnode,\n-\t\t\t\tstruct xen_vring *vring)\n-{\n-\tvring->txvring_addr =\n-\t\tmap_gntnode(gntnode, vring->dom_id, &vring->txpfn_tbl, &vring->txpfn_num, &vring->tx_pindex);\n-\tRTE_LOG(INFO, XENHOST, \"  %s: map tx vring at %p\\n\", __func__, (void *)vring->txvring_addr);\n-\tif (vring->txvring_addr)\n-\t\treturn 0;\n-\telse\n-\t\treturn -1;\n-}\n-\n-void\n-cleanup_vring(struct xen_vring *vring)\n-{\n-\tint pg_sz = getpagesize();\n-\tuint32_t i;\n-\n-\tRTE_LOG(INFO, XENHOST, \"  %s: cleanup dom %u vring %u\\n\", __func__, vring->dom_id, vring->virtio_idx);\n-\tif (vring->rxvring_addr) {\n-\t\tmunmap(vring->rxvring_addr, vring->rxpfn_num * pg_sz);\n-\t\tRTE_LOG(INFO, XENHOST, \"  %s: unmap rx vring [%p, %p]\\n\",\n-\t\t\t__func__,\n-\t\t\tvring->rxvring_addr,\n-\t\t\tRTE_PTR_ADD(vring->rxvring_addr,\n-\t\t\tvring->rxpfn_num * pg_sz - 1));\n-\t}\n-\tvring->rxvring_addr = NULL;\n-\n-\n-\tif (vring->rx_pindex) {\n-\t\tRTE_LOG(INFO, XENHOST, \"  %s: unmap rx vring %u grefs\\n\", __func__, vring->rxpfn_num);\n-\t\tfor (i = 0; i < vring->rxpfn_num; i++) {\n-\t\t\txen_unmap_grant_ref(vring->rx_pindex[i]);\n-\t\t}\n-\t}\n-\tvring->rx_pindex = NULL;\n-\n-\tfree(vring->rxpfn_tbl);\n-\tvring->rxpfn_tbl = NULL;\n-\n-\tif (vring->txvring_addr) {\n-\t\tmunmap(vring->txvring_addr, vring->txpfn_num * pg_sz);\n-\t\tRTE_LOG(INFO, XENHOST, \"  %s: unmap tx vring [%p, %p]\\n\",\n-\t\t\t__func__,\n-\t\t\tvring->txvring_addr,\n-\t\t\tRTE_PTR_ADD(vring->txvring_addr,\n-\t\t\tvring->txpfn_num * pg_sz - 1));\n-\t}\n-\tvring->txvring_addr = NULL;\n-\n-\tif (vring->tx_pindex) {\n-\t\tRTE_LOG(INFO, XENHOST, \"  %s: unmap tx vring %u grefs\\n\", __func__, vring->txpfn_num);\n-\t\tfor (i = 0; i < vring->txpfn_num; i++) {\n-\t\t\txen_unmap_grant_ref(vring->tx_pindex[i]);\n-\t\t}\n-\t}\n-\tvring->tx_pindex = NULL;\n-\n-\tfree(vring->txpfn_tbl);\n-\tvring->txpfn_tbl = NULL;\n-\n-\tif (vring->flag) {\n-\t\tif (!munmap((void *)vring->flag, pg_sz))\n-\t\t\tRTE_LOG(INFO, XENHOST, \"  %s: unmap flag page at %p\\n\", __func__, vring->flag);\n-\t\tif (!xen_unmap_grant_ref(vring->flag_index))\n-\t\t\tRTE_LOG(INFO, XENHOST, \"  %s: release flag ref index 0x%\" PRIx64 \"\\n\", __func__, vring->flag_index);\n-\t}\n-\tvring->flag = NULL;\n-\treturn;\n-}\n-\n-\n-\n-static int\n-xen_parse_etheraddr(struct xen_vring *vring)\n-{\n-\tchar path[PATH_MAX] = {0};\n-\tchar *buf;\n-\tuint32_t len;\n-\tint ret = -1;\n-\n-\tsnprintf(path, sizeof(path),\n-\t\tXEN_VM_ROOTNODE_FMT\"/%d_\"XEN_ADDR_SUFFIX,\n-\t\tvring->dom_id, vring->virtio_idx);\n-\n-\tif ((buf = xen_read_node(path, &len)) == NULL)\n-\t\tgoto out;\n-\n-\tif (cmdline_parse_etheraddr(NULL, buf, &vring->addr,\n-\t\t\tsizeof(vring->addr)) < 0)\n-\t\tgoto out;\n-\tret = 0;\n-out:\n-\tfree(buf);\n-\treturn ret;\n-}\n-\n-\n-int\n-parse_vringnode(struct xen_guest *guest, uint32_t virtio_idx)\n-{\n-\tchar path[PATH_MAX] = {0};\n-\tstruct xen_gntnode *rx_gntnode = NULL;\n-\tstruct xen_gntnode *tx_gntnode = NULL;\n-\tstruct xen_vring *vring = NULL;\n-\n-\t/*check if null terminated */\n-\tsnprintf(path, sizeof(path),\n-\t\tXEN_VM_ROOTNODE_FMT\"/%d_\"XEN_RXVRING_SUFFIX,\n-\t\tguest->dom_id,\n-\t\tvirtio_idx);\n-\n-\tRTE_LOG(INFO, XENHOST, \"  %s: virtio %u parse rx gntnode %s\\n\", __func__, virtio_idx, path);\n-\trx_gntnode = parse_gntnode(guest->dom_id, path);\n-\tif (rx_gntnode == NULL)\n-\t\tgoto err;\n-\n-\t/*check if null terminated */\n-\tsnprintf(path, sizeof(path),\n-\t\tXEN_VM_ROOTNODE_FMT\"/%d_\"XEN_TXVRING_SUFFIX,\n-\t\tguest->dom_id,\n-\t\tvirtio_idx);\n-\n-\tRTE_LOG(INFO, XENHOST, \"  %s: virtio %u parse tx gntnode %s\\n\", __func__, virtio_idx, path);\n-\ttx_gntnode = parse_gntnode(guest->dom_id, path);\n-\tif (tx_gntnode == NULL)\n-\t\tgoto err;\n-\n-\tvring = &guest->vring[virtio_idx];\n-\tbzero(vring, sizeof(*vring));\n-\tvring->dom_id = guest->dom_id;\n-\tvring->virtio_idx = virtio_idx;\n-\n-\tif (xen_parse_etheraddr(vring) != 0)\n-\t\tgoto err;\n-\n-\tRTE_LOG(INFO, XENHOST, \"  %s: virtio %u map rx gntnode %s\\n\", __func__, virtio_idx, path);\n-\tif (xen_map_rxvringnode(rx_gntnode, vring) != 0)\n-\t\tgoto err;\n-\n-\tRTE_LOG(INFO, XENHOST, \"  %s: virtio %u map tx gntnode %s\\n\", __func__, virtio_idx, path);\n-\tif (xen_map_txvringnode(tx_gntnode, vring) != 0)\n-\t\tgoto err;\n-\n-\tif (xen_map_vringflag(vring) != 0)\n-\t\tgoto err;\n-\n-\tguest->vring_num++;\n-\n-\txen_free_gntnode(rx_gntnode);\n-\txen_free_gntnode(tx_gntnode);\n-\n-\treturn 0;\n-\n-err:\n-\tif (rx_gntnode)\n-\t\txen_free_gntnode(rx_gntnode);\n-\tif (tx_gntnode)\n-\t\txen_free_gntnode(tx_gntnode);\n-\tif (vring) {\n-\t\tcleanup_vring(vring);\n-\t\tbzero(vring, sizeof(*vring));\n-\t}\n-\treturn -1;\n-}\n-\n-/*\n- * Open xen grant dev driver\n- * @return\n- *  0 on success, -1 on failure.\n- */\n-static int\n-xen_grant_init(void)\n-{\n-\td_fd = open(XEN_GNTDEV_FNAME, O_RDWR);\n-\n-\treturn d_fd == -1? (-1): (0);\n-}\n-\n-/*\n- * Initialise xenstore handle and open grant dev driver.\n- * @return\n- *  0 on success, -1 on failure.\n- */\n-int\n-xenhost_init(void)\n-{\n-\txs = xs_daemon_open();\n-\tif (xs == NULL) {\n-\t\trte_panic(\"failed initialize xen daemon handler\");\n-\t\treturn -1;\n-\t}\n-\tif (xen_grant_init())\n-\t\treturn -1;\n-\treturn 0;\n-}\n",
    "prefixes": [
        "dpdk-dev",
        "1/6"
    ]
}