* [dpdk-dev] [PATCH 1/6] example/vhost_xen: remove
2017-08-30 18:10 [dpdk-dev] [PATCH 0/6] remove xen dom0 support in DPDK Jianfeng Tan
@ 2017-08-30 18:10 ` Jianfeng Tan
2017-09-04 14:14 ` Bruce Richardson
2017-08-30 18:10 ` [dpdk-dev] [PATCH 2/6] net/xenvirt: remove Jianfeng Tan
` (5 subsequent siblings)
6 siblings, 1 reply; 21+ messages in thread
From: Jianfeng Tan @ 2017-08-30 18:10 UTC (permalink / raw)
To: dev
Cc: xen-devel, thomas, john.mcnamara, oao.m.martins, jerin.jacob,
shahafs, Jianfeng Tan
Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
MAINTAINERS | 1 -
examples/Makefile | 1 -
examples/vhost_xen/Makefile | 52 --
examples/vhost_xen/main.c | 1522 -----------------------------------
examples/vhost_xen/main.h | 66 --
examples/vhost_xen/vhost_monitor.c | 595 --------------
examples/vhost_xen/virtio-net.h | 113 ---
examples/vhost_xen/xen_vhost.h | 148 ----
examples/vhost_xen/xenstore_parse.c | 775 ------------------
9 files changed, 3273 deletions(-)
delete mode 100644 examples/vhost_xen/Makefile
delete mode 100644 examples/vhost_xen/main.c
delete mode 100644 examples/vhost_xen/main.h
delete mode 100644 examples/vhost_xen/vhost_monitor.c
delete mode 100644 examples/vhost_xen/virtio-net.h
delete mode 100644 examples/vhost_xen/xen_vhost.h
delete mode 100644 examples/vhost_xen/xenstore_parse.c
diff --git a/MAINTAINERS b/MAINTAINERS
index a0cd75e..fe6c6db 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -196,7 +196,6 @@ F: lib/librte_eal/linuxapp/eal/*xen*
F: lib/librte_eal/linuxapp/eal/include/exec-env/rte_dom0_common.h
F: drivers/net/xenvirt/
F: doc/guides/xen/
-F: examples/vhost_xen/
F: doc/guides/nics/features/xenvirt.ini
FreeBSD EAL (with overlaps)
diff --git a/examples/Makefile b/examples/Makefile
index 28354ff..d27eddd 100644
--- a/examples/Makefile
+++ b/examples/Makefile
@@ -89,7 +89,6 @@ DIRS-$(CONFIG_RTE_LIBRTE_VHOST) += tep_termination
endif
DIRS-$(CONFIG_RTE_LIBRTE_TIMER) += timer
DIRS-$(CONFIG_RTE_LIBRTE_VHOST) += vhost vhost_scsi
-DIRS-$(CONFIG_RTE_LIBRTE_XEN_DOM0) += vhost_xen
DIRS-y += vmdq
DIRS-y += vmdq_dcb
ifeq ($(CONFIG_RTE_LIBRTE_POWER), y)
diff --git a/examples/vhost_xen/Makefile b/examples/vhost_xen/Makefile
deleted file mode 100644
index ad2466a..0000000
--- a/examples/vhost_xen/Makefile
+++ /dev/null
@@ -1,52 +0,0 @@
-# BSD LICENSE
-#
-# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in
-# the documentation and/or other materials provided with the
-# distribution.
-# * Neither the name of Intel Corporation nor the names of its
-# contributors may be used to endorse or promote products derived
-# from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-ifeq ($(RTE_SDK),)
-$(error "Please define RTE_SDK environment variable")
-endif
-
-# Default target, can be overridden by command line or environment
-RTE_TARGET ?= x86_64-native-linuxapp-gcc
-
-include $(RTE_SDK)/mk/rte.vars.mk
-
-# binary name
-APP = vhost-switch
-
-# all source are stored in SRCS-y
-SRCS-y := main.c vhost_monitor.c xenstore_parse.c
-
-CFLAGS += -O2 -I/usr/local/include -D_FILE_OFFSET_BITS=64 -Wno-unused-parameter
-CFLAGS += $(WERROR_FLAGS)
-CFLAGS += -D_GNU_SOURCE
-LDFLAGS += -lxenstore
-
-include $(RTE_SDK)/mk/rte.extapp.mk
diff --git a/examples/vhost_xen/main.c b/examples/vhost_xen/main.c
deleted file mode 100644
index eba4d35..0000000
--- a/examples/vhost_xen/main.c
+++ /dev/null
@@ -1,1522 +0,0 @@
-/*-
- * BSD LICENSE
- *
- * Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Intel Corporation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <arpa/inet.h>
-#include <getopt.h>
-#include <linux/if_ether.h>
-#include <linux/if_vlan.h>
-#include <linux/virtio_net.h>
-#include <linux/virtio_ring.h>
-#include <signal.h>
-#include <stdint.h>
-#include <sys/eventfd.h>
-#include <sys/param.h>
-#include <unistd.h>
-
-#include <rte_atomic.h>
-#include <rte_cycles.h>
-#include <rte_ethdev.h>
-#include <rte_log.h>
-#include <rte_string_fns.h>
-#include <rte_pause.h>
-
-#include "main.h"
-#include "virtio-net.h"
-#include "xen_vhost.h"
-
-#define MAX_QUEUES 128
-
-/* the maximum number of external ports supported */
-#define MAX_SUP_PORTS 1
-
-/*
- * Calculate the number of buffers needed per port
- */
-#define NUM_MBUFS_PER_PORT ((MAX_QUEUES*RTE_TEST_RX_DESC_DEFAULT) + \
- (num_switching_cores*MAX_PKT_BURST) + \
- (num_switching_cores*RTE_TEST_TX_DESC_DEFAULT) +\
- (num_switching_cores*MBUF_CACHE_SIZE))
-
-#define MBUF_CACHE_SIZE 64
-
-/*
- * RX and TX Prefetch, Host, and Write-back threshold values should be
- * carefully set for optimal performance. Consult the network
- * controller's datasheet and supporting DPDK documentation for guidance
- * on how these parameters should be set.
- */
-#define RX_PTHRESH 8 /* Default values of RX prefetch threshold reg. */
-#define RX_HTHRESH 8 /* Default values of RX host threshold reg. */
-#define RX_WTHRESH 4 /* Default values of RX write-back threshold reg. */
-
-/*
- * These default values are optimized for use with the Intel(R) 82599 10 GbE
- * Controller and the DPDK ixgbe PMD. Consider using other values for other
- * network controllers and/or network drivers.
- */
-#define TX_PTHRESH 36 /* Default values of TX prefetch threshold reg. */
-#define TX_HTHRESH 0 /* Default values of TX host threshold reg. */
-#define TX_WTHRESH 0 /* Default values of TX write-back threshold reg. */
-
-#define MAX_PKT_BURST 32 /* Max burst size for RX/TX */
-#define MAX_MRG_PKT_BURST 16 /* Max burst for merge buffers. Set to 1 due to performance issue. */
-#define BURST_TX_DRAIN_US 100 /* TX drain every ~100us */
-
-/* State of virtio device. */
-#define DEVICE_NOT_READY 0
-#define DEVICE_READY 1
-#define DEVICE_SAFE_REMOVE 2
-
-/* Config_core_flag status definitions. */
-#define REQUEST_DEV_REMOVAL 1
-#define ACK_DEV_REMOVAL 0
-
-/* Configurable number of RX/TX ring descriptors */
-#define RTE_TEST_RX_DESC_DEFAULT 128
-#define RTE_TEST_TX_DESC_DEFAULT 512
-
-#define INVALID_PORT_ID 0xFF
-
-/* Max number of devices. Limited by vmdq. */
-#define MAX_DEVICES 64
-
-/* Size of buffers used for snprintfs. */
-#define MAX_PRINT_BUFF 6072
-
-
-/* Maximum long option length for option parsing. */
-#define MAX_LONG_OPT_SZ 64
-
-/* Used to compare MAC addresses. */
-#define MAC_ADDR_CMP 0xFFFFFFFFFFFF
-
-/* mask of enabled ports */
-static uint32_t enabled_port_mask = 0;
-
-/*Number of switching cores enabled*/
-static uint32_t num_switching_cores = 0;
-
-/* number of devices/queues to support*/
-static uint32_t num_queues = 0;
-uint32_t num_devices = 0;
-
-/* Enable VM2VM communications. If this is disabled then the MAC address compare is skipped. */
-static uint32_t enable_vm2vm = 1;
-/* Enable stats. */
-static uint32_t enable_stats = 0;
-
-/* empty vmdq configuration structure. Filled in programatically */
-static const struct rte_eth_conf vmdq_conf_default = {
- .rxmode = {
- .mq_mode = ETH_MQ_RX_VMDQ_ONLY,
- .split_hdr_size = 0,
- .header_split = 0, /**< Header Split disabled */
- .hw_ip_checksum = 0, /**< IP checksum offload disabled */
- .hw_vlan_filter = 0, /**< VLAN filtering disabled */
- /*
- * It is necessary for 1G NIC such as I350,
- * this fixes bug of ipv4 forwarding in guest can't
- * forward pakets from one virtio dev to another virtio dev.
- */
- .hw_vlan_strip = 1, /**< VLAN strip enabled. */
- .jumbo_frame = 0, /**< Jumbo Frame Support disabled */
- .hw_strip_crc = 1, /**< CRC stripped by hardware */
- },
-
- .txmode = {
- .mq_mode = ETH_MQ_TX_NONE,
- },
- .rx_adv_conf = {
- /*
- * should be overridden separately in code with
- * appropriate values
- */
- .vmdq_rx_conf = {
- .nb_queue_pools = ETH_8_POOLS,
- .enable_default_pool = 0,
- .default_pool = 0,
- .nb_pool_maps = 0,
- .pool_map = {{0, 0},},
- },
- },
-};
-
-static unsigned lcore_ids[RTE_MAX_LCORE];
-static uint8_t ports[RTE_MAX_ETHPORTS];
-static unsigned num_ports = 0; /**< The number of ports specified in command line */
-
-const uint16_t vlan_tags[] = {
- 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007,
- 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015,
- 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023,
- 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031,
- 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039,
- 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047,
- 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055,
- 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063,
-};
-
-/* ethernet addresses of ports */
-static struct ether_addr vmdq_ports_eth_addr[RTE_MAX_ETHPORTS];
-
-/* heads for the main used and free linked lists for the data path. */
-static struct virtio_net_data_ll *ll_root_used = NULL;
-static struct virtio_net_data_ll *ll_root_free = NULL;
-
-/* Array of data core structures containing information on individual core linked lists. */
-static struct lcore_info lcore_info[RTE_MAX_LCORE];
-
-/* Used for queueing bursts of TX packets. */
-struct mbuf_table {
- unsigned len;
- unsigned txq_id;
- struct rte_mbuf *m_table[MAX_PKT_BURST];
-};
-
-/* TX queue for each data core. */
-struct mbuf_table lcore_tx_queue[RTE_MAX_LCORE];
-
-/* Vlan header struct used to insert vlan tags on TX. */
-struct vlan_ethhdr {
- unsigned char h_dest[ETH_ALEN];
- unsigned char h_source[ETH_ALEN];
- __be16 h_vlan_proto;
- __be16 h_vlan_TCI;
- __be16 h_vlan_encapsulated_proto;
-};
-
-/* Header lengths. */
-#define VLAN_HLEN 4
-#define VLAN_ETH_HLEN 18
-
-/* Per-device statistics struct */
-struct device_statistics {
- uint64_t tx_total;
- rte_atomic64_t rx_total;
- uint64_t tx;
- rte_atomic64_t rx;
-} __rte_cache_aligned;
-struct device_statistics dev_statistics[MAX_DEVICES];
-
-/*
- * Builds up the correct configuration for VMDQ VLAN pool map
- * according to the pool & queue limits.
- */
-static inline int
-get_eth_conf(struct rte_eth_conf *eth_conf, uint32_t num_devices)
-{
- struct rte_eth_vmdq_rx_conf conf;
- unsigned i;
-
- memset(&conf, 0, sizeof(conf));
- conf.nb_queue_pools = (enum rte_eth_nb_pools)num_devices;
- conf.nb_pool_maps = num_devices;
-
- for (i = 0; i < conf.nb_pool_maps; i++) {
- conf.pool_map[i].vlan_id = vlan_tags[ i ];
- conf.pool_map[i].pools = (1UL << i);
- }
-
- (void)(rte_memcpy(eth_conf, &vmdq_conf_default, sizeof(*eth_conf)));
- (void)(rte_memcpy(ð_conf->rx_adv_conf.vmdq_rx_conf, &conf,
- sizeof(eth_conf->rx_adv_conf.vmdq_rx_conf)));
- return 0;
-}
-
-/*
- * Validate the device number according to the max pool number gotten form dev_info
- * If the device number is invalid, give the error message and return -1.
- * Each device must have its own pool.
- */
-static inline int
-validate_num_devices(uint32_t max_nb_devices)
-{
- if (num_devices > max_nb_devices) {
- RTE_LOG(ERR, VHOST_PORT, "invalid number of devices\n");
- return -1;
- }
- return 0;
-}
-
-/*
- * Initialises a given port using global settings and with the rx buffers
- * coming from the mbuf_pool passed as parameter
- */
-static inline int
-port_init(uint8_t port, struct rte_mempool *mbuf_pool)
-{
- struct rte_eth_dev_info dev_info;
- struct rte_eth_rxconf *rxconf;
- struct rte_eth_conf port_conf;
- uint16_t rx_rings, tx_rings = (uint16_t)rte_lcore_count();
- uint16_t rx_ring_size = RTE_TEST_RX_DESC_DEFAULT;
- uint16_t tx_ring_size = RTE_TEST_TX_DESC_DEFAULT;
- int retval;
- uint16_t q;
-
- /* The max pool number from dev_info will be used to validate the pool number specified in cmd line */
- rte_eth_dev_info_get (port, &dev_info);
-
- /*configure the number of supported virtio devices based on VMDQ limits */
- num_devices = dev_info.max_vmdq_pools;
- num_queues = dev_info.max_rx_queues;
-
- retval = validate_num_devices(MAX_DEVICES);
- if (retval < 0)
- return retval;
-
- /* Get port configuration. */
- retval = get_eth_conf(&port_conf, num_devices);
- if (retval < 0)
- return retval;
-
- if (port >= rte_eth_dev_count()) return -1;
-
- rx_rings = (uint16_t)num_queues,
- /* Configure ethernet device. */
- retval = rte_eth_dev_configure(port, rx_rings, tx_rings, &port_conf);
- if (retval != 0)
- return retval;
-
- retval = rte_eth_dev_adjust_nb_rx_tx_desc(port, &rx_ring_size,
- &tx_ring_size);
- if (retval != 0)
- return retval;
- if (rx_ring_size > RTE_TEST_RX_DESC_DEFAULT ||
- tx_ring_size > RTE_TEST_TX_DESC_DEFAULT) {
- RTE_LOG(ERR, VHOST_PORT, "Mbuf pool has an insufficient size for "
- "port %u.\n", port);
- return -1;
- }
-
- rte_eth_dev_info_get(port, &dev_info);
- rxconf = &dev_info.default_rxconf;
- rxconf->rx_drop_en = 1;
- /* Setup the queues. */
- for (q = 0; q < rx_rings; q ++) {
- retval = rte_eth_rx_queue_setup(port, q, rx_ring_size,
- rte_eth_dev_socket_id(port), rxconf,
- mbuf_pool);
- if (retval < 0)
- return retval;
- }
- for (q = 0; q < tx_rings; q ++) {
- retval = rte_eth_tx_queue_setup(port, q, tx_ring_size,
- rte_eth_dev_socket_id(port),
- NULL);
- if (retval < 0)
- return retval;
- }
-
- /* Start the device. */
- retval = rte_eth_dev_start(port);
- if (retval < 0)
- return retval;
-
- rte_eth_macaddr_get(port, &vmdq_ports_eth_addr[port]);
- RTE_LOG(INFO, VHOST_PORT, "Max virtio devices supported: %u\n", num_devices);
- RTE_LOG(INFO, VHOST_PORT, "Port %u MAC: %02"PRIx8" %02"PRIx8" %02"PRIx8
- " %02"PRIx8" %02"PRIx8" %02"PRIx8"\n",
- (unsigned)port,
- vmdq_ports_eth_addr[port].addr_bytes[0],
- vmdq_ports_eth_addr[port].addr_bytes[1],
- vmdq_ports_eth_addr[port].addr_bytes[2],
- vmdq_ports_eth_addr[port].addr_bytes[3],
- vmdq_ports_eth_addr[port].addr_bytes[4],
- vmdq_ports_eth_addr[port].addr_bytes[5]);
-
- return 0;
-}
-
-/*
- * Parse the portmask provided at run time.
- */
-static int
-parse_portmask(const char *portmask)
-{
- char *end = NULL;
- unsigned long pm;
-
- errno = 0;
-
- /* parse hexadecimal string */
- pm = strtoul(portmask, &end, 16);
- if ((portmask[0] == '\0') || (end == NULL) || (*end != '\0') || (errno != 0))
- return -1;
-
- if (pm == 0)
- return -1;
-
- return pm;
-
-}
-
-/*
- * Parse num options at run time.
- */
-static int
-parse_num_opt(const char *q_arg, uint32_t max_valid_value)
-{
- char *end = NULL;
- unsigned long num;
-
- errno = 0;
-
- /* parse unsigned int string */
- num = strtoul(q_arg, &end, 10);
- if ((q_arg[0] == '\0') || (end == NULL) || (*end != '\0') || (errno != 0))
- return -1;
-
- if (num > max_valid_value)
- return -1;
-
- return num;
-
-}
-
-/*
- * Display usage
- */
-static void
-us_vhost_usage(const char *prgname)
-{
- RTE_LOG(INFO, VHOST_CONFIG, "%s [EAL options] -- -p PORTMASK --vm2vm [0|1] --stats [0-N] --nb-devices ND\n"
- " -p PORTMASK: Set mask for ports to be used by application\n"
- " --vm2vm [0|1]: disable/enable(default) vm2vm comms\n"
- " --stats [0-N]: 0: Disable stats, N: Time in seconds to print stats\n",
- prgname);
-}
-
-/*
- * Parse the arguments given in the command line of the application.
- */
-static int
-us_vhost_parse_args(int argc, char **argv)
-{
- int opt, ret;
- int option_index;
- unsigned i;
- const char *prgname = argv[0];
- static struct option long_option[] = {
- {"vm2vm", required_argument, NULL, 0},
- {"stats", required_argument, NULL, 0},
- {NULL, 0, 0, 0}
- };
-
- /* Parse command line */
- while ((opt = getopt_long(argc, argv, "p:",long_option, &option_index)) != EOF) {
- switch (opt) {
- /* Portmask */
- case 'p':
- enabled_port_mask = parse_portmask(optarg);
- if (enabled_port_mask == 0) {
- RTE_LOG(INFO, VHOST_CONFIG, "Invalid portmask\n");
- us_vhost_usage(prgname);
- return -1;
- }
- break;
-
- case 0:
- /* Enable/disable vm2vm comms. */
- if (!strncmp(long_option[option_index].name, "vm2vm", MAX_LONG_OPT_SZ)) {
- ret = parse_num_opt(optarg, 1);
- if (ret == -1) {
- RTE_LOG(INFO, VHOST_CONFIG, "Invalid argument for vm2vm [0|1]\n");
- us_vhost_usage(prgname);
- return -1;
- } else {
- enable_vm2vm = ret;
- }
- }
-
- /* Enable/disable stats. */
- if (!strncmp(long_option[option_index].name, "stats", MAX_LONG_OPT_SZ)) {
- ret = parse_num_opt(optarg, INT32_MAX);
- if (ret == -1) {
- RTE_LOG(INFO, VHOST_CONFIG, "Invalid argument for stats [0..N]\n");
- us_vhost_usage(prgname);
- return -1;
- } else {
- enable_stats = ret;
- }
- }
- break;
-
- /* Invalid option - print options. */
- default:
- us_vhost_usage(prgname);
- return -1;
- }
- }
-
- for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
- if (enabled_port_mask & (1 << i))
- ports[num_ports++] = (uint8_t)i;
- }
-
- if ((num_ports == 0) || (num_ports > MAX_SUP_PORTS)) {
- RTE_LOG(INFO, VHOST_PORT, "Current enabled port number is %u,"
- "but only %u port can be enabled\n",num_ports, MAX_SUP_PORTS);
- return -1;
- }
-
- return 0;
-}
-
-/*
- * Update the global var NUM_PORTS and array PORTS according to system ports number
- * and return valid ports number
- */
-static unsigned check_ports_num(unsigned nb_ports)
-{
- unsigned valid_num_ports = num_ports;
- unsigned portid;
-
- if (num_ports > nb_ports) {
- RTE_LOG(INFO, VHOST_PORT, "\nSpecified port number(%u) exceeds total system port number(%u)\n",
- num_ports, nb_ports);
- num_ports = nb_ports;
- }
-
- for (portid = 0; portid < num_ports; portid ++) {
- if (ports[portid] >= nb_ports) {
- RTE_LOG(INFO, VHOST_PORT, "\nSpecified port ID(%u) exceeds max system port ID(%u)\n",
- ports[portid], (nb_ports - 1));
- ports[portid] = INVALID_PORT_ID;
- valid_num_ports--;
- }
- }
- return valid_num_ports;
-}
-
-/*
- * Function to convert guest physical addresses to vhost virtual addresses. This
- * is used to convert virtio buffer addresses.
- */
-static __rte_always_inline uint64_t
-gpa_to_vva(struct virtio_net *dev, uint64_t guest_pa)
-{
- struct virtio_memory_regions *region;
- uint32_t regionidx;
- uint64_t vhost_va = 0;
-
- for (regionidx = 0; regionidx < dev->mem->nregions; regionidx++) {
- region = &dev->mem->regions[regionidx];
- if ((guest_pa >= region->guest_phys_address) &&
- (guest_pa <= region->guest_phys_address_end)) {
- vhost_va = region->address_offset + guest_pa;
- break;
- }
- }
- RTE_LOG_DP(DEBUG, VHOST_DATA, "(%" PRIu64 ") GPA %p| VVA %p\n",
- dev->device_fh, (void*)(uintptr_t)guest_pa, (void*)(uintptr_t)vhost_va);
-
- return vhost_va;
-}
-
-/*
- * This function adds buffers to the virtio devices RX virtqueue. Buffers can
- * be received from the physical port or from another virtio device. A packet
- * count is returned to indicate the number of packets that were successfully
- * added to the RX queue.
- */
-static __rte_always_inline uint32_t
-virtio_dev_rx(struct virtio_net *dev, struct rte_mbuf **pkts, uint32_t count)
-{
- struct vhost_virtqueue *vq;
- struct vring_desc *desc;
- struct rte_mbuf *buff;
- /* The virtio_hdr is initialised to 0. */
- struct virtio_net_hdr_mrg_rxbuf virtio_hdr = {{0,0,0,0,0,0},0};
- uint64_t buff_addr = 0;
- uint64_t buff_hdr_addr = 0;
- uint32_t head[MAX_PKT_BURST], packet_len = 0;
- uint32_t head_idx, packet_success = 0;
- uint16_t avail_idx, res_cur_idx;
- uint16_t res_base_idx, res_end_idx;
- uint16_t free_entries;
- uint8_t success = 0;
- void *userdata;
-
- RTE_LOG_DP(DEBUG, VHOST_DATA, "(%" PRIu64 ") virtio_dev_rx()\n", dev->device_fh);
- vq = dev->virtqueue_rx;
- count = (count > MAX_PKT_BURST) ? MAX_PKT_BURST : count;
- /* As many data cores may want access to available buffers, they need to be reserved. */
- do {
-
- res_base_idx = vq->last_used_idx_res;
-
- avail_idx = *((volatile uint16_t *)&vq->avail->idx);
-
- free_entries = (avail_idx - res_base_idx);
-
- /*check that we have enough buffers*/
- if (unlikely(count > free_entries))
- count = free_entries;
-
- if (count == 0)
- return 0;
-
- res_end_idx = res_base_idx + count;
- /* vq->last_used_idx_res is atomically updated. */
- success = rte_atomic16_cmpset(&vq->last_used_idx_res, res_base_idx,
- res_end_idx);
- } while (unlikely(success == 0));
- res_cur_idx = res_base_idx;
- RTE_LOG_DP(DEBUG, VHOST_DATA, "(%" PRIu64 ") Current Index %d| End Index %d\n",
- dev->device_fh, res_cur_idx, res_end_idx);
-
- /* Prefetch available ring to retrieve indexes. */
- rte_prefetch0(&vq->avail->ring[res_cur_idx & (vq->size - 1)]);
-
- /* Retrieve all of the head indexes first to avoid caching issues. */
- for (head_idx = 0; head_idx < count; head_idx++)
- head[head_idx] = vq->avail->ring[(res_cur_idx + head_idx) & (vq->size - 1)];
-
- /*Prefetch descriptor index. */
- rte_prefetch0(&vq->desc[head[packet_success]]);
-
- while (res_cur_idx != res_end_idx) {
- /* Get descriptor from available ring */
- desc = &vq->desc[head[packet_success]];
- /* Prefetch descriptor address. */
- rte_prefetch0(desc);
-
- buff = pkts[packet_success];
-
- /* Convert from gpa to vva (guest physical addr -> vhost virtual addr) */
- buff_addr = gpa_to_vva(dev, desc->addr);
- /* Prefetch buffer address. */
- rte_prefetch0((void*)(uintptr_t)buff_addr);
-
- {
- /* Copy virtio_hdr to packet and increment buffer address */
- buff_hdr_addr = buff_addr;
- packet_len = rte_pktmbuf_data_len(buff) + vq->vhost_hlen;
-
- /*
- * If the descriptors are chained the header and data are placed in
- * separate buffers.
- */
- if (desc->flags & VRING_DESC_F_NEXT) {
- desc->len = vq->vhost_hlen;
- desc = &vq->desc[desc->next];
- /* Buffer address translation. */
- buff_addr = gpa_to_vva(dev, desc->addr);
- desc->len = rte_pktmbuf_data_len(buff);
- } else {
- buff_addr += vq->vhost_hlen;
- desc->len = packet_len;
- }
- }
-
- /* Update used ring with desc information */
- vq->used->ring[res_cur_idx & (vq->size - 1)].id = head[packet_success];
- vq->used->ring[res_cur_idx & (vq->size - 1)].len = packet_len;
-
- /* Copy mbuf data to buffer */
- userdata = rte_pktmbuf_mtod(buff, void *);
- rte_memcpy((void *)(uintptr_t)buff_addr, userdata, rte_pktmbuf_data_len(buff));
-
- res_cur_idx++;
- packet_success++;
-
- /* mergeable is disabled then a header is required per buffer. */
- rte_memcpy((void *)(uintptr_t)buff_hdr_addr, (const void *)&virtio_hdr, vq->vhost_hlen);
- if (res_cur_idx < res_end_idx) {
- /* Prefetch descriptor index. */
- rte_prefetch0(&vq->desc[head[packet_success]]);
- }
- }
-
- rte_compiler_barrier();
-
- /* Wait until it's our turn to add our buffer to the used ring. */
- while (unlikely(vq->last_used_idx != res_base_idx))
- rte_pause();
-
- *(volatile uint16_t *)&vq->used->idx += count;
-
- vq->last_used_idx = res_end_idx;
-
- return count;
-}
-
-/*
- * Compares a packet destination MAC address to a device MAC address.
- */
-static __rte_always_inline int
-ether_addr_cmp(struct ether_addr *ea, struct ether_addr *eb)
-{
- return ((*(uint64_t *)ea ^ *(uint64_t *)eb) & MAC_ADDR_CMP) == 0;
-}
-
-/*
- * This function registers mac along with a
- * vlan tag to a VMDQ.
- */
-static int
-link_vmdq(struct virtio_net *dev)
-{
- int ret;
- struct virtio_net_data_ll *dev_ll;
-
- dev_ll = ll_root_used;
-
- while (dev_ll != NULL) {
- if ((dev != dev_ll->dev) && ether_addr_cmp(&dev->mac_address, &dev_ll->dev->mac_address)) {
- RTE_LOG(INFO, VHOST_DATA, "(%"PRIu64") WARNING: This device is using an existing MAC address and has not been registered.\n", dev->device_fh);
- return -1;
- }
- dev_ll = dev_ll->next;
- }
-
- /* vlan_tag currently uses the device_id. */
- dev->vlan_tag = vlan_tags[dev->device_fh];
- dev->vmdq_rx_q = dev->device_fh * (num_queues/num_devices);
-
- /* Print out VMDQ registration info. */
- RTE_LOG(INFO, VHOST_DATA, "(%"PRIu64") MAC_ADDRESS %02x:%02x:%02x:%02x:%02x:%02x and VLAN_TAG %d registered\n",
- dev->device_fh,
- dev->mac_address.addr_bytes[0], dev->mac_address.addr_bytes[1],
- dev->mac_address.addr_bytes[2], dev->mac_address.addr_bytes[3],
- dev->mac_address.addr_bytes[4], dev->mac_address.addr_bytes[5],
- dev->vlan_tag);
-
- /* Register the MAC address. */
- ret = rte_eth_dev_mac_addr_add(ports[0], &dev->mac_address, (uint32_t)dev->device_fh);
- if (ret) {
- RTE_LOG(ERR, VHOST_DATA, "(%"PRIu64") Failed to add device MAC address to VMDQ\n",
- dev->device_fh);
- return -1;
- }
-
- /* Enable stripping of the vlan tag as we handle routing. */
- rte_eth_dev_set_vlan_strip_on_queue(ports[0], dev->vmdq_rx_q, 1);
-
- rte_compiler_barrier();
- /* Set device as ready for RX. */
- dev->ready = DEVICE_READY;
-
- return 0;
-}
-
-/*
- * Removes MAC address and vlan tag from VMDQ. Ensures that nothing is adding buffers to the RX
- * queue before disabling RX on the device.
- */
-static inline void
-unlink_vmdq(struct virtio_net *dev)
-{
- unsigned i = 0;
- unsigned rx_count;
- struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
-
- if (dev->ready == DEVICE_READY) {
- /*clear MAC and VLAN settings*/
- rte_eth_dev_mac_addr_remove(ports[0], &dev->mac_address);
- for (i = 0; i < 6; i++)
- dev->mac_address.addr_bytes[i] = 0;
-
- dev->vlan_tag = 0;
-
- /*Clear out the receive buffers*/
- rx_count = rte_eth_rx_burst(ports[0],
- (uint16_t)dev->vmdq_rx_q, pkts_burst, MAX_PKT_BURST);
-
- while (rx_count) {
- for (i = 0; i < rx_count; i++)
- rte_pktmbuf_free(pkts_burst[i]);
-
- rx_count = rte_eth_rx_burst(ports[0],
- (uint16_t)dev->vmdq_rx_q, pkts_burst, MAX_PKT_BURST);
- }
-
- dev->ready = DEVICE_NOT_READY;
- }
-}
-
-/*
- * Check if the packet destination MAC address is for a local device. If so then put
- * the packet on that devices RX queue. If not then return.
- */
-static __rte_always_inline unsigned
-virtio_tx_local(struct virtio_net *dev, struct rte_mbuf *m)
-{
- struct virtio_net_data_ll *dev_ll;
- struct ether_hdr *pkt_hdr;
- uint64_t ret = 0;
-
- pkt_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
-
- /*get the used devices list*/
- dev_ll = ll_root_used;
-
- while (dev_ll != NULL) {
- if (likely(dev_ll->dev->ready == DEVICE_READY) && ether_addr_cmp(&(pkt_hdr->d_addr),
- &dev_ll->dev->mac_address)) {
-
- /* Drop the packet if the TX packet is destined for the TX device. */
- if (dev_ll->dev->device_fh == dev->device_fh) {
- RTE_LOG_DP(DEBUG, VHOST_DATA, "(%" PRIu64 ") TX: "
- "Source and destination MAC addresses are the same. "
- "Dropping packet.\n",
- dev_ll->dev->device_fh);
- return 0;
- }
-
-
- RTE_LOG_DP(DEBUG, VHOST_DATA, "(%" PRIu64 ") TX: "
- "MAC address is local\n", dev_ll->dev->device_fh);
-
- if (dev_ll->dev->remove) {
- /*drop the packet if the device is marked for removal*/
- RTE_LOG_DP(DEBUG, VHOST_DATA, "(%" PRIu64 ") "
- "Device is marked for removal\n",
- dev_ll->dev->device_fh);
- } else {
- /*send the packet to the local virtio device*/
- ret = virtio_dev_rx(dev_ll->dev, &m, 1);
- if (enable_stats) {
- rte_atomic64_add(&dev_statistics[dev_ll->dev->device_fh].rx_total, 1);
- rte_atomic64_add(&dev_statistics[dev_ll->dev->device_fh].rx, ret);
- dev_statistics[dev->device_fh].tx_total++;
- dev_statistics[dev->device_fh].tx += ret;
- }
- }
-
- return 0;
- }
- dev_ll = dev_ll->next;
- }
-
- return -1;
-}
-
-/*
- * This function routes the TX packet to the correct interface. This may be a local device
- * or the physical port.
- */
-static __rte_always_inline void
-virtio_tx_route(struct virtio_net* dev, struct rte_mbuf *m, struct rte_mempool *mbuf_pool, uint16_t vlan_tag)
-{
- struct mbuf_table *tx_q;
- struct vlan_ethhdr *vlan_hdr;
- struct rte_mbuf **m_table;
- struct rte_mbuf *mbuf;
- unsigned len, ret;
- const uint16_t lcore_id = rte_lcore_id();
-
- /*check if destination is local VM*/
- if (enable_vm2vm && (virtio_tx_local(dev, m) == 0)) {
- return;
- }
-
- RTE_LOG_DP(DEBUG, VHOST_DATA, "(%" PRIu64 ") TX: "
- "MAC address is external\n", dev->device_fh);
-
- /*Add packet to the port tx queue*/
- tx_q = &lcore_tx_queue[lcore_id];
- len = tx_q->len;
-
- /* Allocate an mbuf and populate the structure. */
- mbuf = rte_pktmbuf_alloc(mbuf_pool);
- if(!mbuf)
- return;
-
- mbuf->data_len = m->data_len + VLAN_HLEN;
- mbuf->pkt_len = mbuf->data_len;
-
- /* Copy ethernet header to mbuf. */
- rte_memcpy(rte_pktmbuf_mtod(mbuf, void*),
- rte_pktmbuf_mtod(m, const void*), ETH_HLEN);
-
-
- /* Setup vlan header. Bytes need to be re-ordered for network with htons()*/
- vlan_hdr = rte_pktmbuf_mtod(mbuf, struct vlan_ethhdr *);
- vlan_hdr->h_vlan_encapsulated_proto = vlan_hdr->h_vlan_proto;
- vlan_hdr->h_vlan_proto = htons(ETH_P_8021Q);
- vlan_hdr->h_vlan_TCI = htons(vlan_tag);
-
- /* Copy the remaining packet contents to the mbuf. */
- rte_memcpy(rte_pktmbuf_mtod_offset(mbuf, void *, VLAN_ETH_HLEN),
- rte_pktmbuf_mtod_offset(m, const void *, ETH_HLEN),
- (m->data_len - ETH_HLEN));
- tx_q->m_table[len] = mbuf;
- len++;
- if (enable_stats) {
- dev_statistics[dev->device_fh].tx_total++;
- dev_statistics[dev->device_fh].tx++;
- }
-
- if (unlikely(len == MAX_PKT_BURST)) {
- m_table = (struct rte_mbuf **)tx_q->m_table;
- ret = rte_eth_tx_burst(ports[0], (uint16_t)tx_q->txq_id, m_table, (uint16_t) len);
- /* Free any buffers not handled by TX and update the port stats. */
- if (unlikely(ret < len)) {
- do {
- rte_pktmbuf_free(m_table[ret]);
- } while (++ret < len);
- }
-
- len = 0;
- }
-
- tx_q->len = len;
- return;
-}
-
-static __rte_always_inline void
-virtio_dev_tx(struct virtio_net* dev, struct rte_mempool *mbuf_pool)
-{
- struct rte_mbuf m;
- struct vhost_virtqueue *vq;
- struct vring_desc *desc;
- uint64_t buff_addr = 0;
- uint32_t head[MAX_PKT_BURST];
- uint32_t used_idx;
- uint32_t i;
- uint16_t free_entries, packet_success = 0;
- uint16_t avail_idx;
-
- vq = dev->virtqueue_tx;
- avail_idx = *((volatile uint16_t *)&vq->avail->idx);
-
- /* If there are no available buffers then return. */
- if (vq->last_used_idx == avail_idx)
- return;
-
- RTE_LOG_DP(DEBUG, VHOST_DATA, "(%" PRIu64 ") virtio_dev_tx()\n",
- dev->device_fh);
-
- /* Prefetch available ring to retrieve head indexes. */
- rte_prefetch0(&vq->avail->ring[vq->last_used_idx & (vq->size - 1)]);
-
- /*get the number of free entries in the ring*/
- free_entries = avail_idx - vq->last_used_idx;
- free_entries = unlikely(free_entries < MAX_PKT_BURST) ? free_entries : MAX_PKT_BURST;
-
- RTE_LOG_DP(DEBUG, VHOST_DATA, "(%" PRIu64 ") Buffers available %d\n",
- dev->device_fh, free_entries);
- /* Retrieve all of the head indexes first to avoid caching issues. */
- for (i = 0; i < free_entries; i++)
- head[i] = vq->avail->ring[(vq->last_used_idx + i) & (vq->size - 1)];
-
- /* Prefetch descriptor index. */
- rte_prefetch0(&vq->desc[head[packet_success]]);
-
- while (packet_success < free_entries) {
- desc = &vq->desc[head[packet_success]];
- /* Prefetch descriptor address. */
- rte_prefetch0(desc);
-
- if (packet_success < (free_entries - 1)) {
- /* Prefetch descriptor index. */
- rte_prefetch0(&vq->desc[head[packet_success+1]]);
- }
-
- /* Update used index buffer information. */
- used_idx = vq->last_used_idx & (vq->size - 1);
- vq->used->ring[used_idx].id = head[packet_success];
- vq->used->ring[used_idx].len = 0;
-
- /* Discard first buffer as it is the virtio header */
- desc = &vq->desc[desc->next];
-
- /* Buffer address translation. */
- buff_addr = gpa_to_vva(dev, desc->addr);
- /* Prefetch buffer address. */
- rte_prefetch0((void*)(uintptr_t)buff_addr);
-
- /* Setup dummy mbuf. This is copied to a real mbuf if transmitted out the physical port. */
- m.data_len = desc->len;
- m.data_off = 0;
- m.nb_segs = 1;
-
- virtio_tx_route(dev, &m, mbuf_pool, 0);
-
- vq->last_used_idx++;
- packet_success++;
- }
-
- rte_compiler_barrier();
- vq->used->idx += packet_success;
- /* Kick guest if required. */
-}
-
-/*
- * This function is called by each data core. It handles all RX/TX registered with the
- * core. For TX the specific lcore linked list is used. For RX, MAC addresses are compared
- * with all devices in the main linked list.
- */
-static int
-switch_worker(__attribute__((unused)) void *arg)
-{
- struct rte_mempool *mbuf_pool = arg;
- struct virtio_net *dev = NULL;
- struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
- struct virtio_net_data_ll *dev_ll;
- struct mbuf_table *tx_q;
- volatile struct lcore_ll_info *lcore_ll;
- const uint64_t drain_tsc = (rte_get_tsc_hz() + US_PER_S - 1) / US_PER_S * BURST_TX_DRAIN_US;
- uint64_t prev_tsc, diff_tsc, cur_tsc, ret_count = 0;
- unsigned ret, i;
- const uint16_t lcore_id = rte_lcore_id();
- const uint16_t num_cores = (uint16_t)rte_lcore_count();
- uint16_t rx_count = 0;
-
- RTE_LOG(INFO, VHOST_DATA, "Procesing on Core %u started \n", lcore_id);
- lcore_ll = lcore_info[lcore_id].lcore_ll;
- prev_tsc = 0;
-
- tx_q = &lcore_tx_queue[lcore_id];
- for (i = 0; i < num_cores; i ++) {
- if (lcore_ids[i] == lcore_id) {
- tx_q->txq_id = i;
- break;
- }
- }
-
- while(1) {
- cur_tsc = rte_rdtsc();
- /*
- * TX burst queue drain
- */
- diff_tsc = cur_tsc - prev_tsc;
- if (unlikely(diff_tsc > drain_tsc)) {
-
- if (tx_q->len) {
- RTE_LOG_DP(DEBUG, VHOST_DATA,
- "TX queue drained after timeout with burst size %u\n",
- tx_q->len);
-
- /*Tx any packets in the queue*/
- ret = rte_eth_tx_burst(ports[0], (uint16_t)tx_q->txq_id,
- (struct rte_mbuf **)tx_q->m_table,
- (uint16_t)tx_q->len);
- if (unlikely(ret < tx_q->len)) {
- do {
- rte_pktmbuf_free(tx_q->m_table[ret]);
- } while (++ret < tx_q->len);
- }
-
- tx_q->len = 0;
- }
-
- prev_tsc = cur_tsc;
-
- }
-
- /*
- * Inform the configuration core that we have exited the linked list and that no devices are
- * in use if requested.
- */
- if (lcore_ll->dev_removal_flag == REQUEST_DEV_REMOVAL)
- lcore_ll->dev_removal_flag = ACK_DEV_REMOVAL;
-
- /*
- * Process devices
- */
- dev_ll = lcore_ll->ll_root_used;
-
- while (dev_ll != NULL) {
- /*get virtio device ID*/
- dev = dev_ll->dev;
-
- if (unlikely(dev->remove)) {
- dev_ll = dev_ll->next;
- unlink_vmdq(dev);
- dev->ready = DEVICE_SAFE_REMOVE;
- continue;
- }
- if (likely(dev->ready == DEVICE_READY)) {
- /*Handle guest RX*/
- rx_count = rte_eth_rx_burst(ports[0],
- (uint16_t)dev->vmdq_rx_q, pkts_burst, MAX_PKT_BURST);
-
- if (rx_count) {
- ret_count = virtio_dev_rx(dev, pkts_burst, rx_count);
- if (enable_stats) {
- rte_atomic64_add(&dev_statistics[dev_ll->dev->device_fh].rx_total, rx_count);
- rte_atomic64_add(&dev_statistics[dev_ll->dev->device_fh].rx, ret_count);
- }
- while (likely(rx_count)) {
- rx_count--;
- rte_pktmbuf_free_seg(pkts_burst[rx_count]);
- }
-
- }
- }
-
- if (likely(!dev->remove))
- /*Handle guest TX*/
- virtio_dev_tx(dev, mbuf_pool);
-
- /*move to the next device in the list*/
- dev_ll = dev_ll->next;
- }
- }
-
- return 0;
-}
-
-/*
- * Add an entry to a used linked list. A free entry must first be found in the free linked list
- * using get_data_ll_free_entry();
- */
-static void
-add_data_ll_entry(struct virtio_net_data_ll **ll_root_addr, struct virtio_net_data_ll *ll_dev)
-{
- struct virtio_net_data_ll *ll = *ll_root_addr;
-
- /* Set next as NULL and use a compiler barrier to avoid reordering. */
- ll_dev->next = NULL;
- rte_compiler_barrier();
-
- /* If ll == NULL then this is the first device. */
- if (ll) {
- /* Increment to the tail of the linked list. */
- while ((ll->next != NULL) )
- ll = ll->next;
-
- ll->next = ll_dev;
- } else {
- *ll_root_addr = ll_dev;
- }
-}
-
-/*
- * Remove an entry from a used linked list. The entry must then be added to the free linked list
- * using put_data_ll_free_entry().
- */
-static void
-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)
-{
- struct virtio_net_data_ll *ll = *ll_root_addr;
-
- if (ll_dev == ll)
- *ll_root_addr = ll_dev->next;
- else
- ll_dev_last->next = ll_dev->next;
-}
-
-/*
- * Find and return an entry from the free linked list.
- */
-static struct virtio_net_data_ll *
-get_data_ll_free_entry(struct virtio_net_data_ll **ll_root_addr)
-{
- struct virtio_net_data_ll *ll_free = *ll_root_addr;
- struct virtio_net_data_ll *ll_dev;
-
- if (ll_free == NULL)
- return NULL;
-
- ll_dev = ll_free;
- *ll_root_addr = ll_free->next;
-
- return ll_dev;
-}
-
-/*
- * Place an entry back on to the free linked list.
- */
-static void
-put_data_ll_free_entry(struct virtio_net_data_ll **ll_root_addr, struct virtio_net_data_ll *ll_dev)
-{
- struct virtio_net_data_ll *ll_free = *ll_root_addr;
-
- ll_dev->next = ll_free;
- *ll_root_addr = ll_dev;
-}
-
-/*
- * Creates a linked list of a given size.
- */
-static struct virtio_net_data_ll *
-alloc_data_ll(uint32_t size)
-{
- struct virtio_net_data_ll *ll_new;
- uint32_t i;
-
- /* Malloc and then chain the linked list. */
- ll_new = malloc(size * sizeof(struct virtio_net_data_ll));
- if (ll_new == NULL) {
- RTE_LOG(ERR, VHOST_CONFIG, "Failed to allocate memory for ll_new.\n");
- return NULL;
- }
-
- for (i = 0; i < size - 1; i++) {
- ll_new[i].dev = NULL;
- ll_new[i].next = &ll_new[i+1];
- }
- ll_new[i].next = NULL;
-
- return ll_new;
-}
-
-/*
- * Create the main linked list along with each individual cores linked list. A used and a free list
- * are created to manage entries.
- */
-static int
-init_data_ll (void)
-{
- int lcore;
-
- RTE_LCORE_FOREACH_SLAVE(lcore) {
- lcore_info[lcore].lcore_ll = malloc(sizeof(struct lcore_ll_info));
- if (lcore_info[lcore].lcore_ll == NULL) {
- RTE_LOG(ERR, VHOST_CONFIG, "Failed to allocate memory for lcore_ll.\n");
- return -1;
- }
-
- lcore_info[lcore].lcore_ll->device_num = 0;
- lcore_info[lcore].lcore_ll->dev_removal_flag = ACK_DEV_REMOVAL;
- lcore_info[lcore].lcore_ll->ll_root_used = NULL;
- if (num_devices % num_switching_cores)
- lcore_info[lcore].lcore_ll->ll_root_free = alloc_data_ll((num_devices / num_switching_cores) + 1);
- else
- lcore_info[lcore].lcore_ll->ll_root_free = alloc_data_ll(num_devices / num_switching_cores);
- }
-
- /* Allocate devices up to a maximum of MAX_DEVICES. */
- ll_root_free = alloc_data_ll(MIN((num_devices), MAX_DEVICES));
-
- return 0;
-}
-/*
- * Remove a device from the specific data core linked list and from the main linked list. The
- * rx/tx thread must be set the flag to indicate that it is safe to remove the device.
- * used.
- */
-static void
-destroy_device (volatile struct virtio_net *dev)
-{
- struct virtio_net_data_ll *ll_lcore_dev_cur;
- struct virtio_net_data_ll *ll_main_dev_cur;
- struct virtio_net_data_ll *ll_lcore_dev_last = NULL;
- struct virtio_net_data_ll *ll_main_dev_last = NULL;
- int lcore;
-
- dev->flags &= ~VIRTIO_DEV_RUNNING;
-
- /*set the remove flag. */
- dev->remove = 1;
-
- while(dev->ready != DEVICE_SAFE_REMOVE) {
- rte_pause();
- }
-
- /* Search for entry to be removed from lcore ll */
- ll_lcore_dev_cur = lcore_info[dev->coreid].lcore_ll->ll_root_used;
- while (ll_lcore_dev_cur != NULL) {
- if (ll_lcore_dev_cur->dev == dev) {
- break;
- } else {
- ll_lcore_dev_last = ll_lcore_dev_cur;
- ll_lcore_dev_cur = ll_lcore_dev_cur->next;
- }
- }
-
- /* Search for entry to be removed from main ll */
- ll_main_dev_cur = ll_root_used;
- ll_main_dev_last = NULL;
- while (ll_main_dev_cur != NULL) {
- if (ll_main_dev_cur->dev == dev) {
- break;
- } else {
- ll_main_dev_last = ll_main_dev_cur;
- ll_main_dev_cur = ll_main_dev_cur->next;
- }
- }
-
- if (ll_lcore_dev_cur == NULL || ll_main_dev_cur == NULL) {
- RTE_LOG(ERR, XENHOST, "%s: could find device in per_cpu list or main_list\n", __func__);
- return;
- }
-
- /* Remove entries from the lcore and main ll. */
- rm_data_ll_entry(&lcore_info[ll_lcore_dev_cur->dev->coreid].lcore_ll->ll_root_used, ll_lcore_dev_cur, ll_lcore_dev_last);
- rm_data_ll_entry(&ll_root_used, ll_main_dev_cur, ll_main_dev_last);
-
- /* Set the dev_removal_flag on each lcore. */
- RTE_LCORE_FOREACH_SLAVE(lcore) {
- lcore_info[lcore].lcore_ll->dev_removal_flag = REQUEST_DEV_REMOVAL;
- }
-
- /*
- * Once each core has set the dev_removal_flag to ACK_DEV_REMOVAL we can be sure that
- * they can no longer access the device removed from the linked lists and that the devices
- * are no longer in use.
- */
- RTE_LCORE_FOREACH_SLAVE(lcore) {
- while (lcore_info[lcore].lcore_ll->dev_removal_flag != ACK_DEV_REMOVAL) {
- rte_pause();
- }
- }
-
- /* Add the entries back to the lcore and main free ll.*/
- put_data_ll_free_entry(&lcore_info[ll_lcore_dev_cur->dev->coreid].lcore_ll->ll_root_free, ll_lcore_dev_cur);
- put_data_ll_free_entry(&ll_root_free, ll_main_dev_cur);
-
- /* Decrement number of device on the lcore. */
- lcore_info[ll_lcore_dev_cur->dev->coreid].lcore_ll->device_num--;
-
- RTE_LOG(INFO, VHOST_DATA, " #####(%"PRIu64") Device has been removed from data core\n", dev->device_fh);
-}
-
-/*
- * A new device is added to a data core. First the device is added to the main linked list
- * and the allocated to a specific data core.
- */
-static int
-new_device (struct virtio_net *dev)
-{
- struct virtio_net_data_ll *ll_dev;
- int lcore, core_add = 0;
- uint32_t device_num_min = num_devices;
-
- /* Add device to main ll */
- ll_dev = get_data_ll_free_entry(&ll_root_free);
- if (ll_dev == NULL) {
- RTE_LOG(INFO, VHOST_DATA, "(%"PRIu64") No free entry found in linked list. Device limit "
- "of %d devices per core has been reached\n",
- dev->device_fh, num_devices);
- return -1;
- }
- ll_dev->dev = dev;
- add_data_ll_entry(&ll_root_used, ll_dev);
-
- /*reset ready flag*/
- dev->ready = DEVICE_NOT_READY;
- dev->remove = 0;
-
- /* Find a suitable lcore to add the device. */
- RTE_LCORE_FOREACH_SLAVE(lcore) {
- if (lcore_info[lcore].lcore_ll->device_num < device_num_min) {
- device_num_min = lcore_info[lcore].lcore_ll->device_num;
- core_add = lcore;
- }
- }
- /* Add device to lcore ll */
- ll_dev->dev->coreid = core_add;
- ll_dev = get_data_ll_free_entry(&lcore_info[ll_dev->dev->coreid].lcore_ll->ll_root_free);
- if (ll_dev == NULL) {
- RTE_LOG(INFO, VHOST_DATA, "(%"PRIu64") Failed to add device to data core\n", dev->device_fh);
- destroy_device(dev);
- return -1;
- }
- ll_dev->dev = dev;
- add_data_ll_entry(&lcore_info[ll_dev->dev->coreid].lcore_ll->ll_root_used, ll_dev);
-
- /* Initialize device stats */
- memset(&dev_statistics[dev->device_fh], 0, sizeof(struct device_statistics));
-
- lcore_info[ll_dev->dev->coreid].lcore_ll->device_num++;
- dev->flags |= VIRTIO_DEV_RUNNING;
-
- RTE_LOG(INFO, VHOST_DATA, "(%"PRIu64") Device has been added to data core %d\n", dev->device_fh, dev->coreid);
-
- link_vmdq(dev);
-
- return 0;
-}
-
-/*
- * These callback allow devices to be added to the data core when configuration
- * has been fully complete.
- */
-static const struct virtio_net_device_ops virtio_net_device_ops =
-{
- .new_device = new_device,
- .destroy_device = destroy_device,
-};
-
-/*
- * This is a thread will wake up after a period to print stats if the user has
- * enabled them.
- */
-static void
-print_stats(void)
-{
- struct virtio_net_data_ll *dev_ll;
- uint64_t tx_dropped, rx_dropped;
- uint64_t tx, tx_total, rx, rx_total;
- uint32_t device_fh;
- const char clr[] = { 27, '[', '2', 'J', '\0' };
- const char top_left[] = { 27, '[', '1', ';', '1', 'H','\0' };
-
- while(1) {
- sleep(enable_stats);
-
- /* Clear screen and move to top left */
- printf("%s%s", clr, top_left);
-
- printf("\nDevice statistics ====================================");
-
- dev_ll = ll_root_used;
- while (dev_ll != NULL) {
- device_fh = (uint32_t)dev_ll->dev->device_fh;
- tx_total = dev_statistics[device_fh].tx_total;
- tx = dev_statistics[device_fh].tx;
- tx_dropped = tx_total - tx;
- rx_total = rte_atomic64_read(&dev_statistics[device_fh].rx_total);
- rx = rte_atomic64_read(&dev_statistics[device_fh].rx);
- rx_dropped = rx_total - rx;
-
- printf("\nStatistics for device %"PRIu32" ------------------------------"
- "\nTX total: %"PRIu64""
- "\nTX dropped: %"PRIu64""
- "\nTX successful: %"PRIu64""
- "\nRX total: %"PRIu64""
- "\nRX dropped: %"PRIu64""
- "\nRX successful: %"PRIu64"",
- device_fh,
- tx_total,
- tx_dropped,
- tx,
- rx_total,
- rx_dropped,
- rx);
-
- dev_ll = dev_ll->next;
- }
- printf("\n======================================================\n");
- }
-}
-
-
-int init_virtio_net(struct virtio_net_device_ops const * const ops);
-
-/*
- * Main function, does initialisation and calls the per-lcore functions.
- */
-int
-main(int argc, char *argv[])
-{
- struct rte_mempool *mbuf_pool;
- unsigned lcore_id, core_id = 0;
- unsigned nb_ports, valid_num_ports;
- int ret;
- uint8_t portid;
- static pthread_t tid;
- char thread_name[RTE_MAX_THREAD_NAME_LEN];
-
- /* init EAL */
- ret = rte_eal_init(argc, argv);
- if (ret < 0)
- rte_exit(EXIT_FAILURE, "Error with EAL initialization\n");
- argc -= ret;
- argv += ret;
-
- /* parse app arguments */
- ret = us_vhost_parse_args(argc, argv);
- if (ret < 0)
- rte_exit(EXIT_FAILURE, "Invalid argument\n");
-
- for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id ++)
- if (rte_lcore_is_enabled(lcore_id))
- lcore_ids[core_id ++] = lcore_id;
-
- if (rte_lcore_count() > RTE_MAX_LCORE)
- rte_exit(EXIT_FAILURE,"Not enough cores\n");
-
- /*set the number of swithcing cores available*/
- num_switching_cores = rte_lcore_count()-1;
-
- /* Get the number of physical ports. */
- nb_ports = rte_eth_dev_count();
-
- /*
- * Update the global var NUM_PORTS and global array PORTS
- * and get value of var VALID_NUM_PORTS according to system ports number
- */
- valid_num_ports = check_ports_num(nb_ports);
-
- if ((valid_num_ports == 0) || (valid_num_ports > MAX_SUP_PORTS)) {
- RTE_LOG(INFO, VHOST_PORT, "Current enabled port number is %u,"
- "but only %u port can be enabled\n",num_ports, MAX_SUP_PORTS);
- return -1;
- }
-
- /* Create the mbuf pool. */
- mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL",
- NUM_MBUFS_PER_PORT * valid_num_ports, MBUF_CACHE_SIZE, 0,
- RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
- if (mbuf_pool == NULL)
- rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n");
-
- /* initialize all ports */
- for (portid = 0; portid < nb_ports; portid++) {
- /* skip ports that are not enabled */
- if ((enabled_port_mask & (1 << portid)) == 0) {
- RTE_LOG(INFO, VHOST_PORT, "Skipping disabled port %d\n", portid);
- continue;
- }
- if (port_init(portid, mbuf_pool) != 0)
- rte_exit(EXIT_FAILURE, "Cannot initialize network ports\n");
- }
-
- /* Initialise all linked lists. */
- if (init_data_ll() == -1)
- rte_exit(EXIT_FAILURE, "Failed to initialize linked list\n");
-
- /* Initialize device stats */
- memset(&dev_statistics, 0, sizeof(dev_statistics));
-
- /* Enable stats if the user option is set. */
- if (enable_stats) {
- ret = pthread_create(&tid, NULL, (void *)print_stats, NULL);
- if (ret != 0)
- rte_exit(EXIT_FAILURE,
- "Cannot create print-stats thread\n");
-
- /* Set thread_name for aid in debugging. */
- snprintf(thread_name, RTE_MAX_THREAD_NAME_LEN, "print-xen-stats");
- ret = rte_thread_setname(tid, thread_name);
- if (ret != 0)
- RTE_LOG(DEBUG, VHOST_CONFIG,
- "Cannot set print-stats name\n");
- }
-
- /* Launch all data cores. */
- RTE_LCORE_FOREACH_SLAVE(lcore_id) {
- rte_eal_remote_launch(switch_worker, mbuf_pool, lcore_id);
- }
-
- init_virtio_xen(&virtio_net_device_ops);
-
- virtio_monitor_loop();
- return 0;
-}
diff --git a/examples/vhost_xen/main.h b/examples/vhost_xen/main.h
deleted file mode 100644
index 5ff48fd..0000000
--- a/examples/vhost_xen/main.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*-
- * BSD LICENSE
- *
- * Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Intel Corporation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _MAIN_H_
-#define _MAIN_H_
-
-/* Macros for printing using RTE_LOG */
-#define RTE_LOGTYPE_VHOST_CONFIG RTE_LOGTYPE_USER1
-#define RTE_LOGTYPE_VHOST_DATA RTE_LOGTYPE_USER2
-#define RTE_LOGTYPE_VHOST_PORT RTE_LOGTYPE_USER3
-
-/*
- * Device linked list structure for data path.
- */
-struct virtio_net_data_ll
-{
- struct virtio_net *dev; /* Pointer to device created by configuration core. */
- struct virtio_net_data_ll *next; /* Pointer to next device in linked list. */
-};
-
-/*
- * Structure containing data core specific information.
- */
-struct lcore_ll_info
-{
- struct virtio_net_data_ll *ll_root_free; /* Pointer to head in free linked list. */
- struct virtio_net_data_ll *ll_root_used; /* Pointer to head of used linked list. */
- uint32_t device_num; /* Number of devices on lcore. */
- volatile uint8_t dev_removal_flag; /* Flag to synchronize device removal. */
-};
-
-struct lcore_info
-{
- struct lcore_ll_info *lcore_ll; /* Pointer to data core specific lcore_ll_info struct */
-};
-#endif /* _MAIN_H_ */
diff --git a/examples/vhost_xen/vhost_monitor.c b/examples/vhost_xen/vhost_monitor.c
deleted file mode 100644
index fb9606b..0000000
--- a/examples/vhost_xen/vhost_monitor.c
+++ /dev/null
@@ -1,595 +0,0 @@
-/*-
- * BSD LICENSE
- *
- * Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Intel Corporation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <dirent.h>
-#include <unistd.h>
-#include <sys/eventfd.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <xen/xen-compat.h>
-#if __XEN_LATEST_INTERFACE_VERSION__ < 0x00040200
-#include <xs.h>
-#else
-#include <xenstore.h>
-#endif
-#include <linux/virtio_ring.h>
-#include <linux/virtio_pci.h>
-#include <linux/virtio_net.h>
-
-#include <rte_ethdev.h>
-#include <rte_log.h>
-#include <rte_malloc.h>
-#include <rte_string_fns.h>
-
-#include "virtio-net.h"
-#include "xen_vhost.h"
-
-struct virtio_watch {
- struct xs_handle *xs;
- int watch_fd;
-};
-
-
-/* device ops to add/remove device to/from data core. */
-static struct virtio_net_device_ops const *notify_ops;
-
-/* root address of the linked list in the configuration core. */
-static struct virtio_net_config_ll *ll_root = NULL;
-
-/* root address of VM. */
-static struct xen_guestlist guest_root;
-
-static struct virtio_watch watch;
-
-static void
-vq_vring_init(struct vhost_virtqueue *vq, unsigned int num, uint8_t *p,
- unsigned long align)
-{
- vq->size = num;
- vq->desc = (struct vring_desc *) p;
- vq->avail = (struct vring_avail *) (p +
- num * sizeof(struct vring_desc));
- vq->used = (void *)
- RTE_ALIGN_CEIL( (uintptr_t)(&vq->avail->ring[num]), align);
-
-}
-
-static int
-init_watch(void)
-{
- struct xs_handle *xs;
- int ret;
- int fd;
-
- /* get a connection to the daemon */
- xs = xs_daemon_open();
- if (xs == NULL) {
- RTE_LOG(ERR, XENHOST, "xs_daemon_open failed\n");
- return -1;
- }
-
- ret = xs_watch(xs, "/local/domain", "mytoken");
- if (ret == 0) {
- RTE_LOG(ERR, XENHOST, "%s: xs_watch failed\n", __func__);
- xs_daemon_close(xs);
- return -1;
- }
-
- /* We are notified of read availability on the watch via the file descriptor. */
- fd = xs_fileno(xs);
- watch.xs = xs;
- watch.watch_fd = fd;
-
- TAILQ_INIT(&guest_root);
- return 0;
-}
-
-static struct xen_guest *
-get_xen_guest(int dom_id)
-{
- struct xen_guest *guest = NULL;
-
- TAILQ_FOREACH(guest, &guest_root, next) {
- if(guest->dom_id == dom_id)
- return guest;
- }
-
- return NULL;
-}
-
-
-static struct xen_guest *
-add_xen_guest(int32_t dom_id)
-{
- struct xen_guest *guest = NULL;
-
- if ((guest = get_xen_guest(dom_id)) != NULL)
- return guest;
-
- guest = calloc(1, sizeof(struct xen_guest));
- if (guest) {
- RTE_LOG(ERR, XENHOST, " %s: return newly created guest with %d rings\n", __func__, guest->vring_num);
- TAILQ_INSERT_TAIL(&guest_root, guest, next);
- guest->dom_id = dom_id;
- }
-
- return guest;
-}
-
-static void
-cleanup_device(struct virtio_net_config_ll *ll_dev)
-{
- if (ll_dev == NULL)
- return;
- if (ll_dev->dev.virtqueue_rx) {
- rte_free(ll_dev->dev.virtqueue_rx);
- ll_dev->dev.virtqueue_rx = NULL;
- }
- if (ll_dev->dev.virtqueue_tx) {
- rte_free(ll_dev->dev.virtqueue_tx);
- ll_dev->dev.virtqueue_tx = NULL;
- }
- free(ll_dev);
-}
-
-/*
- * Add entry containing a device to the device configuration linked list.
- */
-static void
-add_config_ll_entry(struct virtio_net_config_ll *new_ll_dev)
-{
- struct virtio_net_config_ll *ll_dev = ll_root;
-
- /* If ll_dev == NULL then this is the first device so go to else */
- if (ll_dev) {
- /* If the 1st device_id != 0 then we insert our device here. */
- if (ll_dev->dev.device_fh != 0) {
- new_ll_dev->dev.device_fh = 0;
- new_ll_dev->next = ll_dev;
- ll_root = new_ll_dev;
- } else {
- /* increment through the ll until we find un unused device_id,
- * insert the device at that entry
- */
- while ((ll_dev->next != NULL) && (ll_dev->dev.device_fh == (ll_dev->next->dev.device_fh - 1)))
- ll_dev = ll_dev->next;
-
- new_ll_dev->dev.device_fh = ll_dev->dev.device_fh + 1;
- new_ll_dev->next = ll_dev->next;
- ll_dev->next = new_ll_dev;
- }
- } else {
- ll_root = new_ll_dev;
- ll_root->dev.device_fh = 0;
- }
-}
-
-
-/*
- * Remove an entry from the device configuration linked list.
- */
-static struct virtio_net_config_ll *
-rm_config_ll_entry(struct virtio_net_config_ll *ll_dev, struct virtio_net_config_ll *ll_dev_last)
-{
- /* First remove the device and then clean it up. */
- if (ll_dev == ll_root) {
- ll_root = ll_dev->next;
- cleanup_device(ll_dev);
- return ll_root;
- } else {
- ll_dev_last->next = ll_dev->next;
- cleanup_device(ll_dev);
- return ll_dev_last->next;
- }
-}
-
-/*
- * Retrieves an entry from the devices configuration linked list.
- */
-static struct virtio_net_config_ll *
-get_config_ll_entry(unsigned int virtio_idx, unsigned int dom_id)
-{
- struct virtio_net_config_ll *ll_dev = ll_root;
-
- /* Loop through linked list until the dom_id is found. */
- while (ll_dev != NULL) {
- if (ll_dev->dev.dom_id == dom_id && ll_dev->dev.virtio_idx == virtio_idx)
- return ll_dev;
- ll_dev = ll_dev->next;
- }
-
- return NULL;
-}
-
-/*
- * Initialise all variables in device structure.
- */
-static void
-init_dev(struct virtio_net *dev)
-{
- RTE_SET_USED(dev);
-}
-
-
-static struct
-virtio_net_config_ll *new_device(unsigned int virtio_idx, struct xen_guest *guest)
-{
- struct virtio_net_config_ll *new_ll_dev;
- struct vhost_virtqueue *virtqueue_rx, *virtqueue_tx;
- size_t size, vq_ring_size, vq_size = VQ_DESC_NUM;
- void *vq_ring_virt_mem;
- uint64_t gpa;
- uint32_t i;
-
- /* Setup device and virtqueues. */
- new_ll_dev = calloc(1, sizeof(struct virtio_net_config_ll));
- virtqueue_rx = rte_zmalloc(NULL, sizeof(struct vhost_virtqueue), RTE_CACHE_LINE_SIZE);
- virtqueue_tx = rte_zmalloc(NULL, sizeof(struct vhost_virtqueue), RTE_CACHE_LINE_SIZE);
- if (new_ll_dev == NULL || virtqueue_rx == NULL || virtqueue_tx == NULL)
- goto err;
-
- new_ll_dev->dev.virtqueue_rx = virtqueue_rx;
- new_ll_dev->dev.virtqueue_tx = virtqueue_tx;
- new_ll_dev->dev.dom_id = guest->dom_id;
- new_ll_dev->dev.virtio_idx = virtio_idx;
- /* Initialise device and virtqueues. */
- init_dev(&new_ll_dev->dev);
-
- size = vring_size(vq_size, VIRTIO_PCI_VRING_ALIGN);
- vq_ring_size = RTE_ALIGN_CEIL(size, VIRTIO_PCI_VRING_ALIGN);
- (void)vq_ring_size;
-
- vq_ring_virt_mem = guest->vring[virtio_idx].rxvring_addr;
- vq_vring_init(virtqueue_rx, vq_size, vq_ring_virt_mem, VIRTIO_PCI_VRING_ALIGN);
- virtqueue_rx->size = vq_size;
- virtqueue_rx->vhost_hlen = sizeof(struct virtio_net_hdr);
-
- vq_ring_virt_mem = guest->vring[virtio_idx].txvring_addr;
- vq_vring_init(virtqueue_tx, vq_size, vq_ring_virt_mem, VIRTIO_PCI_VRING_ALIGN);
- virtqueue_tx->size = vq_size;
- memcpy(&new_ll_dev->dev.mac_address, &guest->vring[virtio_idx].addr, sizeof(struct ether_addr));
-
- /* virtio_memory has to be one per domid */
- new_ll_dev->dev.mem = malloc(sizeof(struct virtio_memory) + sizeof(struct virtio_memory_regions) * MAX_XENVIRT_MEMPOOL);
- new_ll_dev->dev.mem->nregions = guest->pool_num;
- for (i = 0; i < guest->pool_num; i++) {
- gpa = new_ll_dev->dev.mem->regions[i].guest_phys_address =
- (uint64_t)((uintptr_t)guest->mempool[i].gva);
- new_ll_dev->dev.mem->regions[i].guest_phys_address_end =
- gpa + guest->mempool[i].mempfn_num * getpagesize();
- new_ll_dev->dev.mem->regions[i].address_offset =
- (uint64_t)((uintptr_t)guest->mempool[i].hva -
- (uintptr_t)gpa);
- }
-
- new_ll_dev->next = NULL;
-
- /* Add entry to device configuration linked list. */
- add_config_ll_entry(new_ll_dev);
- return new_ll_dev;
-err:
- free(new_ll_dev);
- rte_free(virtqueue_rx);
- rte_free(virtqueue_tx);
-
- return NULL;
-}
-
-static void
-destroy_guest(struct xen_guest *guest)
-{
- uint32_t i;
-
- for (i = 0; i < guest->vring_num; i++)
- cleanup_vring(&guest->vring[i]);
- /* clean mempool */
- for (i = 0; i < guest->pool_num; i++)
- cleanup_mempool(&guest->mempool[i]);
- free(guest);
-
- return;
-}
-
-/*
- * This function will cleanup the device and remove it from device configuration linked list.
- */
-static void
-destroy_device(unsigned int virtio_idx, unsigned int dom_id)
-{
- struct virtio_net_config_ll *ll_dev_cur_ctx, *ll_dev_last = NULL;
- struct virtio_net_config_ll *ll_dev_cur = ll_root;
-
- /* clean virtio device */
- struct xen_guest *guest = NULL;
- guest = get_xen_guest(dom_id);
- if (guest == NULL)
- return;
-
- /* Find the linked list entry for the device to be removed. */
- ll_dev_cur_ctx = get_config_ll_entry(virtio_idx, dom_id);
- while (ll_dev_cur != NULL) {
- /* If the device is found or a device that doesn't exist is found then it is removed. */
- if (ll_dev_cur == ll_dev_cur_ctx) {
- if ((ll_dev_cur->dev.flags & VIRTIO_DEV_RUNNING))
- notify_ops->destroy_device(&(ll_dev_cur->dev));
- ll_dev_cur = rm_config_ll_entry(ll_dev_cur, ll_dev_last);
- } else {
- ll_dev_last = ll_dev_cur;
- ll_dev_cur = ll_dev_cur->next;
- }
- }
- RTE_LOG(INFO, XENHOST, " %s guest:%p vring:%p rxvring:%p txvring:%p flag:%p\n",
- __func__, guest, &guest->vring[virtio_idx], guest->vring[virtio_idx].rxvring_addr, guest->vring[virtio_idx].txvring_addr, guest->vring[virtio_idx].flag);
- cleanup_vring(&guest->vring[virtio_idx]);
- guest->vring[virtio_idx].removed = 1;
- guest->vring_num -= 1;
-}
-
-
-
-
-static void
-watch_unmap_event(void)
-{
- int i;
- struct xen_guest *guest = NULL;
- bool remove_request;
-
- TAILQ_FOREACH(guest, &guest_root, next) {
- for (i = 0; i < MAX_VIRTIO; i++) {
- if (guest->vring[i].dom_id && guest->vring[i].removed == 0 && *guest->vring[i].flag == 0) {
- RTE_LOG(INFO, XENHOST, "\n\n");
- RTE_LOG(INFO, XENHOST, " #####%s: (%d, %d) to be removed\n",
- __func__,
- guest->vring[i].dom_id,
- i);
- destroy_device(i, guest->dom_id);
- RTE_LOG(INFO, XENHOST, " %s: DOM %u, vring num: %d\n",
- __func__,
- guest->dom_id,
- guest->vring_num);
- }
- }
- }
-
-_find_next_remove:
- guest = NULL;
- remove_request = false;
- TAILQ_FOREACH(guest, &guest_root, next) {
- if (guest->vring_num == 0) {
- remove_request = true;
- break;
- }
- }
- if (remove_request == true) {
- TAILQ_REMOVE(&guest_root, guest, next);
- RTE_LOG(INFO, XENHOST, " #####%s: destroy guest (%d)\n", __func__, guest->dom_id);
- destroy_guest(guest);
- goto _find_next_remove;
- }
- return;
-}
-
-/*
- * OK, if the guest starts first, it is ok.
- * if host starts first, it is ok.
- * if guest starts, and has run for sometime, and host stops and restarts,
- * then last_used_idx 0? how to solve this. */
-
-static void virtio_init(void)
-{
- uint32_t len, e_num;
- uint32_t i,j;
- char **dom;
- char *status;
- int dom_id;
- char path[PATH_MAX];
- char node[PATH_MAX];
- xs_transaction_t th;
- struct xen_guest *guest;
- struct virtio_net_config_ll *net_config;
- char *end;
- int val;
-
- /* init env for watch the node */
- if (init_watch() < 0)
- return;
-
- dom = xs_directory(watch.xs, XBT_NULL, "/local/domain", &e_num);
-
- for (i = 0; i < e_num; i++) {
- errno = 0;
- dom_id = strtol(dom[i], &end, 0);
- if (errno != 0 || end == NULL || dom_id == 0)
- continue;
-
- for (j = 0; j < RTE_MAX_ETHPORTS; j++) {
- snprintf(node, PATH_MAX, "%s%d", VIRTIO_START, j);
- snprintf(path, PATH_MAX, XEN_VM_NODE_FMT,
- dom_id, node);
-
- th = xs_transaction_start(watch.xs);
- status = xs_read(watch.xs, th, path, &len);
- xs_transaction_end(watch.xs, th, false);
-
- if (status == NULL)
- break;
-
- /* if there's any valid virtio device */
- errno = 0;
- val = strtol(status, &end, 0);
- if (errno != 0 || end == NULL || dom_id == 0)
- val = 0;
- if (val == 1) {
- guest = add_xen_guest(dom_id);
- if (guest == NULL)
- continue;
- RTE_LOG(INFO, XENHOST, " there's a new virtio existed, new a virtio device\n\n");
-
- RTE_LOG(INFO, XENHOST, " parse_vringnode dom_id %d virtioidx %d\n",dom_id,j);
- if (parse_vringnode(guest, j)) {
- RTE_LOG(ERR, XENHOST, " there is invalid information in xenstore\n");
- TAILQ_REMOVE(&guest_root, guest, next);
- destroy_guest(guest);
-
- continue;
- }
-
- /*if pool_num > 0, then mempool has already been parsed*/
- if (guest->pool_num == 0 && parse_mempoolnode(guest)) {
- RTE_LOG(ERR, XENHOST, " there is error information in xenstore\n");
- TAILQ_REMOVE(&guest_root, guest, next);
- destroy_guest(guest);
- continue;
- }
-
- net_config = new_device(j, guest);
- /* every thing is ready now, added into data core */
- notify_ops->new_device(&net_config->dev);
- }
- }
- }
-
- free(dom);
- return;
-}
-
-void
-virtio_monitor_loop(void)
-{
- char **vec;
- xs_transaction_t th;
- char *buf;
- unsigned int len;
- unsigned int dom_id;
- uint32_t virtio_idx;
- struct xen_guest *guest;
- struct virtio_net_config_ll *net_config;
- enum fieldnames {
- FLD_NULL = 0,
- FLD_LOCAL,
- FLD_DOMAIN,
- FLD_ID,
- FLD_CONTROL,
- FLD_DPDK,
- FLD_NODE,
- _NUM_FLD
- };
- char *str_fld[_NUM_FLD];
- char *str;
- char *end;
-
- virtio_init();
- while (1) {
- watch_unmap_event();
-
- usleep(50);
- vec = xs_check_watch(watch.xs);
-
- if (vec == NULL)
- continue;
-
- th = xs_transaction_start(watch.xs);
-
- buf = xs_read(watch.xs, th, vec[XS_WATCH_PATH],&len);
- xs_transaction_end(watch.xs, th, false);
-
- if (buf) {
- /* theres' some node for vhost existed */
- if (rte_strsplit(vec[XS_WATCH_PATH], strnlen(vec[XS_WATCH_PATH], PATH_MAX),
- str_fld, _NUM_FLD, '/') == _NUM_FLD) {
- if (strstr(str_fld[FLD_NODE], VIRTIO_START)) {
- errno = 0;
- str = str_fld[FLD_ID];
- dom_id = strtoul(str, &end, 0);
- if (errno != 0 || end == NULL || end == str ) {
- RTE_LOG(INFO, XENHOST, "invalid domain id\n");
- continue;
- }
-
- errno = 0;
- str = str_fld[FLD_NODE] + sizeof(VIRTIO_START) - 1;
- virtio_idx = strtoul(str, &end, 0);
- if (errno != 0 || end == NULL || end == str
- || virtio_idx > MAX_VIRTIO) {
- RTE_LOG(INFO, XENHOST, "invalid virtio idx\n");
- continue;
- }
- RTE_LOG(INFO, XENHOST, " #####virtio dev (%d, %d) is started\n", dom_id, virtio_idx);
-
- guest = add_xen_guest(dom_id);
- if (guest == NULL)
- continue;
- guest->dom_id = dom_id;
- if (parse_vringnode(guest, virtio_idx)) {
- RTE_LOG(ERR, XENHOST, " there is invalid information in xenstore\n");
- /*guest newly created? guest existed ?*/
- TAILQ_REMOVE(&guest_root, guest, next);
- destroy_guest(guest);
- continue;
- }
- /*if pool_num > 0, then mempool has already been parsed*/
- if (guest->pool_num == 0 && parse_mempoolnode(guest)) {
- RTE_LOG(ERR, XENHOST, " there is error information in xenstore\n");
- TAILQ_REMOVE(&guest_root, guest, next);
- destroy_guest(guest);
- continue;
- }
-
-
- net_config = new_device(virtio_idx, guest);
- RTE_LOG(INFO, XENHOST, " Add to dataplane core\n");
- notify_ops->new_device(&net_config->dev);
-
- }
- }
- }
-
- free(vec);
- }
- return;
-}
-
-/*
- * Register ops so that we can add/remove device to data core.
- */
-int
-init_virtio_xen(struct virtio_net_device_ops const *const ops)
-{
- notify_ops = ops;
- if (xenhost_init())
- return -1;
- return 0;
-}
diff --git a/examples/vhost_xen/virtio-net.h b/examples/vhost_xen/virtio-net.h
deleted file mode 100644
index ab69726..0000000
--- a/examples/vhost_xen/virtio-net.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/*-
- * BSD LICENSE
- *
- * Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Intel Corporation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _VIRTIO_NET_H_
-#define _VIRTIO_NET_H_
-
-#include <stdint.h>
-
-#define VQ_DESC_NUM 256
-/* Used to indicate that the device is running on a data core */
-#define VIRTIO_DEV_RUNNING 1
-
-/*
- * Structure contains variables relevant to TX/RX virtqueues.
- */
-struct vhost_virtqueue
-{
- struct vring_desc *desc; /* Virtqueue descriptor ring. */
- struct vring_avail *avail; /* Virtqueue available ring. */
- struct vring_used *used; /* Virtqueue used ring. */
- uint32_t size; /* Size of descriptor ring. */
- uint32_t vhost_hlen; /* Vhost header length (varies depending on RX merge buffers. */
- volatile uint16_t last_used_idx; /* Last index used on the available ring */
- volatile uint16_t last_used_idx_res; /* Used for multiple devices reserving buffers. */
-} __rte_cache_aligned;
-
-/*
- * Device structure contains all configuration information relating to the device.
- */
-struct virtio_net
-{
- struct vhost_virtqueue *virtqueue_tx; /* Contains all TX virtqueue information. */
- struct vhost_virtqueue *virtqueue_rx; /* Contains all RX virtqueue information. */
- struct virtio_memory *mem; /* QEMU memory and memory region information. */
- struct ether_addr mac_address; /* Device MAC address (Obtained on first TX packet). */
- uint32_t flags; /* Device flags. Only used to check if device is running on data core. */
- uint32_t vlan_tag; /* Vlan tag for device. Currently set to device_id (0-63). */
- uint32_t vmdq_rx_q;
- uint64_t device_fh; /* device identifier. */
- uint16_t coreid;
- volatile uint8_t ready; /* A device is set as ready if the MAC address has been set. */
- volatile uint8_t remove; /* Device is marked for removal from the data core. */
- uint32_t virtio_idx; /* Index of virtio device */
- uint32_t dom_id; /* Domain id of xen guest */
-} ___rte_cache_aligned;
-
-/*
- * Device linked list structure for configuration.
- */
-struct virtio_net_config_ll
-{
- struct virtio_net dev; /* Virtio device. */
- struct virtio_net_config_ll *next; /* Next entry on linked list. */
-};
-
-/*
- * Information relating to memory regions including offsets to addresses in QEMUs memory file.
- */
-struct virtio_memory_regions {
- uint64_t guest_phys_address; /* Base guest physical address of region. */
- uint64_t guest_phys_address_end; /* End guest physical address of region. */
- uint64_t memory_size; /* Size of region. */
- uint64_t userspace_address; /* Base userspace address of region. */
- uint64_t address_offset; /* Offset of region for address translation. */
-};
-
-/*
- * Memory structure includes region and mapping information.
- */
-struct virtio_memory {
- uint32_t nregions; /* Number of memory regions. */
- struct virtio_memory_regions regions[0]; /* Memory region information. */
-};
-
-/*
- * Device operations to add/remove device.
- */
-struct virtio_net_device_ops {
- int (* new_device)(struct virtio_net *); /* Add device. */
- void (* destroy_device) (volatile struct virtio_net *); /* Remove device. */
-};
-
-#endif
diff --git a/examples/vhost_xen/xen_vhost.h b/examples/vhost_xen/xen_vhost.h
deleted file mode 100644
index 2fc304c..0000000
--- a/examples/vhost_xen/xen_vhost.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/*-
- * BSD LICENSE
- *
- * Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Intel Corporation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _XEN_VHOST_H_
-#define _XEN_VHOST_H_
-
-#include <stdint.h>
-
-#include <rte_ether.h>
-
-#include "virtio-net.h"
-
-#define RTE_LOGTYPE_XENHOST RTE_LOGTYPE_USER1
-
-#define XEN_VM_ROOTNODE_FMT "/local/domain/%d/control/dpdk"
-#define XEN_VM_NODE_FMT "/local/domain/%d/control/dpdk/%s"
-#define XEN_MEMPOOL_SUFFIX "mempool_gref"
-#define XEN_RXVRING_SUFFIX "rx_vring_gref"
-#define XEN_TXVRING_SUFFIX "tx_vring_gref"
-#define XEN_GVA_SUFFIX "mempool_va"
-#define XEN_VRINGFLAG_SUFFIX "vring_flag"
-#define XEN_ADDR_SUFFIX "ether_addr"
-#define VIRTIO_START "event_type_start_"
-
-#define XEN_GREF_SPLITTOKEN ','
-
-#define MAX_XENVIRT_MEMPOOL 16
-#define MAX_VIRTIO 32
-#define MAX_GREF_PER_NODE 64 /* 128 MB memory */
-
-#define PAGE_SIZE 4096
-#define PAGE_PFNNUM (PAGE_SIZE / sizeof(uint32_t))
-
-#define XEN_GNTDEV_FNAME "/dev/xen/gntdev"
-
-/* xen grant reference info in one grant node */
-struct xen_gnt {
- uint32_t gref; /* grant reference for this node */
- union {
- int gref; /* grant reference */
- uint32_t pfn_num; /* guest pfn number of grant reference */
- } gref_pfn[PAGE_PFNNUM];
-}__attribute__((__packed__));
-
-
-/* structure for mempool or vring node list */
-struct xen_gntnode {
- uint32_t gnt_num; /* grant reference number */
- struct xen_gnt *gnt_info; /* grant reference info */
-};
-
-
-struct xen_vring {
- uint32_t dom_id;
- uint32_t virtio_idx; /* index of virtio device */
- void *rxvring_addr; /* mapped virtual address of rxvring */
- void *txvring_addr; /* mapped virtual address of txvring */
- uint32_t rxpfn_num; /* number of gpfn for rxvring */
- uint32_t txpfn_num; /* number of gpfn for txvring */
- uint32_t *rxpfn_tbl; /* array of rxvring gpfn */
- uint32_t *txpfn_tbl; /* array of txvring gpfn */
- uint64_t *rx_pindex; /* index used to release rx grefs */
- uint64_t *tx_pindex; /* index used to release tx grefs */
- uint64_t flag_index;
- uint8_t *flag; /* cleared to zero on guest unmap */
- struct ether_addr addr; /* ethernet address of virtio device */
- uint8_t removed;
-
-};
-
-struct xen_mempool {
- uint32_t dom_id; /* guest domain id */
- uint32_t pool_idx; /* index of memory pool */
- void *gva; /* guest virtual address of mbuf pool */
- void *hva; /* host virtual address of mbuf pool */
- uint32_t mempfn_num; /* number of gpfn for mbuf pool */
- uint32_t *mempfn_tbl; /* array of mbuf pool gpfn */
- uint64_t *pindex; /* index used to release grefs */
-};
-
-struct xen_guest {
- TAILQ_ENTRY(xen_guest) next;
- int32_t dom_id; /* guest domain id */
- uint32_t pool_num; /* number of mbuf pool of the guest */
- uint32_t vring_num; /* number of virtio ports of the guest */
- /* array contain the guest mbuf pool info */
- struct xen_mempool mempool[MAX_XENVIRT_MEMPOOL];
- /* array contain the guest rx/tx vring info */
- struct xen_vring vring[MAX_VIRTIO];
-};
-
-TAILQ_HEAD(xen_guestlist, xen_guest);
-
-int
-parse_mempoolnode(struct xen_guest *guest);
-
-int
-xenhost_init(void);
-
-int
-parse_vringnode(struct xen_guest *guest, uint32_t virtio_idx);
-
-int
-parse_mempoolnode(struct xen_guest *guest);
-
-void
-cleanup_mempool(struct xen_mempool *mempool);
-
-void
-cleanup_vring(struct xen_vring *vring);
-
-void
-virtio_monitor_loop(void);
-
-int
-init_virtio_xen(struct virtio_net_device_ops const * const);
-
-#endif
diff --git a/examples/vhost_xen/xenstore_parse.c b/examples/vhost_xen/xenstore_parse.c
deleted file mode 100644
index ab089f1..0000000
--- a/examples/vhost_xen/xenstore_parse.c
+++ /dev/null
@@ -1,775 +0,0 @@
-/*-
- * BSD LICENSE
- *
- * Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Intel Corporation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdint.h>
-#include <unistd.h>
-#include <inttypes.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <xen/sys/gntalloc.h>
-#include <xen/sys/gntdev.h>
-#include <xen/xen-compat.h>
-#if __XEN_LATEST_INTERFACE_VERSION__ < 0x00040200
-#include <xs.h>
-#else
-#include <xenstore.h>
-#endif
-
-#include <rte_common.h>
-#include <rte_memory.h>
-#include <rte_eal.h>
-#include <rte_malloc.h>
-#include <rte_string_fns.h>
-#include <rte_log.h>
-#include <rte_debug.h>
-
-#include "xen_vhost.h"
-
-/* xenstore handle */
-static struct xs_handle *xs = NULL;
-
-/* gntdev file descriptor to map grant pages */
-static int d_fd = -1;
-
-/*
- * The grant node format in xenstore for vring/mpool is like:
- * idx#_rx_vring_gref = "gref1#, gref2#, gref3#"
- * idx#_mempool_gref = "gref1#, gref2#, gref3#"
- * each gref# is the grant reference for a shared page.
- * In each shared page, we store the grant_node_item items.
- */
-struct grant_node_item {
- uint32_t gref;
- uint32_t pfn;
-} __attribute__((packed));
-
-int cmdline_parse_etheraddr(void *tk, const char *srcbuf,
- void *res, unsigned ressize);
-
-/* Map grant ref refid at addr_ori*/
-static void *
-xen_grant_mmap(void *addr_ori, int domid, int refid, uint64_t *pindex)
-{
- struct ioctl_gntdev_map_grant_ref arg;
- void *addr = NULL;
- int pg_sz = getpagesize();
-
- arg.count = 1;
- arg.refs[0].domid = domid;
- arg.refs[0].ref = refid;
-
- int rv = ioctl(d_fd, IOCTL_GNTDEV_MAP_GRANT_REF, &arg);
- if (rv) {
- RTE_LOG(ERR, XENHOST, " %s: (%d,%d) %s (ioctl failed)\n", __func__,
- domid, refid, strerror(errno));
- return NULL;
- }
-
- if (addr_ori == NULL)
- addr = mmap(addr_ori, pg_sz, PROT_READ|PROT_WRITE, MAP_SHARED,
- d_fd, arg.index);
- else
- addr = mmap(addr_ori, pg_sz, PROT_READ|PROT_WRITE, MAP_SHARED | MAP_FIXED,
- d_fd, arg.index);
-
- if (addr == MAP_FAILED) {
- RTE_LOG(ERR, XENHOST, " %s: (%d, %d) %s (map failed)\n", __func__,
- domid, refid, strerror(errno));
- return NULL;
- }
-
- if (pindex)
- *pindex = arg.index;
-
- return addr;
-}
-
-/* Unmap one grant ref, and munmap must be called before this */
-static int
-xen_unmap_grant_ref(uint64_t index)
-{
- struct ioctl_gntdev_unmap_grant_ref arg;
- int rv;
-
- arg.count = 1;
- arg.index = index;
- rv = ioctl(d_fd, IOCTL_GNTDEV_UNMAP_GRANT_REF, &arg);
- if (rv) {
- RTE_LOG(ERR, XENHOST, " %s: index 0x%" PRIx64 "unmap failed\n", __func__, index);
- return -1;
- }
- return 0;
-}
-
-/*
- * Reserve a virtual address space.
- * On success, returns the pointer. On failure, returns NULL.
- */
-static void *
-get_xen_virtual(size_t size, size_t page_sz)
-{
- void *addr;
- uintptr_t aligned_addr;
-
- addr = mmap(NULL, size + page_sz, PROT_READ, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
- if (addr == MAP_FAILED) {
- RTE_LOG(ERR, XENHOST, "failed get a virtual area\n");
- return NULL;
- }
-
- aligned_addr = RTE_ALIGN_CEIL((uintptr_t)addr, page_sz);
- munmap(addr, aligned_addr - (uintptr_t)addr);
- munmap((void *)(aligned_addr + size), page_sz + (uintptr_t)addr - aligned_addr);
- addr = (void *)(aligned_addr);
-
- return addr;
-}
-
-static void
-free_xen_virtual(void *addr, size_t size, size_t page_sz __rte_unused)
-{
- if (addr)
- munmap(addr, size);
-}
-
-/*
- * Returns val str in xenstore.
- * @param path
- * Full path string for key
- * @return
- * Pointer to Val str, NULL on failure
- */
-static char *
-xen_read_node(char *path, uint32_t *len)
-{
- char *buf;
-
- buf = xs_read(xs, XBT_NULL, path, len);
- return buf;
-}
-
-static int
-cal_pagenum(struct xen_gnt *gnt)
-{
- unsigned int i;
- /*
- * the items in the page are in the format of
- * gref#,pfn#,...,gref#,pfn#
- * FIXME, 0 is reserved by system, use it as terminator.
- */
- for (i = 0; i < (PAGE_PFNNUM) / 2; i++) {
- if (gnt->gref_pfn[i * 2].gref <= 0)
- break;
- }
-
- return i;
-}
-
-/* Frees memory allocated to a grant node */
-static void
-xen_free_gntnode(struct xen_gntnode *gntnode)
-{
- if (gntnode == NULL)
- return;
- free(gntnode->gnt_info);
- free(gntnode);
-}
-
-/*
- * Parse a grant node.
- * @param domid
- * Guest domain id.
- * @param path
- * Full path string for a grant node, like for the following (key, val) pair
- * idx#_mempool_gref = "gref#, gref#, gref#"
- * path = 'local/domain/domid/control/dpdk/idx#_mempool_gref'
- * gref# is a shared page contain packed (gref,pfn) entries
- * @return
- * Returns the pointer to xen_gntnode
- */
-static struct xen_gntnode *
-parse_gntnode(int dom_id, char *path)
-{
- char **gref_list = NULL;
- uint32_t i, len, gref_num;
- void *addr = NULL;
- char *buf = NULL;
- struct xen_gntnode *gntnode = NULL;
- struct xen_gnt *gnt = NULL;
- int pg_sz = getpagesize();
- char *end;
- uint64_t index;
-
- if ((buf = xen_read_node(path, &len)) == NULL)
- goto err;
-
- gref_list = malloc(MAX_GREF_PER_NODE * sizeof(char *));
- if (gref_list == NULL)
- goto err;
-
- gref_num = rte_strsplit(buf, len, gref_list, MAX_GREF_PER_NODE,
- XEN_GREF_SPLITTOKEN);
- if (gref_num == 0) {
- RTE_LOG(ERR, XENHOST, " %s: invalid grant node format\n", __func__);
- goto err;
- }
-
- gntnode = calloc(1, sizeof(struct xen_gntnode));
- gnt = calloc(gref_num, sizeof(struct xen_gnt));
- if (gnt == NULL || gntnode == NULL)
- goto err;
-
- for (i = 0; i < gref_num; i++) {
- errno = 0;
- gnt[i].gref = strtol(gref_list[i], &end, 0);
- if (errno != 0 || end == NULL || end == gref_list[i] ||
- (*end != '\0' && *end != XEN_GREF_SPLITTOKEN)) {
- RTE_LOG(ERR, XENHOST, " %s: parse grant node item failed\n", __func__);
- goto err;
- }
- addr = xen_grant_mmap(NULL, dom_id, gnt[i].gref, &index);
- if (addr == NULL) {
- RTE_LOG(ERR, XENHOST, " %s: map gref %u failed\n", __func__, gnt[i].gref);
- goto err;
- }
- RTE_LOG(INFO, XENHOST, " %s: map gref %u to %p\n", __func__, gnt[i].gref, addr);
- memcpy(gnt[i].gref_pfn, addr, pg_sz);
- if (munmap(addr, pg_sz)) {
- RTE_LOG(INFO, XENHOST, " %s: unmap gref %u failed\n", __func__, gnt[i].gref);
- goto err;
- }
- if (xen_unmap_grant_ref(index)) {
- RTE_LOG(INFO, XENHOST, " %s: release gref %u failed\n", __func__, gnt[i].gref);
- goto err;
- }
-
- }
-
- gntnode->gnt_num = gref_num;
- gntnode->gnt_info = gnt;
-
- free(buf);
- free(gref_list);
- return gntnode;
-
-err:
- free(gnt);
- free(gntnode);
- free(gref_list);
- free(buf);
- return NULL;
-}
-
-/*
- * This function maps grant node of vring or mbuf pool to a continuous virtual address space,
- * and returns mapped address, pfn array, index array
- * @param gntnode
- * Pointer to grant node
- * @param domid
- * Guest domain id
- * @param ppfn
- * Pointer to pfn array, caller should free this array
- * @param pgs
- * Pointer to number of pages
- * @param ppindex
- * Pointer to index array, used to release grefs when to free this node
- * @return
- * Pointer to mapped virtual address, NULL on failure
- */
-static void *
-map_gntnode(struct xen_gntnode *gntnode, int domid, uint32_t **ppfn, uint32_t *pgs, uint64_t **ppindex)
-{
- struct xen_gnt *gnt;
- uint32_t i, j;
- size_t total_pages = 0;
- void *addr;
- uint32_t *pfn;
- uint64_t *pindex;
- uint32_t pfn_num = 0;
- int pg_sz;
-
- if (gntnode == NULL)
- return NULL;
-
- pg_sz = getpagesize();
- for (i = 0; i < gntnode->gnt_num; i++) {
- gnt = gntnode->gnt_info + i;
- total_pages += cal_pagenum(gnt);
- }
- if ((addr = get_xen_virtual(total_pages * pg_sz, pg_sz)) == NULL) {
- RTE_LOG(ERR, XENHOST, " %s: failed get_xen_virtual\n", __func__);
- return NULL;
- }
- pfn = calloc(total_pages, (size_t)sizeof(uint32_t));
- pindex = calloc(total_pages, (size_t)sizeof(uint64_t));
- if (pfn == NULL || pindex == NULL) {
- free_xen_virtual(addr, total_pages * pg_sz, pg_sz);
- free(pfn);
- free(pindex);
- return NULL;
- }
-
- RTE_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));
- for (i = 0; i < gntnode->gnt_num; i++) {
- gnt = gntnode->gnt_info + i;
- for (j = 0; j < (PAGE_PFNNUM) / 2; j++) {
- if ((gnt->gref_pfn[j * 2].gref) <= 0)
- goto _end;
- /*alternative: batch map, or through libxc*/
- if (xen_grant_mmap(RTE_PTR_ADD(addr, pfn_num * pg_sz),
- domid,
- gnt->gref_pfn[j * 2].gref,
- &pindex[pfn_num]) == NULL) {
- goto mmap_failed;
- }
- pfn[pfn_num] = gnt->gref_pfn[j * 2 + 1].pfn_num;
- pfn_num++;
- }
- }
-
-mmap_failed:
- if (pfn_num)
- munmap(addr, pfn_num * pg_sz);
- for (i = 0; i < pfn_num; i++) {
- xen_unmap_grant_ref(pindex[i]);
- }
- free(pindex);
- free(pfn);
- return NULL;
-
-_end:
- if (ppindex)
- *ppindex = pindex;
- else
- free(pindex);
- if (ppfn)
- *ppfn = pfn;
- else
- free(pfn);
- if (pgs)
- *pgs = total_pages;
-
- return addr;
-}
-
-static int
-parse_mpool_va(struct xen_mempool *mempool)
-{
- char path[PATH_MAX] = {0};
- char *buf;
- uint32_t len;
- char *end;
- int ret = -1;
-
- errno = 0;
- snprintf(path, sizeof(path),
- XEN_VM_ROOTNODE_FMT"/%d_"XEN_GVA_SUFFIX,
- mempool->dom_id, mempool->pool_idx);
-
- if((buf = xen_read_node(path, &len)) == NULL)
- goto out;
- mempool->gva = (void *)strtoul(buf, &end, 16);
- if (errno != 0 || end == NULL || end == buf || *end != '\0') {
- mempool->gva = NULL;
- goto out;
- }
- ret = 0;
-out:
- free(buf);
- return ret;
-}
-
-/*
- * map mbuf pool
- */
-static int
-map_mempoolnode(struct xen_gntnode *gntnode,
- struct xen_mempool *mempool)
-{
- if (gntnode == NULL || mempool == NULL)
- return -1;
-
- mempool->hva =
- map_gntnode(gntnode, mempool->dom_id, &mempool->mempfn_tbl, &mempool->mempfn_num, &mempool->pindex);
-
- RTE_LOG(INFO, XENHOST, " %s: map mempool at %p\n", __func__, (void *)mempool->hva);
- if (mempool->hva)
- return 0;
- else {
- return -1;
- }
-}
-
-void
-cleanup_mempool(struct xen_mempool *mempool)
-{
- int pg_sz = getpagesize();
- uint32_t i;
-
- if (mempool->hva)
- munmap(mempool->hva, mempool->mempfn_num * pg_sz);
- mempool->hva = NULL;
-
- if (mempool->pindex) {
- RTE_LOG(INFO, XENHOST, " %s: unmap dom %02u mempool%02u %u grefs\n",
- __func__,
- mempool->dom_id,
- mempool->pool_idx,
- mempool->mempfn_num);
- for (i = 0; i < mempool->mempfn_num; i ++) {
- xen_unmap_grant_ref(mempool->pindex[i]);
- }
- }
- mempool->pindex = NULL;
-
- free(mempool->mempfn_tbl);
- mempool->mempfn_tbl = NULL;
-}
-
-/*
- * process mempool node idx#_mempool_gref, idx = 0, 1, 2...
- * until we encounter a node that doesn't exist.
- */
-int
-parse_mempoolnode(struct xen_guest *guest)
-{
- uint32_t i, len;
- char path[PATH_MAX] = {0};
- struct xen_gntnode *gntnode = NULL;
- struct xen_mempool *mempool = NULL;
- char *buf;
-
- bzero(&guest->mempool, MAX_XENVIRT_MEMPOOL * sizeof(guest->mempool[0]));
- guest->pool_num = 0;
-
- while (1) {
- /* check if null terminated */
- snprintf(path, sizeof(path),
- XEN_VM_ROOTNODE_FMT"/%d_"XEN_MEMPOOL_SUFFIX,
- guest->dom_id,
- guest->pool_num);
-
- if ((buf = xen_read_node(path, &len)) != NULL) {
- /* this node exists */
- free(buf);
- } else {
- if (guest->pool_num == 0) {
- RTE_LOG(ERR, PMD, "no mempool found\n");
- return -1;
- }
- break;
- }
-
- mempool = &guest->mempool[guest->pool_num];
- mempool->dom_id = guest->dom_id;
- mempool->pool_idx = guest->pool_num;
-
- RTE_LOG(INFO, XENHOST, " %s: mempool %u parse gntnode %s\n", __func__, guest->pool_num, path);
- gntnode = parse_gntnode(guest->dom_id, path);
- if (gntnode == NULL)
- goto err;
-
- if (parse_mpool_va(mempool))
- goto err;
-
- RTE_LOG(INFO, XENHOST, " %s: mempool %u map gntnode %s\n", __func__, guest->pool_num, path);
- if (map_mempoolnode(gntnode, mempool))
- goto err;
-
- xen_free_gntnode(gntnode);
- guest->pool_num++;
- }
-
- return 0;
-err:
- if (gntnode)
- xen_free_gntnode(gntnode);
- for (i = 0; i < MAX_XENVIRT_MEMPOOL ; i++) {
- cleanup_mempool(&guest->mempool[i]);
- }
- /* reinitialise mempool */
- bzero(&guest->mempool, MAX_XENVIRT_MEMPOOL * sizeof(guest->mempool[0]));
- return -1;
-}
-
-static int
-xen_map_vringflag(struct xen_vring *vring)
-{
- char path[PATH_MAX] = {0};
- char *buf;
- uint32_t len,gref;
- int pg_sz = getpagesize();
- char *end;
-
- snprintf(path, sizeof(path),
- XEN_VM_ROOTNODE_FMT"/%d_"XEN_VRINGFLAG_SUFFIX,
- vring->dom_id, vring->virtio_idx);
-
- if((buf = xen_read_node(path, &len)) == NULL)
- goto err;
-
- errno = 0;
- gref = strtol(buf, &end, 0);
- if (errno != 0 || end == NULL || end == buf) {
- goto err;
- }
- vring->flag = xen_grant_mmap(0, vring->dom_id, gref, &vring->flag_index);
- if (vring->flag == NULL || *vring->flag == 0)
- goto err;
-
- free(buf);
- return 0;
-err:
- free(buf);
- if (vring->flag) {
- munmap(vring->flag, pg_sz);
- vring->flag = NULL;
- xen_unmap_grant_ref(vring->flag_index);
- }
- return -1;
-}
-
-
-static int
-xen_map_rxvringnode(struct xen_gntnode *gntnode,
- struct xen_vring *vring)
-{
- vring->rxvring_addr =
- map_gntnode(gntnode, vring->dom_id, &vring->rxpfn_tbl, &vring->rxpfn_num, &vring->rx_pindex);
- RTE_LOG(INFO, XENHOST, " %s: map rx vring at %p\n", __func__, (void *)vring->rxvring_addr);
- if (vring->rxvring_addr)
- return 0;
- else
- return -1;
-}
-
-static int
-xen_map_txvringnode(struct xen_gntnode *gntnode,
- struct xen_vring *vring)
-{
- vring->txvring_addr =
- map_gntnode(gntnode, vring->dom_id, &vring->txpfn_tbl, &vring->txpfn_num, &vring->tx_pindex);
- RTE_LOG(INFO, XENHOST, " %s: map tx vring at %p\n", __func__, (void *)vring->txvring_addr);
- if (vring->txvring_addr)
- return 0;
- else
- return -1;
-}
-
-void
-cleanup_vring(struct xen_vring *vring)
-{
- int pg_sz = getpagesize();
- uint32_t i;
-
- RTE_LOG(INFO, XENHOST, " %s: cleanup dom %u vring %u\n", __func__, vring->dom_id, vring->virtio_idx);
- if (vring->rxvring_addr) {
- munmap(vring->rxvring_addr, vring->rxpfn_num * pg_sz);
- RTE_LOG(INFO, XENHOST, " %s: unmap rx vring [%p, %p]\n",
- __func__,
- vring->rxvring_addr,
- RTE_PTR_ADD(vring->rxvring_addr,
- vring->rxpfn_num * pg_sz - 1));
- }
- vring->rxvring_addr = NULL;
-
-
- if (vring->rx_pindex) {
- RTE_LOG(INFO, XENHOST, " %s: unmap rx vring %u grefs\n", __func__, vring->rxpfn_num);
- for (i = 0; i < vring->rxpfn_num; i++) {
- xen_unmap_grant_ref(vring->rx_pindex[i]);
- }
- }
- vring->rx_pindex = NULL;
-
- free(vring->rxpfn_tbl);
- vring->rxpfn_tbl = NULL;
-
- if (vring->txvring_addr) {
- munmap(vring->txvring_addr, vring->txpfn_num * pg_sz);
- RTE_LOG(INFO, XENHOST, " %s: unmap tx vring [%p, %p]\n",
- __func__,
- vring->txvring_addr,
- RTE_PTR_ADD(vring->txvring_addr,
- vring->txpfn_num * pg_sz - 1));
- }
- vring->txvring_addr = NULL;
-
- if (vring->tx_pindex) {
- RTE_LOG(INFO, XENHOST, " %s: unmap tx vring %u grefs\n", __func__, vring->txpfn_num);
- for (i = 0; i < vring->txpfn_num; i++) {
- xen_unmap_grant_ref(vring->tx_pindex[i]);
- }
- }
- vring->tx_pindex = NULL;
-
- free(vring->txpfn_tbl);
- vring->txpfn_tbl = NULL;
-
- if (vring->flag) {
- if (!munmap((void *)vring->flag, pg_sz))
- RTE_LOG(INFO, XENHOST, " %s: unmap flag page at %p\n", __func__, vring->flag);
- if (!xen_unmap_grant_ref(vring->flag_index))
- RTE_LOG(INFO, XENHOST, " %s: release flag ref index 0x%" PRIx64 "\n", __func__, vring->flag_index);
- }
- vring->flag = NULL;
- return;
-}
-
-
-
-static int
-xen_parse_etheraddr(struct xen_vring *vring)
-{
- char path[PATH_MAX] = {0};
- char *buf;
- uint32_t len;
- int ret = -1;
-
- snprintf(path, sizeof(path),
- XEN_VM_ROOTNODE_FMT"/%d_"XEN_ADDR_SUFFIX,
- vring->dom_id, vring->virtio_idx);
-
- if ((buf = xen_read_node(path, &len)) == NULL)
- goto out;
-
- if (cmdline_parse_etheraddr(NULL, buf, &vring->addr,
- sizeof(vring->addr)) < 0)
- goto out;
- ret = 0;
-out:
- free(buf);
- return ret;
-}
-
-
-int
-parse_vringnode(struct xen_guest *guest, uint32_t virtio_idx)
-{
- char path[PATH_MAX] = {0};
- struct xen_gntnode *rx_gntnode = NULL;
- struct xen_gntnode *tx_gntnode = NULL;
- struct xen_vring *vring = NULL;
-
- /*check if null terminated */
- snprintf(path, sizeof(path),
- XEN_VM_ROOTNODE_FMT"/%d_"XEN_RXVRING_SUFFIX,
- guest->dom_id,
- virtio_idx);
-
- RTE_LOG(INFO, XENHOST, " %s: virtio %u parse rx gntnode %s\n", __func__, virtio_idx, path);
- rx_gntnode = parse_gntnode(guest->dom_id, path);
- if (rx_gntnode == NULL)
- goto err;
-
- /*check if null terminated */
- snprintf(path, sizeof(path),
- XEN_VM_ROOTNODE_FMT"/%d_"XEN_TXVRING_SUFFIX,
- guest->dom_id,
- virtio_idx);
-
- RTE_LOG(INFO, XENHOST, " %s: virtio %u parse tx gntnode %s\n", __func__, virtio_idx, path);
- tx_gntnode = parse_gntnode(guest->dom_id, path);
- if (tx_gntnode == NULL)
- goto err;
-
- vring = &guest->vring[virtio_idx];
- bzero(vring, sizeof(*vring));
- vring->dom_id = guest->dom_id;
- vring->virtio_idx = virtio_idx;
-
- if (xen_parse_etheraddr(vring) != 0)
- goto err;
-
- RTE_LOG(INFO, XENHOST, " %s: virtio %u map rx gntnode %s\n", __func__, virtio_idx, path);
- if (xen_map_rxvringnode(rx_gntnode, vring) != 0)
- goto err;
-
- RTE_LOG(INFO, XENHOST, " %s: virtio %u map tx gntnode %s\n", __func__, virtio_idx, path);
- if (xen_map_txvringnode(tx_gntnode, vring) != 0)
- goto err;
-
- if (xen_map_vringflag(vring) != 0)
- goto err;
-
- guest->vring_num++;
-
- xen_free_gntnode(rx_gntnode);
- xen_free_gntnode(tx_gntnode);
-
- return 0;
-
-err:
- if (rx_gntnode)
- xen_free_gntnode(rx_gntnode);
- if (tx_gntnode)
- xen_free_gntnode(tx_gntnode);
- if (vring) {
- cleanup_vring(vring);
- bzero(vring, sizeof(*vring));
- }
- return -1;
-}
-
-/*
- * Open xen grant dev driver
- * @return
- * 0 on success, -1 on failure.
- */
-static int
-xen_grant_init(void)
-{
- d_fd = open(XEN_GNTDEV_FNAME, O_RDWR);
-
- return d_fd == -1? (-1): (0);
-}
-
-/*
- * Initialise xenstore handle and open grant dev driver.
- * @return
- * 0 on success, -1 on failure.
- */
-int
-xenhost_init(void)
-{
- xs = xs_daemon_open();
- if (xs == NULL) {
- rte_panic("failed initialize xen daemon handler");
- return -1;
- }
- if (xen_grant_init())
- return -1;
- return 0;
-}
--
2.7.4
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [dpdk-dev] [PATCH 1/6] example/vhost_xen: remove
2017-08-30 18:10 ` [dpdk-dev] [PATCH 1/6] example/vhost_xen: remove Jianfeng Tan
@ 2017-09-04 14:14 ` Bruce Richardson
0 siblings, 0 replies; 21+ messages in thread
From: Bruce Richardson @ 2017-09-04 14:14 UTC (permalink / raw)
To: Jianfeng Tan
Cc: dev, xen-devel, thomas, john.mcnamara, oao.m.martins,
jerin.jacob, shahafs
On Wed, Aug 30, 2017 at 06:10:29PM +0000, Jianfeng Tan wrote:
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Minor nit: checkpatch points out that the prefix should be "examples/..."
rather than "example/..."
Otherwise:
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
^ permalink raw reply [flat|nested] 21+ messages in thread
* [dpdk-dev] [PATCH 2/6] net/xenvirt: remove
2017-08-30 18:10 [dpdk-dev] [PATCH 0/6] remove xen dom0 support in DPDK Jianfeng Tan
2017-08-30 18:10 ` [dpdk-dev] [PATCH 1/6] example/vhost_xen: remove Jianfeng Tan
@ 2017-08-30 18:10 ` Jianfeng Tan
2017-09-04 14:25 ` Bruce Richardson
2017-08-30 18:10 ` [dpdk-dev] [PATCH 3/6] xen: remove xen dependency in app, examples, test Jianfeng Tan
` (4 subsequent siblings)
6 siblings, 1 reply; 21+ messages in thread
From: Jianfeng Tan @ 2017-08-30 18:10 UTC (permalink / raw)
To: dev
Cc: xen-devel, thomas, john.mcnamara, oao.m.martins, jerin.jacob,
shahafs, Jianfeng Tan
Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
MAINTAINERS | 2 -
app/test-pmd/Makefile | 4 -
app/test-pmd/testpmd.c | 12 -
config/common_base | 5 -
config/defconfig_arm-armv7a-linuxapp-gcc | 1 -
doc/guides/nics/features/xenvirt.ini | 6 -
drivers/net/Makefile | 2 -
drivers/net/xenvirt/Makefile | 57 --
drivers/net/xenvirt/rte_eth_xenvirt.c | 766 ------------------------
drivers/net/xenvirt/rte_eth_xenvirt.h | 61 --
drivers/net/xenvirt/rte_eth_xenvirt_version.map | 7 -
drivers/net/xenvirt/rte_mempool_gntalloc.c | 295 ---------
drivers/net/xenvirt/rte_xen_lib.c | 454 --------------
drivers/net/xenvirt/rte_xen_lib.h | 116 ----
drivers/net/xenvirt/virtio_logs.h | 70 ---
drivers/net/xenvirt/virtqueue.h | 273 ---------
mk/rte.app.mk | 1 -
pkg/dpdk.spec | 3 -
18 files changed, 2135 deletions(-)
delete mode 100644 doc/guides/nics/features/xenvirt.ini
delete mode 100644 drivers/net/xenvirt/Makefile
delete mode 100644 drivers/net/xenvirt/rte_eth_xenvirt.c
delete mode 100644 drivers/net/xenvirt/rte_eth_xenvirt.h
delete mode 100644 drivers/net/xenvirt/rte_eth_xenvirt_version.map
delete mode 100644 drivers/net/xenvirt/rte_mempool_gntalloc.c
delete mode 100644 drivers/net/xenvirt/rte_xen_lib.c
delete mode 100644 drivers/net/xenvirt/rte_xen_lib.h
delete mode 100644 drivers/net/xenvirt/virtio_logs.h
delete mode 100644 drivers/net/xenvirt/virtqueue.h
diff --git a/MAINTAINERS b/MAINTAINERS
index fe6c6db..003e72e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -194,9 +194,7 @@ M: Jianfeng Tan <jianfeng.tan@intel.com>
F: lib/librte_eal/linuxapp/xen_dom0/
F: lib/librte_eal/linuxapp/eal/*xen*
F: lib/librte_eal/linuxapp/eal/include/exec-env/rte_dom0_common.h
-F: drivers/net/xenvirt/
F: doc/guides/xen/
-F: doc/guides/nics/features/xenvirt.ini
FreeBSD EAL (with overlaps)
M: Bruce Richardson <bruce.richardson@intel.com>
diff --git a/app/test-pmd/Makefile b/app/test-pmd/Makefile
index c36be19..b6e80dd 100644
--- a/app/test-pmd/Makefile
+++ b/app/test-pmd/Makefile
@@ -77,10 +77,6 @@ ifeq ($(CONFIG_RTE_LIBRTE_BNXT_PMD),y)
LDLIBS += -lrte_pmd_bnxt
endif
-ifeq ($(CONFIG_RTE_LIBRTE_PMD_XENVIRT),y)
-LDLIBS += -lrte_pmd_xenvirt
-endif
-
endif
CFLAGS_cmdline.o := -D_GNU_SOURCE
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index 7d40139..f8d02ae 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -76,9 +76,6 @@
#ifdef RTE_LIBRTE_IXGBE_PMD
#include <rte_pmd_ixgbe.h>
#endif
-#ifdef RTE_LIBRTE_PMD_XENVIRT
-#include <rte_eth_xenvirt.h>
-#endif
#ifdef RTE_LIBRTE_PDUMP
#include <rte_pdump.h>
#endif
@@ -497,15 +494,6 @@ mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
"create a new mbuf pool <%s>: n=%u, size=%u, socket=%u\n",
pool_name, nb_mbuf, mbuf_seg_size, socket_id);
-#ifdef RTE_LIBRTE_PMD_XENVIRT
- rte_mp = rte_mempool_gntalloc_create(pool_name, nb_mbuf, mb_size,
- (unsigned) mb_mempool_cache,
- sizeof(struct rte_pktmbuf_pool_private),
- rte_pktmbuf_pool_init, NULL,
- rte_pktmbuf_init, NULL,
- socket_id, 0);
-#endif
-
/* if the former XEN allocation failed fall back to normal allocation */
if (rte_mp == NULL) {
if (mp_anon != 0) {
diff --git a/config/common_base b/config/common_base
index 5e97a08..93928b6 100644
--- a/config/common_base
+++ b/config/common_base
@@ -411,11 +411,6 @@ CONFIG_RTE_LIBRTE_AVP_DEBUG_BUFFERS=n
CONFIG_RTE_LIBRTE_PMD_TAP=n
#
-# Compile Xen PMD
-#
-CONFIG_RTE_LIBRTE_PMD_XENVIRT=n
-
-#
# Compile null PMD
#
CONFIG_RTE_LIBRTE_PMD_NULL=y
diff --git a/config/defconfig_arm-armv7a-linuxapp-gcc b/config/defconfig_arm-armv7a-linuxapp-gcc
index 00bc2ab..6628567 100644
--- a/config/defconfig_arm-armv7a-linuxapp-gcc
+++ b/config/defconfig_arm-armv7a-linuxapp-gcc
@@ -76,7 +76,6 @@ CONFIG_RTE_LIBRTE_I40E_PMD=n
CONFIG_RTE_LIBRTE_IXGBE_PMD=n
CONFIG_RTE_LIBRTE_MLX4_PMD=n
CONFIG_RTE_LIBRTE_VMXNET3_PMD=n
-CONFIG_RTE_LIBRTE_PMD_XENVIRT=n
CONFIG_RTE_LIBRTE_PMD_BNX2X=n
CONFIG_RTE_LIBRTE_QEDE_PMD=n
CONFIG_RTE_LIBRTE_SFC_EFX_PMD=n
diff --git a/doc/guides/nics/features/xenvirt.ini b/doc/guides/nics/features/xenvirt.ini
deleted file mode 100644
index 8ab5f46..0000000
--- a/doc/guides/nics/features/xenvirt.ini
+++ /dev/null
@@ -1,6 +0,0 @@
-;
-; Supported features of the 'xenvirt' network poll mode driver.
-;
-; Refer to default.ini for the full list of available PMD features.
-;
-[Features]
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index d33c959..0e00cd1 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -97,8 +97,6 @@ DIRS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += virtio
DEPDIRS-virtio = $(core-libs)
DIRS-$(CONFIG_RTE_LIBRTE_VMXNET3_PMD) += vmxnet3
DEPDIRS-vmxnet3 = $(core-libs)
-DIRS-$(CONFIG_RTE_LIBRTE_PMD_XENVIRT) += xenvirt
-DEPDIRS-xenvirt = $(core-libs) librte_cmdline
ifeq ($(CONFIG_RTE_LIBRTE_KNI),y)
DIRS-$(CONFIG_RTE_LIBRTE_PMD_KNI) += kni
diff --git a/drivers/net/xenvirt/Makefile b/drivers/net/xenvirt/Makefile
deleted file mode 100644
index 8b4b8f0..0000000
--- a/drivers/net/xenvirt/Makefile
+++ /dev/null
@@ -1,57 +0,0 @@
-# BSD LICENSE
-#
-# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in
-# the documentation and/or other materials provided with the
-# distribution.
-# * Neither the name of Intel Corporation nor the names of its
-# contributors may be used to endorse or promote products derived
-# from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-include $(RTE_SDK)/mk/rte.vars.mk
-
-#
-# library name
-#
-LIB = librte_pmd_xenvirt.a
-
-CFLAGS += -O3
-CFLAGS += $(WERROR_FLAGS)
-LDLIBS += -lxenstore
-
-EXPORT_MAP := rte_eth_xenvirt_version.map
-
-LIBABIVER := 1
-
-#
-# all source are stored in SRCS-y
-#
-SRCS-$(CONFIG_RTE_LIBRTE_PMD_XENVIRT) += rte_eth_xenvirt.c rte_mempool_gntalloc.c rte_xen_lib.c
-
-#
-# Export include files
-#
-SYMLINK-y-include += rte_eth_xenvirt.h
-
-include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/net/xenvirt/rte_eth_xenvirt.c b/drivers/net/xenvirt/rte_eth_xenvirt.c
deleted file mode 100644
index e404b77..0000000
--- a/drivers/net/xenvirt/rte_eth_xenvirt.c
+++ /dev/null
@@ -1,766 +0,0 @@
-/*-
- * BSD LICENSE
- *
- * Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Intel Corporation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdint.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/mman.h>
-#include <errno.h>
-#include <sys/user.h>
-#ifndef PAGE_SIZE
-#define PAGE_SIZE sysconf(_SC_PAGE_SIZE)
-#endif
-#include <linux/binfmts.h>
-#include <xen/xen-compat.h>
-#if __XEN_LATEST_INTERFACE_VERSION__ < 0x00040200
-#include <xs.h>
-#else
-#include <xenstore.h>
-#endif
-#include <linux/virtio_ring.h>
-
-#include <rte_mbuf.h>
-#include <rte_ethdev.h>
-#include <rte_malloc.h>
-#include <rte_memcpy.h>
-#include <rte_string_fns.h>
-#include <rte_vdev.h>
-#include <cmdline_parse.h>
-#include <cmdline_parse_etheraddr.h>
-
-#include "rte_xen_lib.h"
-#include "virtqueue.h"
-#include "rte_eth_xenvirt.h"
-
-#define VQ_DESC_NUM 256
-#define VIRTIO_MBUF_BURST_SZ 64
-
-/* virtio_idx is increased after new device is created.*/
-static int virtio_idx = 0;
-
-static struct rte_eth_link pmd_link = {
- .link_speed = ETH_SPEED_NUM_10G,
- .link_duplex = ETH_LINK_FULL_DUPLEX,
- .link_status = ETH_LINK_DOWN,
- .link_autoneg = ETH_LINK_SPEED_FIXED
-};
-
-static void
-eth_xenvirt_free_queues(struct rte_eth_dev *dev);
-
-static uint16_t
-eth_xenvirt_rx(void *q, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
-{
- struct virtqueue *rxvq = q;
- struct rte_mbuf *rxm, *new_mbuf;
- uint16_t nb_used, num;
- uint32_t len[VIRTIO_MBUF_BURST_SZ];
- uint32_t i;
- struct pmd_internals *pi = rxvq->internals;
-
- nb_used = VIRTQUEUE_NUSED(rxvq);
-
- rte_smp_rmb();
- num = (uint16_t)(likely(nb_used <= nb_pkts) ? nb_used : nb_pkts);
- num = (uint16_t)(likely(num <= VIRTIO_MBUF_BURST_SZ) ? num : VIRTIO_MBUF_BURST_SZ);
- if (unlikely(num == 0)) return 0;
-
- num = virtqueue_dequeue_burst(rxvq, rx_pkts, len, num);
- PMD_RX_LOG(DEBUG, "used:%d dequeue:%d\n", nb_used, num);
- for (i = 0; i < num ; i ++) {
- rxm = rx_pkts[i];
- PMD_RX_LOG(DEBUG, "packet len:%d\n", len[i]);
- rxm->next = NULL;
- rxm->data_off = RTE_PKTMBUF_HEADROOM;
- rxm->data_len = (uint16_t)(len[i] - sizeof(struct virtio_net_hdr));
- rxm->nb_segs = 1;
- rxm->port = pi->port_id;
- rxm->pkt_len = (uint32_t)(len[i] - sizeof(struct virtio_net_hdr));
- }
- /* allocate new mbuf for the used descriptor */
- while (likely(!virtqueue_full(rxvq))) {
- new_mbuf = rte_mbuf_raw_alloc(rxvq->mpool);
- if (unlikely(new_mbuf == NULL)) {
- break;
- }
- if (unlikely(virtqueue_enqueue_recv_refill(rxvq, new_mbuf))) {
- rte_pktmbuf_free_seg(new_mbuf);
- break;
- }
- }
- pi->eth_stats.ipackets += num;
- return num;
-}
-
-static uint16_t
-eth_xenvirt_tx(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
-{
- struct virtqueue *txvq = tx_queue;
- struct rte_mbuf *txm;
- uint16_t nb_used, nb_tx, num, i;
- int error;
- uint32_t len[VIRTIO_MBUF_BURST_SZ];
- struct rte_mbuf *snd_pkts[VIRTIO_MBUF_BURST_SZ];
- struct pmd_internals *pi = txvq->internals;
-
- nb_tx = 0;
-
- if (unlikely(nb_pkts == 0))
- return 0;
-
- PMD_TX_LOG(DEBUG, "%d packets to xmit", nb_pkts);
- nb_used = VIRTQUEUE_NUSED(txvq);
-
- rte_smp_rmb();
-
- num = (uint16_t)(likely(nb_used <= VIRTIO_MBUF_BURST_SZ) ? nb_used : VIRTIO_MBUF_BURST_SZ);
- num = virtqueue_dequeue_burst(txvq, snd_pkts, len, num);
-
- for (i = 0; i < num ; i ++) {
- /* mergable not supported, one segment only */
- rte_pktmbuf_free_seg(snd_pkts[i]);
- }
-
- while (nb_tx < nb_pkts) {
- if (likely(!virtqueue_full(txvq))) {
- /* TODO drop tx_pkts if it contains multiple segments */
- txm = tx_pkts[nb_tx];
- error = virtqueue_enqueue_xmit(txvq, txm);
- if (unlikely(error)) {
- if (error == ENOSPC)
- PMD_TX_LOG(ERR, "virtqueue_enqueue Free count = 0\n");
- else if (error == EMSGSIZE)
- PMD_TX_LOG(ERR, "virtqueue_enqueue Free count < 1\n");
- else
- PMD_TX_LOG(ERR, "virtqueue_enqueue error: %d\n", error);
- break;
- }
- nb_tx++;
- } else {
- PMD_TX_LOG(ERR, "No free tx descriptors to transmit\n");
- /* virtqueue_notify not needed in our para-virt solution */
- break;
- }
- }
- pi->eth_stats.opackets += nb_tx;
- return nb_tx;
-}
-
-static int
-eth_dev_configure(struct rte_eth_dev *dev __rte_unused)
-{
- RTE_LOG(ERR, PMD, "%s\n", __func__);
- return 0;
-}
-
-/*
- * Create a shared page between guest and host.
- * Host monitors this page if it is cleared on unmap, and then
- * do necessary clean up.
- */
-static void
-gntalloc_vring_flag(int vtidx)
-{
- char key_str[PATH_MAX];
- char val_str[PATH_MAX];
- uint32_t gref_tmp;
- void *ptr;
-
- if (grefwatch_from_alloc(&gref_tmp, &ptr)) {
- RTE_LOG(ERR, PMD, "grefwatch_from_alloc error\n");
- exit(0);
- }
-
- *(uint8_t *)ptr = MAP_FLAG;
- snprintf(val_str, sizeof(val_str), "%u", gref_tmp);
- snprintf(key_str, sizeof(key_str),
- DPDK_XENSTORE_PATH"%d"VRING_FLAG_STR, vtidx);
- xenstore_write(key_str, val_str);
-}
-
-/*
- * Notify host this virtio device is started.
- * Host could start polling this device.
- */
-static void
-dev_start_notify(int vtidx)
-{
- char key_str[PATH_MAX];
- char val_str[PATH_MAX];
-
- RTE_LOG(INFO, PMD, "%s: virtio %d is started\n", __func__, vtidx);
- gntalloc_vring_flag(vtidx);
-
- snprintf(key_str, sizeof(key_str), "%s%s%d",
- DPDK_XENSTORE_PATH, EVENT_TYPE_START_STR,
- vtidx);
- snprintf(val_str, sizeof(val_str), "1");
- xenstore_write(key_str, val_str);
-}
-
-/*
- * Notify host this virtio device is stopped.
- * Host could stop polling this device.
- */
-static void
-dev_stop_notify(int vtidx)
-{
- RTE_SET_USED(vtidx);
-}
-
-
-static int
-update_mac_address(struct ether_addr *mac_addrs, int vtidx)
-{
- char key_str[PATH_MAX];
- char val_str[PATH_MAX];
- int rv;
-
- if (mac_addrs == NULL) {
- RTE_LOG(ERR, PMD, "%s: NULL pointer mac specified\n", __func__);
- return -1;
- }
- rv = snprintf(key_str, sizeof(key_str),
- DPDK_XENSTORE_PATH"%d_ether_addr", vtidx);
- if (rv == -1)
- return rv;
- rv = snprintf(val_str, sizeof(val_str), "%02x:%02x:%02x:%02x:%02x:%02x",
- mac_addrs->addr_bytes[0],
- mac_addrs->addr_bytes[1],
- mac_addrs->addr_bytes[2],
- mac_addrs->addr_bytes[3],
- mac_addrs->addr_bytes[4],
- mac_addrs->addr_bytes[5]);
- if (rv == -1)
- return rv;
- if (xenstore_write(key_str, val_str))
- return rv;
- return 0;
-}
-
-
-static int
-eth_dev_start(struct rte_eth_dev *dev)
-{
- struct virtqueue *rxvq = dev->data->rx_queues[0];
- struct virtqueue *txvq = dev->data->tx_queues[0];
- struct rte_mbuf *m;
- struct pmd_internals *pi = (struct pmd_internals *)dev->data->dev_private;
- int rv;
-
- dev->data->dev_link.link_status = ETH_LINK_UP;
- while (!virtqueue_full(rxvq)) {
- m = rte_mbuf_raw_alloc(rxvq->mpool);
- if (m == NULL)
- break;
- /* Enqueue allocated buffers. */
- if (virtqueue_enqueue_recv_refill(rxvq, m)) {
- rte_pktmbuf_free_seg(m);
- break;
- }
- }
-
- rxvq->internals = pi;
- txvq->internals = pi;
-
- rv = update_mac_address(dev->data->mac_addrs, pi->virtio_idx);
- if (rv)
- return -1;
- dev_start_notify(pi->virtio_idx);
-
- return 0;
-}
-
-static void
-eth_dev_stop(struct rte_eth_dev *dev)
-{
- struct pmd_internals *pi = (struct pmd_internals *)dev->data->dev_private;
-
- dev->data->dev_link.link_status = ETH_LINK_DOWN;
- dev_stop_notify(pi->virtio_idx);
-}
-
-/*
- * Notify host this virtio device is closed.
- * Host could do necessary clean up to this device.
- */
-static void
-eth_dev_close(struct rte_eth_dev *dev)
-{
- eth_xenvirt_free_queues(dev);
-}
-
-static void
-eth_dev_info(struct rte_eth_dev *dev,
- struct rte_eth_dev_info *dev_info)
-{
- struct pmd_internals *internals = dev->data->dev_private;
-
- RTE_SET_USED(internals);
- dev_info->max_mac_addrs = 1;
- dev_info->max_rx_pktlen = (uint32_t)2048;
- dev_info->max_rx_queues = (uint16_t)1;
- dev_info->max_tx_queues = (uint16_t)1;
- dev_info->min_rx_bufsize = 0;
-}
-
-static void
-eth_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
-{
- struct pmd_internals *internals = dev->data->dev_private;
- if(stats)
- rte_memcpy(stats, &internals->eth_stats, sizeof(*stats));
-}
-
-static void
-eth_stats_reset(struct rte_eth_dev *dev)
-{
- struct pmd_internals *internals = dev->data->dev_private;
- /* Reset software totals */
- memset(&internals->eth_stats, 0, sizeof(internals->eth_stats));
-}
-
-static void
-eth_queue_release(void *q)
-{
- rte_free(q);
-}
-
-static int
-eth_link_update(struct rte_eth_dev *dev __rte_unused,
- int wait_to_complete __rte_unused)
-{
- return 0;
-}
-
-/*
- * Create shared vring between guest and host.
- * Memory is allocated through grant alloc driver, so it is not physical continuous.
- */
-static void *
-gntalloc_vring_create(int queue_type, uint32_t size, int vtidx)
-{
- char key_str[PATH_MAX] = {0};
- char val_str[PATH_MAX] = {0};
- void *va = NULL;
- int pg_size;
- uint32_t pg_num;
- uint32_t *gref_arr = NULL;
- phys_addr_t *pa_arr = NULL;
- uint64_t start_index;
- int rv;
-
- pg_size = getpagesize();
- size = RTE_ALIGN_CEIL(size, pg_size);
- pg_num = size / pg_size;
-
- gref_arr = calloc(pg_num, sizeof(gref_arr[0]));
- pa_arr = calloc(pg_num, sizeof(pa_arr[0]));
-
- if (gref_arr == NULL || pa_arr == NULL) {
- RTE_LOG(ERR, PMD, "%s: calloc failed\n", __func__);
- goto out;
- }
-
- va = gntalloc(size, gref_arr, &start_index);
- if (va == NULL) {
- RTE_LOG(ERR, PMD, "%s: gntalloc failed\n", __func__);
- goto out;
- }
-
- if (get_phys_map(va, pa_arr, pg_num, pg_size))
- goto out;
-
- /* write in xenstore gref and pfn for each page of vring */
- if (grant_node_create(pg_num, gref_arr, pa_arr, val_str, sizeof(val_str))) {
- gntfree(va, size, start_index);
- va = NULL;
- goto out;
- }
-
- if (queue_type == VTNET_RQ)
- rv = snprintf(key_str, sizeof(key_str), DPDK_XENSTORE_PATH"%d"RXVRING_XENSTORE_STR, vtidx);
- else
- rv = snprintf(key_str, sizeof(key_str), DPDK_XENSTORE_PATH"%d"TXVRING_XENSTORE_STR, vtidx);
- if (rv == -1 || xenstore_write(key_str, val_str) == -1) {
- gntfree(va, size, start_index);
- va = NULL;
- }
-out:
- free(pa_arr);
- free(gref_arr);
-
- return va;
-}
-
-
-
-static struct virtqueue *
-virtio_queue_setup(struct rte_eth_dev *dev, int queue_type)
-{
- struct virtqueue *vq = NULL;
- uint16_t vq_size = VQ_DESC_NUM;
- int i = 0;
- char vq_name[VIRTQUEUE_MAX_NAME_SZ];
- size_t size;
- struct vring *vr;
-
- /* Allocate memory for virtqueue. */
- if (queue_type == VTNET_RQ) {
- snprintf(vq_name, sizeof(vq_name), "port%d_rvq",
- dev->data->port_id);
- vq = rte_zmalloc(vq_name, sizeof(struct virtqueue) +
- vq_size * sizeof(struct vq_desc_extra), RTE_CACHE_LINE_SIZE);
- if (vq == NULL) {
- RTE_LOG(ERR, PMD, "%s: unabled to allocate virtqueue\n", __func__);
- return NULL;
- }
- memcpy(vq->vq_name, vq_name, sizeof(vq->vq_name));
- } else if(queue_type == VTNET_TQ) {
- snprintf(vq_name, sizeof(vq_name), "port%d_tvq",
- dev->data->port_id);
- vq = rte_zmalloc(vq_name, sizeof(struct virtqueue) +
- vq_size * sizeof(struct vq_desc_extra), RTE_CACHE_LINE_SIZE);
- if (vq == NULL) {
- RTE_LOG(ERR, PMD, "%s: unabled to allocate virtqueue\n", __func__);
- return NULL;
- }
- memcpy(vq->vq_name, vq_name, sizeof(vq->vq_name));
- }
-
- memcpy(vq->vq_name, vq_name, sizeof(vq->vq_name));
-
- vq->vq_alignment = VIRTIO_PCI_VRING_ALIGN;
- vq->vq_nentries = vq_size;
- vq->vq_free_cnt = vq_size;
- /* Calcuate vring size according to virtio spec */
- size = vring_size(vq_size, VIRTIO_PCI_VRING_ALIGN);
- vq->vq_ring_size = RTE_ALIGN_CEIL(size, VIRTIO_PCI_VRING_ALIGN);
- /* Allocate memory for virtio vring through gntalloc driver*/
- vq->vq_ring_virt_mem = gntalloc_vring_create(queue_type, vq->vq_ring_size,
- ((struct pmd_internals *)dev->data->dev_private)->virtio_idx);
- memset(vq->vq_ring_virt_mem, 0, vq->vq_ring_size);
- vr = &vq->vq_ring;
- vring_init(vr, vq_size, vq->vq_ring_virt_mem, vq->vq_alignment);
- /*
- * Locally maintained last consumed index, this idex trails
- * vq_ring.used->idx.
- */
- vq->vq_used_cons_idx = 0;
- vq->vq_desc_head_idx = 0;
- vq->vq_free_cnt = vq->vq_nentries;
- memset(vq->vq_descx, 0, sizeof(struct vq_desc_extra) * vq->vq_nentries);
-
- /* Chain all the descriptors in the ring with an END */
- for (i = 0; i < vq_size - 1; i++)
- vr->desc[i].next = (uint16_t)(i + 1);
- vr->desc[i].next = VQ_RING_DESC_CHAIN_END;
-
- return vq;
-}
-
-static int
-eth_rx_queue_setup(struct rte_eth_dev *dev,uint16_t rx_queue_id,
- uint16_t nb_rx_desc __rte_unused,
- unsigned int socket_id __rte_unused,
- const struct rte_eth_rxconf *rx_conf __rte_unused,
- struct rte_mempool *mb_pool)
-{
- struct virtqueue *vq;
- vq = dev->data->rx_queues[rx_queue_id] = virtio_queue_setup(dev, VTNET_RQ);
- vq->mpool = mb_pool;
- return 0;
-}
-
-static int
-eth_tx_queue_setup(struct rte_eth_dev *dev, uint16_t tx_queue_id,
- uint16_t nb_tx_desc __rte_unused,
- unsigned int socket_id __rte_unused,
- const struct rte_eth_txconf *tx_conf __rte_unused)
-{
- dev->data->tx_queues[tx_queue_id] = virtio_queue_setup(dev, VTNET_TQ);
- return 0;
-}
-
-static void
-eth_xenvirt_free_queues(struct rte_eth_dev *dev)
-{
- int i;
-
- for (i = 0; i < dev->data->nb_rx_queues; i++) {
- eth_queue_release(dev->data->rx_queues[i]);
- dev->data->rx_queues[i] = NULL;
- }
- dev->data->nb_rx_queues = 0;
-
- for (i = 0; i < dev->data->nb_tx_queues; i++) {
- eth_queue_release(dev->data->tx_queues[i]);
- dev->data->tx_queues[i] = NULL;
- }
- dev->data->nb_tx_queues = 0;
-}
-
-static const struct eth_dev_ops ops = {
- .dev_start = eth_dev_start,
- .dev_stop = eth_dev_stop,
- .dev_close = eth_dev_close,
- .dev_configure = eth_dev_configure,
- .dev_infos_get = eth_dev_info,
- .rx_queue_setup = eth_rx_queue_setup,
- .tx_queue_setup = eth_tx_queue_setup,
- .rx_queue_release = eth_queue_release,
- .tx_queue_release = eth_queue_release,
- .link_update = eth_link_update,
- .stats_get = eth_stats_get,
- .stats_reset = eth_stats_reset,
-};
-
-
-static int
-rte_eth_xenvirt_parse_args(struct xenvirt_dict *dict,
- const char *name, const char *params)
-{
- int i;
- char *pairs[RTE_ETH_XENVIRT_MAX_ARGS];
- int num_of_pairs;
- char *pair[2];
- char *args;
- int ret = -1;
-
- if (params == NULL)
- return 0;
-
- args = rte_zmalloc(NULL, strlen(params) + 1, RTE_CACHE_LINE_SIZE);
- if (args == NULL) {
- RTE_LOG(ERR, PMD, "Couldn't parse %s device \n", name);
- return -1;
- }
- rte_memcpy(args, params, strlen(params));
-
- num_of_pairs = rte_strsplit(args, strnlen(args, MAX_ARG_STRLEN),
- pairs,
- RTE_ETH_XENVIRT_MAX_ARGS ,
- RTE_ETH_XENVIRT_PAIRS_DELIM);
-
- for (i = 0; i < num_of_pairs; i++) {
- pair[0] = NULL;
- pair[1] = NULL;
- rte_strsplit(pairs[i], strnlen(pairs[i], MAX_ARG_STRLEN),
- pair, 2,
- RTE_ETH_XENVIRT_KEY_VALUE_DELIM);
-
- if (pair[0] == NULL || pair[1] == NULL || pair[0][0] == 0
- || pair[1][0] == 0) {
- RTE_LOG(ERR, PMD,
- "Couldn't parse %s device,"
- "wrong key or value \n", name);
- goto err;
- }
-
- if (!strncmp(pair[0], RTE_ETH_XENVIRT_MAC_PARAM,
- sizeof(RTE_ETH_XENVIRT_MAC_PARAM))) {
- if (cmdline_parse_etheraddr(NULL,
- pair[1],
- &dict->addr,
- sizeof(dict->addr)) < 0) {
- RTE_LOG(ERR, PMD,
- "Invalid %s device ether address\n",
- name);
- goto err;
- }
-
- dict->addr_valid = 1;
- }
- }
-
- ret = 0;
-err:
- rte_free(args);
- return ret;
-}
-
-enum dev_action {
- DEV_CREATE,
- DEV_ATTACH
-};
-
-static struct rte_vdev_driver pmd_xenvirt_drv;
-
-static int
-eth_dev_xenvirt_create(const char *name, const char *params,
- const unsigned numa_node,
- enum dev_action action)
-{
- struct rte_eth_dev_data *data = NULL;
- struct pmd_internals *internals = NULL;
- struct rte_eth_dev *eth_dev = NULL;
- struct xenvirt_dict dict;
-
- memset(&dict, 0, sizeof(struct xenvirt_dict));
-
- RTE_LOG(INFO, PMD, "Creating virtio rings backed ethdev on numa socket %u\n",
- numa_node);
- RTE_SET_USED(action);
-
- if (rte_eth_xenvirt_parse_args(&dict, name, params) < 0) {
- RTE_LOG(ERR, PMD, "%s: Failed to parse ethdev parameters\n", __func__);
- return -1;
- }
-
- /* now do all data allocation - for eth_dev structure, dummy pci driver
- * and internal (private) data
- */
- data = rte_zmalloc_socket(name, sizeof(*data), 0, numa_node);
- if (data == NULL)
- goto err;
-
- internals = rte_zmalloc_socket(name, sizeof(*internals), 0, numa_node);
- if (internals == NULL)
- goto err;
-
- /* reserve an ethdev entry */
- eth_dev = rte_eth_dev_allocate(name);
- if (eth_dev == NULL)
- goto err;
-
- data->dev_private = internals;
- data->port_id = eth_dev->data->port_id;
- data->nb_rx_queues = (uint16_t)1;
- data->nb_tx_queues = (uint16_t)1;
- data->dev_link = pmd_link;
- data->mac_addrs = rte_zmalloc("xen_virtio", ETHER_ADDR_LEN, 0);
-
- if(dict.addr_valid)
- memcpy(&data->mac_addrs->addr_bytes, &dict.addr, sizeof(struct ether_addr));
- else
- eth_random_addr(&data->mac_addrs->addr_bytes[0]);
-
- eth_dev->data = data;
- eth_dev->dev_ops = &ops;
-
- eth_dev->data->dev_flags = RTE_ETH_DEV_DETACHABLE;
- eth_dev->data->kdrv = RTE_KDRV_NONE;
- eth_dev->data->numa_node = numa_node;
-
- eth_dev->rx_pkt_burst = eth_xenvirt_rx;
- eth_dev->tx_pkt_burst = eth_xenvirt_tx;
-
- internals->virtio_idx = virtio_idx++;
- internals->port_id = eth_dev->data->port_id;
-
- return 0;
-
-err:
- rte_free(data);
- rte_free(internals);
-
- return -1;
-}
-
-
-static int
-eth_dev_xenvirt_free(const char *name, const unsigned numa_node)
-{
- struct rte_eth_dev *eth_dev = NULL;
-
- RTE_LOG(DEBUG, PMD,
- "Free virtio rings backed ethdev on numa socket %u\n",
- numa_node);
-
- /* find an ethdev entry */
- eth_dev = rte_eth_dev_allocated(name);
- if (eth_dev == NULL)
- return -1;
-
- if (eth_dev->data->dev_started == 1) {
- eth_dev_stop(eth_dev);
- eth_dev_close(eth_dev);
- }
-
- eth_dev->rx_pkt_burst = NULL;
- eth_dev->tx_pkt_burst = NULL;
- eth_dev->dev_ops = NULL;
-
- rte_free(eth_dev->data);
- rte_free(eth_dev->data->dev_private);
- rte_free(eth_dev->data->mac_addrs);
-
- virtio_idx--;
-
- return 0;
-}
-
-/*TODO: Support multiple process model */
-static int
-rte_pmd_xenvirt_probe(struct rte_vdev_device *dev)
-{
- if (virtio_idx == 0) {
- if (xenstore_init() != 0) {
- RTE_LOG(ERR, PMD, "%s: xenstore init failed\n", __func__);
- return -1;
- }
- if (gntalloc_open() != 0) {
- RTE_LOG(ERR, PMD, "%s: grant init failed\n", __func__);
- return -1;
- }
- }
- eth_dev_xenvirt_create(rte_vdev_device_name(dev),
- rte_vdev_device_args(dev), rte_socket_id(), DEV_CREATE);
- return 0;
-}
-
-static int
-rte_pmd_xenvirt_remove(struct rte_vdev_device *dev)
-{
- eth_dev_xenvirt_free(rte_vdev_device_name(dev), rte_socket_id());
-
- if (virtio_idx == 0) {
- if (xenstore_uninit() != 0)
- RTE_LOG(ERR, PMD, "%s: xenstore uninit failed\n", __func__);
-
- gntalloc_close();
- }
- return 0;
-}
-
-static struct rte_vdev_driver pmd_xenvirt_drv = {
- .probe = rte_pmd_xenvirt_probe,
- .remove = rte_pmd_xenvirt_remove,
-};
-
-RTE_PMD_REGISTER_VDEV(net_xenvirt, pmd_xenvirt_drv);
-RTE_PMD_REGISTER_ALIAS(net_xenvirt, eth_xenvirt);
-RTE_PMD_REGISTER_PARAM_STRING(net_xenvirt,
- "mac=<mac addr>");
diff --git a/drivers/net/xenvirt/rte_eth_xenvirt.h b/drivers/net/xenvirt/rte_eth_xenvirt.h
deleted file mode 100644
index 598adc6..0000000
--- a/drivers/net/xenvirt/rte_eth_xenvirt.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*-
- * BSD LICENSE
- *
- * Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Intel Corporation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _RTE_ETH_XENVIRT_H_
-#define _RTE_ETH_XENVIRT_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <rte_mempool.h>
-
-/**
- * Creates mempool for xen virtio PMD.
- * This function uses memzone_reserve to allocate memory for meta data,
- * and uses grant alloc driver to allocate memory for data area.
- * The input parameters are exactly the same as rte_mempool_create.
- */
-struct rte_mempool *
-rte_mempool_gntalloc_create(const char *name, unsigned elt_num, unsigned elt_size,
- unsigned cache_size, unsigned private_data_size,
- rte_mempool_ctor_t *mp_init, void *mp_init_arg,
- rte_mempool_obj_cb_t *obj_init, void *obj_init_arg,
- int socket_id, unsigned flags);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/drivers/net/xenvirt/rte_eth_xenvirt_version.map b/drivers/net/xenvirt/rte_eth_xenvirt_version.map
deleted file mode 100644
index dd636f7..0000000
--- a/drivers/net/xenvirt/rte_eth_xenvirt_version.map
+++ /dev/null
@@ -1,7 +0,0 @@
-DPDK_2.0 {
- global:
-
- rte_mempool_gntalloc_create;
-
- local: *;
-};
diff --git a/drivers/net/xenvirt/rte_mempool_gntalloc.c b/drivers/net/xenvirt/rte_mempool_gntalloc.c
deleted file mode 100644
index 73e82f8..0000000
--- a/drivers/net/xenvirt/rte_mempool_gntalloc.c
+++ /dev/null
@@ -1,295 +0,0 @@
-/*-
- * BSD LICENSE
- *
- * Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Intel Corporation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdint.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <sys/mman.h>
-#include <sys/ioctl.h>
-#include <string.h>
-#include <xen/sys/gntalloc.h>
-
-#include <rte_common.h>
-#include <rte_mempool.h>
-#include <rte_memory.h>
-#include <rte_errno.h>
-
-#include "rte_xen_lib.h"
-#include "rte_eth_xenvirt.h"
-
-struct _gntarr {
- uint32_t gref;
- phys_addr_t pa;
- uint64_t index;
- void *va;
-};
-
-struct _mempool_gntalloc_info {
- struct rte_mempool *mp;
- uint32_t pg_num;
- uint32_t *gref_arr;
- phys_addr_t *pa_arr;
- void *va;
- uint32_t mempool_idx;
- uint64_t start_index;
-};
-
-
-static rte_atomic32_t global_xenvirt_mempool_idx = RTE_ATOMIC32_INIT(-1);
-
-static int
-compare(const void *p1, const void *p2)
-{
- return ((const struct _gntarr *)p1)->pa - ((const struct _gntarr *)p2)->pa;
-}
-
-
-static struct _mempool_gntalloc_info
-_create_mempool(const char *name, unsigned elt_num, unsigned elt_size,
- unsigned cache_size, unsigned private_data_size,
- rte_mempool_ctor_t *mp_init, void *mp_init_arg,
- rte_mempool_obj_cb_t *obj_init, void *obj_init_arg,
- int socket_id, unsigned flags)
-{
- struct _mempool_gntalloc_info mgi;
- struct rte_mempool *mp = NULL;
- struct rte_mempool_objsz objsz;
- uint32_t pg_num, rpg_num, pg_shift, pg_sz;
- char *va, *orig_va, *uv; /* uv: from which, the pages could be freed */
- ssize_t sz, usz; /* usz: unused size */
- /*
- * for each page allocated through xen_gntalloc driver,
- * gref_arr:stores grant references,
- * pa_arr: stores physical address,
- * gnt_arr: stores all meta dat
- */
- uint32_t *gref_arr = NULL;
- phys_addr_t *pa_arr = NULL;
- struct _gntarr *gnt_arr = NULL;
- /* start index of the grant referances, used for dealloc*/
- uint64_t start_index;
- uint32_t i, j;
- int rv = 0;
- struct ioctl_gntalloc_dealloc_gref arg;
-
- mgi.mp = NULL;
- va = orig_va = uv = NULL;
- pg_num = rpg_num = 0;
- sz = 0;
-
- pg_sz = getpagesize();
- if (rte_is_power_of_2(pg_sz) == 0) {
- goto out;
- }
- pg_shift = rte_bsf32(pg_sz);
-
- rte_mempool_calc_obj_size(elt_size, flags, &objsz);
- sz = rte_mempool_xmem_size(elt_num, objsz.total_size, pg_shift);
- pg_num = sz >> pg_shift;
-
- pa_arr = calloc(pg_num, sizeof(pa_arr[0]));
- gref_arr = calloc(pg_num, sizeof(gref_arr[0]));
- gnt_arr = calloc(pg_num, sizeof(gnt_arr[0]));
- if ((gnt_arr == NULL) || (gref_arr == NULL) || (pa_arr == NULL))
- goto out;
-
- /* grant index is continuous in ascending order */
- orig_va = gntalloc(sz, gref_arr, &start_index);
- if (orig_va == NULL)
- goto out;
-
- get_phys_map(orig_va, pa_arr, pg_num, pg_sz);
- for (i = 0; i < pg_num; i++) {
- gnt_arr[i].index = start_index + i * pg_sz;
- gnt_arr[i].gref = gref_arr[i];
- gnt_arr[i].pa = pa_arr[i];
- gnt_arr[i].va = RTE_PTR_ADD(orig_va, i * pg_sz);
- }
- qsort(gnt_arr, pg_num, sizeof(struct _gntarr), compare);
-
- va = get_xen_virtual(sz, pg_sz);
- if (va == NULL) {
- goto out;
- }
-
- /*
- * map one by one, as index isn't continuous now.
- * pg_num VMAs, doesn't linux has a limitation on this?
- */
- for (i = 0; i < pg_num; i++) {
- /* update gref_arr and pa_arr after sort */
- gref_arr[i] = gnt_arr[i].gref;
- pa_arr[i] = gnt_arr[i].pa;
- gnt_arr[i].va = mmap(va + i * pg_sz, pg_sz, PROT_READ | PROT_WRITE,
- MAP_SHARED | MAP_FIXED, gntalloc_fd, gnt_arr[i].index);
- if ((gnt_arr[i].va == MAP_FAILED) || (gnt_arr[i].va != (va + i * pg_sz))) {
- RTE_LOG(ERR, PMD, "failed to map %d pages\n", i);
- goto mmap_failed;
- }
- }
-
- /*
- * Check that allocated size is big enough to hold elt_num
- * objects and a calcualte how many bytes are actually required.
- */
- usz = rte_mempool_xmem_usage(va, elt_num, objsz.total_size, pa_arr, pg_num, pg_shift);
- if (usz < 0) {
- mp = NULL;
- i = pg_num;
- goto mmap_failed;
- } else {
- /* unmap unused pages if any */
- uv = RTE_PTR_ADD(va, usz);
- if ((usz = va + sz - uv) > 0) {
-
- RTE_LOG(ERR, PMD,
- "%s(%s): unmap unused %zu of %zu "
- "mmaped bytes @%p orig:%p\n",
- __func__, name, usz, sz, uv, va);
- munmap(uv, usz);
- i = (sz - usz) / pg_sz;
- for (; i < pg_num; i++) {
- arg.count = 1;
- arg.index = gnt_arr[i].index;
- rv = ioctl(gntalloc_fd, IOCTL_GNTALLOC_DEALLOC_GREF, &arg);
- if (rv) {
- /* shouldn't fail here */
- RTE_LOG(ERR, PMD, "va=%p pa=%"PRIu64"x index=%"PRIu64" %s\n",
- gnt_arr[i].va,
- gnt_arr[i].pa,
- arg.index, strerror(errno));
- rte_panic("gntdealloc failed when freeing pages\n");
- }
- }
-
- rpg_num = (sz - usz) >> pg_shift;
- } else
- rpg_num = pg_num;
-
- mp = rte_mempool_xmem_create(name, elt_num, elt_size,
- cache_size, private_data_size,
- mp_init, mp_init_arg,
- obj_init, obj_init_arg,
- socket_id, flags, va, pa_arr, rpg_num, pg_shift);
-
- RTE_ASSERT(elt_num == mp->size);
- }
- mgi.mp = mp;
- mgi.pg_num = rpg_num;
- mgi.gref_arr = gref_arr;
- mgi.pa_arr = pa_arr;
- if (mp)
- mgi.mempool_idx = rte_atomic32_add_return(&global_xenvirt_mempool_idx, 1);
- mgi.start_index = start_index;
- mgi.va = va;
-
- if (mp == NULL) {
- i = pg_num;
- goto mmap_failed;
- }
-
-/*
- * unmap only, without deallocate grant reference.
- * unused pages have already been unmaped,
- * unmap twice will fail, but it is safe.
- */
-mmap_failed:
- for (j = 0; j < i; j++) {
- if (gnt_arr[i].va)
- munmap(gnt_arr[i].va, pg_sz);
- }
-out:
- free(gnt_arr);
- if (orig_va)
- munmap(orig_va, sz);
- if (mp == NULL) {
- free(gref_arr);
- free(pa_arr);
-
- /* some gref has already been de-allocated from the list in the driver,
- * so dealloc one by one, and it is safe to deallocate twice
- */
- if (orig_va) {
- for (i = 0; i < pg_num; i++) {
- arg.index = start_index + i * pg_sz;
- rv = ioctl(gntalloc_fd, IOCTL_GNTALLOC_DEALLOC_GREF, arg);
- }
- }
- }
- return mgi;
-}
-
-struct rte_mempool *
-rte_mempool_gntalloc_create(const char *name, unsigned elt_num, unsigned elt_size,
- unsigned cache_size, unsigned private_data_size,
- rte_mempool_ctor_t *mp_init, void *mp_init_arg,
- rte_mempool_obj_cb_t *obj_init, void *obj_init_arg,
- int socket_id, unsigned flags)
-{
- int rv;
- uint32_t i;
- struct _mempool_gntalloc_info mgi;
- struct ioctl_gntalloc_dealloc_gref arg;
- int pg_sz = getpagesize();
-
- mgi = _create_mempool(name, elt_num, elt_size,
- cache_size, private_data_size,
- mp_init, mp_init_arg,
- obj_init, obj_init_arg,
- socket_id, flags);
- if (mgi.mp) {
- rv = grant_gntalloc_mbuf_pool(mgi.mp,
- mgi.pg_num,
- mgi.gref_arr,
- mgi.pa_arr,
- mgi.mempool_idx);
- free(mgi.gref_arr);
- free(mgi.pa_arr);
- if (rv == 0)
- return mgi.mp;
- /*
- * in _create_mempool, unused pages have already been unmapped, deallocagted
- * unmap and dealloc the remained ones here.
- */
- munmap(mgi.va, pg_sz * mgi.pg_num);
- for (i = 0; i < mgi.pg_num; i++) {
- arg.index = mgi.start_index + i * pg_sz;
- rv = ioctl(gntalloc_fd, IOCTL_GNTALLOC_DEALLOC_GREF, arg);
- }
- return NULL;
- }
- return NULL;
-
-
-
-}
diff --git a/drivers/net/xenvirt/rte_xen_lib.c b/drivers/net/xenvirt/rte_xen_lib.c
deleted file mode 100644
index 6c9a1d4..0000000
--- a/drivers/net/xenvirt/rte_xen_lib.c
+++ /dev/null
@@ -1,454 +0,0 @@
-/*-
- * BSD LICENSE
- *
- * Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Intel Corporation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <sys/mman.h>
-#include <sys/ioctl.h>
-#include <xen/xen-compat.h>
-#if __XEN_LATEST_INTERFACE_VERSION__ < 0x00040200
-#include <xs.h>
-#else
-#include <xenstore.h>
-#endif
-#include <xen/sys/gntalloc.h>
-
-#include <rte_common.h>
-#include <rte_string_fns.h>
-#include <rte_malloc.h>
-
-#include "rte_xen_lib.h"
-
-/*
- * The grant node format in xenstore for vring/mpool is:
- * 0_rx_vring_gref = "gref1#, gref2#, gref3#"
- * 0_mempool_gref = "gref1#, gref2#, gref3#"
- * each gref# is a grant reference for a shared page.
- * In each shared page, we store the grant_node_item items.
- */
-struct grant_node_item {
- uint32_t gref;
- uint32_t pfn;
-} __attribute__((packed));
-
-/* fd for xen_gntalloc driver, used to allocate grant pages*/
-int gntalloc_fd = -1;
-
-/* xenstore path for local domain, now it is '/local/domain/domid/' */
-static char *dompath = NULL;
-/* handle to xenstore read/write operations */
-static struct xs_handle *xs = NULL;
-/* flag to indicate if xenstore cleanup is required */
-static bool is_xenstore_cleaned_up;
-
-/*
- * Reserve a virtual address space.
- * On success, returns the pointer. On failure, returns NULL.
- */
-void *
-get_xen_virtual(size_t size, size_t page_sz)
-{
- void *addr;
- uintptr_t aligned_addr;
-
- addr = mmap(NULL, size + page_sz, PROT_READ, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
- if (addr == MAP_FAILED) {
- RTE_LOG(ERR, PMD, "failed get a virtual area\n");
- return NULL;
- }
-
- aligned_addr = RTE_ALIGN_CEIL((uintptr_t)addr, page_sz);
- addr = (void *)(aligned_addr);
-
- return addr;
-}
-
-/*
- * Get the physical address for virtual memory starting at va.
- */
-int
-get_phys_map(void *va, phys_addr_t pa[], uint32_t pg_num, uint32_t pg_sz)
-{
- int32_t fd, rc = 0;
- uint32_t i, nb;
- off_t ofs;
-
- ofs = (uintptr_t)va / pg_sz * sizeof(*pa);
- nb = pg_num * sizeof(*pa);
-
- if ((fd = open(PAGEMAP_FNAME, O_RDONLY)) < 0 ||
- (rc = pread(fd, pa, nb, ofs)) < 0 ||
- (rc -= nb) != 0) {
- RTE_LOG(ERR, PMD, "%s: failed read of %u bytes from \'%s\' "
- "at offset %lu, error code: %d\n",
- __func__, nb, PAGEMAP_FNAME, (unsigned long)ofs, errno);
- rc = ENOENT;
- }
-
- close(fd);
- for (i = 0; i != pg_num; i++)
- pa[i] = (pa[i] & PAGEMAP_PFN_MASK) * pg_sz;
-
- return rc;
-}
-
-int
-gntalloc_open(void)
-{
- gntalloc_fd = open(XEN_GNTALLOC_FNAME, O_RDWR);
- return (gntalloc_fd != -1) ? 0 : -1;
-}
-
-void
-gntalloc_close(void)
-{
- if (gntalloc_fd != -1)
- close(gntalloc_fd);
- gntalloc_fd = -1;
-}
-
-void *
-gntalloc(size_t size, uint32_t *gref, uint64_t *start_index)
-{
- int page_size = getpagesize();
- uint32_t i, pg_num;
- void *va;
- int rv;
- struct ioctl_gntalloc_alloc_gref *arg;
- struct ioctl_gntalloc_dealloc_gref arg_d;
-
- if (size % page_size) {
- RTE_LOG(ERR, PMD, "%s: %zu isn't multiple of page size\n",
- __func__, size);
- return NULL;
- }
-
- pg_num = size / page_size;
- arg = malloc(sizeof(*arg) + (pg_num - 1) * sizeof(uint32_t));
- if (arg == NULL)
- return NULL;
- arg->domid = DOM0_DOMID;
- arg->flags = GNTALLOC_FLAG_WRITABLE;
- arg->count = pg_num;
-
- rv = ioctl(gntalloc_fd, IOCTL_GNTALLOC_ALLOC_GREF, arg);
- if (rv) {
- RTE_LOG(ERR, PMD, "%s: ioctl error\n", __func__);
- free(arg);
- return NULL;
- }
-
- va = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, gntalloc_fd, arg->index);
- if (va == MAP_FAILED) {
- RTE_LOG(ERR, PMD, "%s: mmap failed\n", __func__);
- arg_d.count = pg_num;
- arg_d.index = arg->index;
- ioctl(gntalloc_fd, IOCTL_GNTALLOC_DEALLOC_GREF, arg_d);
- free(arg);
- return NULL;
- }
-
- if (gref) {
- for (i = 0; i < pg_num; i++) {
- gref[i] = arg->gref_ids[i];
- }
- }
- if (start_index)
- *start_index = arg->index;
-
- free(arg);
-
- return va;
-}
-
-int
-grefwatch_from_alloc(uint32_t *gref, void **pptr)
-{
- int rv;
- void *ptr;
- int pg_size = getpagesize();
- struct ioctl_gntalloc_alloc_gref arg = {
- .domid = DOM0_DOMID,
- .flags = GNTALLOC_FLAG_WRITABLE,
- .count = 1
- };
- struct ioctl_gntalloc_dealloc_gref arg_d;
- struct ioctl_gntalloc_unmap_notify notify = {
- .action = UNMAP_NOTIFY_CLEAR_BYTE
- };
-
- rv = ioctl(gntalloc_fd, IOCTL_GNTALLOC_ALLOC_GREF, &arg);
- if (rv) {
- RTE_LOG(ERR, PMD, "%s: ioctl error\n", __func__);
- return -1;
- }
-
- ptr = (void *)mmap(NULL, pg_size, PROT_READ|PROT_WRITE, MAP_SHARED, gntalloc_fd, arg.index);
- arg_d.index = arg.index;
- arg_d.count = 1;
- if (ptr == MAP_FAILED) {
- RTE_LOG(ERR, PMD, "%s: mmap failed\n", __func__);
- ioctl(gntalloc_fd, IOCTL_GNTALLOC_DEALLOC_GREF, &arg_d);
- return -1;
- }
- if (pptr)
- *pptr = ptr;
- if (gref)
- *gref = arg.gref_ids[0];
-
- notify.index = arg.index;
- rv = ioctl(gntalloc_fd, IOCTL_GNTALLOC_SET_UNMAP_NOTIFY, ¬ify);
- if (rv) {
- RTE_LOG(ERR, PMD, "%s: unmap notify failed\n", __func__);
- munmap(ptr, pg_size);
- ioctl(gntalloc_fd, IOCTL_GNTALLOC_DEALLOC_GREF, &arg_d);
- return -1;
- }
-
- return 0;
-}
-
-void
-gntfree(void *va, size_t sz, uint64_t start_index)
-{
- struct ioctl_gntalloc_dealloc_gref arg_d;
-
- if (va && sz) {
- munmap(va, sz);
- arg_d.count = sz / getpagesize();
- arg_d.index = start_index;
- ioctl(gntalloc_fd, IOCTL_GNTALLOC_DEALLOC_GREF, &arg_d);
- }
-}
-
-static int
-xenstore_cleanup(void)
-{
- char store_path[PATH_MAX] = {0};
-
- if (snprintf(store_path, sizeof(store_path),
- "%s%s", dompath, DPDK_XENSTORE_NODE) == -1)
- return -1;
-
- if (xs_rm(xs, XBT_NULL, store_path) == false) {
- RTE_LOG(ERR, PMD, "%s: failed cleanup node\n", __func__);
- return -1;
- }
-
- return 0;
-}
-
-int
-xenstore_init(void)
-{
- unsigned int len, domid;
- char *buf;
- char *end;
-
- xs = xs_domain_open();
- if (xs == NULL) {
- RTE_LOG(ERR, PMD,"%s: xs_domain_open failed\n", __func__);
- return -1;
- }
- buf = xs_read(xs, XBT_NULL, "domid", &len);
- if (buf == NULL) {
- RTE_LOG(ERR, PMD, "%s: failed read domid\n", __func__);
- return -1;
- }
- errno = 0;
- domid = strtoul(buf, &end, 0);
- if (errno != 0 || end == NULL || end == buf || domid == 0)
- return -1;
-
- RTE_LOG(INFO, PMD, "retrieved dom ID = %d\n", domid);
-
- dompath = xs_get_domain_path(xs, domid);
- if (dompath == NULL)
- return -1;
-
- xs_transaction_start(xs); /* When to stop transaction */
-
- if (is_xenstore_cleaned_up == 0) {
- if (xenstore_cleanup())
- return -1;
- is_xenstore_cleaned_up = 1;
- }
-
- return 0;
-}
-
-int
-xenstore_uninit(void)
-{
- xs_close(xs);
-
- if (is_xenstore_cleaned_up == 0) {
- if (xenstore_cleanup())
- return -1;
- is_xenstore_cleaned_up = 1;
- }
- free(dompath);
- dompath = NULL;
-
- return 0;
-}
-
-int
-xenstore_write(const char *key_str, const char *val_str)
-{
- char grant_path[PATH_MAX];
- int rv, len;
-
- if (xs == NULL) {
- RTE_LOG(ERR, PMD, "%s: xenstore init failed\n", __func__);
- return -1;
- }
- rv = snprintf(grant_path, sizeof(grant_path), "%s%s", dompath, key_str);
- if (rv == -1) {
- RTE_LOG(ERR, PMD, "%s: snprintf %s %s failed\n",
- __func__, dompath, key_str);
- return -1;
- }
- len = strnlen(val_str, PATH_MAX);
-
- if (xs_write(xs, XBT_NULL, grant_path, val_str, len) == false) {
- RTE_LOG(ERR, PMD, "%s: xs_write failed\n", __func__);
- return -1;
- }
-
- return 0;
-}
-
-int
-grant_node_create(uint32_t pg_num, uint32_t *gref_arr, phys_addr_t *pa_arr, char *val_str, size_t str_size)
-{
- uint64_t start_index;
- int pg_size;
- uint32_t pg_shift;
- void *ptr = NULL;
- uint32_t count, entries_per_pg;
- uint32_t i, j = 0, k = 0;
- uint32_t *gref_tmp;
- int first = 1;
- char tmp_str[PATH_MAX] = {0};
- int rv = -1;
-
- pg_size = getpagesize();
- if (rte_is_power_of_2(pg_size) == 0) {
- return -1;
- }
- pg_shift = rte_bsf32(pg_size);
- if (pg_size % sizeof(struct grant_node_item)) {
- RTE_LOG(ERR, PMD, "pg_size isn't a multiple of grant node item\n");
- return -1;
- }
-
- entries_per_pg = pg_size / sizeof(struct grant_node_item);
- count = (pg_num + entries_per_pg - 1 ) / entries_per_pg;
- gref_tmp = malloc(count * sizeof(uint32_t));
- if (gref_tmp == NULL)
- return -1;
- ptr = gntalloc(pg_size * count, gref_tmp, &start_index);
- if (ptr == NULL) {
- RTE_LOG(ERR, PMD, "%s: gntalloc error of %d pages\n", __func__, count);
- free(gref_tmp);
- return -1;
- }
-
- while (j < pg_num) {
- if (first) {
- rv = snprintf(val_str, str_size, "%u", gref_tmp[k]);
- first = 0;
- } else {
- snprintf(tmp_str, PATH_MAX, "%s", val_str);
- rv = snprintf(val_str, str_size, "%s,%u", tmp_str, gref_tmp[k]);
- }
- k++;
- if (rv == -1)
- break;
-
- for (i = 0; i < entries_per_pg && j < pg_num ; i++) {
- ((struct grant_node_item *)ptr)->gref = gref_arr[j];
- ((struct grant_node_item *)ptr)->pfn = pa_arr[j] >> pg_shift;
- ptr = RTE_PTR_ADD(ptr, sizeof(struct grant_node_item));
- j++;
- }
- }
- if (rv == -1) {
- gntfree(ptr, pg_size * count, start_index);
- } else
- rv = 0;
- free(gref_tmp);
- return rv;
-}
-
-
-int
-grant_gntalloc_mbuf_pool(struct rte_mempool *mpool, uint32_t pg_num, uint32_t *gref_arr, phys_addr_t *pa_arr, int mempool_idx)
-{
- char key_str[PATH_MAX] = {0};
- char val_str[PATH_MAX] = {0};
- void *mempool_obj_va;
-
- if (grant_node_create(pg_num, gref_arr, pa_arr, val_str, sizeof(val_str))) {
- return -1;
- }
-
- if (snprintf(key_str, sizeof(key_str),
- DPDK_XENSTORE_PATH"%d"MEMPOOL_XENSTORE_STR, mempool_idx) == -1)
- return -1;
- if (xenstore_write(key_str, val_str) == -1)
- return -1;
-
- if (snprintf(key_str, sizeof(key_str),
- DPDK_XENSTORE_PATH"%d"MEMPOOL_VA_XENSTORE_STR, mempool_idx) == -1)
- return -1;
- if (mpool->nb_mem_chunks != 1) {
- RTE_LOG(ERR, PMD,
- "mempool with more than 1 chunk is not supported\n");
- return -1;
- }
- mempool_obj_va = STAILQ_FIRST(&mpool->mem_list)->addr;
- if (snprintf(val_str, sizeof(val_str), "%"PRIxPTR,
- (uintptr_t)mempool_obj_va) == -1)
- return -1;
- if (xenstore_write(key_str, val_str) == -1)
- return -1;
-
- return 0;
-}
diff --git a/drivers/net/xenvirt/rte_xen_lib.h b/drivers/net/xenvirt/rte_xen_lib.h
deleted file mode 100644
index d973eac..0000000
--- a/drivers/net/xenvirt/rte_xen_lib.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/*-
- * BSD LICENSE
- *
- * Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Intel Corporation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _RTE_XEN_DUMMY_PMD_H
-#define _RTE_XEN_DUMMY_PMD_H
-
-#include <stdint.h>
-
-#include <rte_common.h>
-#include <rte_mempool.h>
-#include <rte_ether.h>
-
-#define PAGEMAP_FNAME "/proc/self/pagemap"
-#define XEN_GNTALLOC_FNAME "/dev/xen/gntalloc"
-#define DPDK_XENSTORE_PATH "/control/dpdk/"
-#define DPDK_XENSTORE_NODE "/control/dpdk"
-/*format 0_mempool_gref = "1537,1524,1533" */
-#define MEMPOOL_XENSTORE_STR "_mempool_gref"
-/*format 0_mempool_va = 0x80340000 */
-#define MEMPOOL_VA_XENSTORE_STR "_mempool_va"
-/*format 0_rx_vring_gref = "1537,1524,1533" */
-#define RXVRING_XENSTORE_STR "_rx_vring_gref"
-/*format 0_tx_vring_gref = "1537,1524,1533" */
-#define TXVRING_XENSTORE_STR "_tx_vring_gref"
-#define VRING_FLAG_STR "_vring_flag"
-/*format: event_type_start_0 = 1*/
-#define EVENT_TYPE_START_STR "event_type_start_"
-
-#define DOM0_DOMID 0
-/*
- * the pfn (page frame number) are bits 0-54 (see pagemap.txt in linux
- * Documentation).
- */
-#define PAGEMAP_PFN_BITS 54
-#define PAGEMAP_PFN_MASK RTE_LEN2MASK(PAGEMAP_PFN_BITS, phys_addr_t)
-
-#define MAP_FLAG 0xA5
-
-#define RTE_ETH_XENVIRT_PAIRS_DELIM ';'
-#define RTE_ETH_XENVIRT_KEY_VALUE_DELIM '='
-#define RTE_ETH_XENVIRT_MAX_ARGS 1
-#define RTE_ETH_XENVIRT_MAC_PARAM "mac"
-struct xenvirt_dict {
- uint8_t addr_valid;
- struct ether_addr addr;
-};
-
-extern int gntalloc_fd;
-
-int
-gntalloc_open(void);
-
-void
-gntalloc_close(void);
-
-void *
-gntalloc(size_t sz, uint32_t *gref, uint64_t *start_index);
-
-void
-gntfree(void *va, size_t sz, uint64_t start_index);
-
-int
-xenstore_init(void);
-
-int
-xenstore_uninit(void);
-
-int
-xenstore_write(const char *key_str, const char *val_str);
-
-int
-get_phys_map(void *va, phys_addr_t pa[], uint32_t pg_num, uint32_t pg_sz);
-
-void *
-get_xen_virtual(size_t size, size_t page_sz);
-
-int
-grefwatch_from_alloc(uint32_t *gref, void **pptr);
-
-
-int grant_node_create(uint32_t pg_num, uint32_t *gref_arr, phys_addr_t *pa_arr, char *val_str, size_t str_size);
-
-int
-grant_gntalloc_mbuf_pool(struct rte_mempool *mpool, uint32_t pg_num, uint32_t *gref_arr, phys_addr_t *pa_arr, int mempool_idx);
-
-#endif
diff --git a/drivers/net/xenvirt/virtio_logs.h b/drivers/net/xenvirt/virtio_logs.h
deleted file mode 100644
index d6c33f7..0000000
--- a/drivers/net/xenvirt/virtio_logs.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*-
- * BSD LICENSE
- *
- * Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Intel Corporation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _VIRTIO_LOGS_H_
-#define _VIRTIO_LOGS_H_
-
-#include <rte_log.h>
-
-#ifdef RTE_LIBRTE_VIRTIO_DEBUG_INIT
-#define PMD_INIT_LOG(level, fmt, args...) \
- RTE_LOG(level, PMD, "%s(): " fmt "\n", __func__, ## args)
-#define PMD_INIT_FUNC_TRACE() PMD_INIT_LOG(DEBUG, " >>")
-#else
-#define PMD_INIT_LOG(level, fmt, args...) do { } while(0)
-#define PMD_INIT_FUNC_TRACE() do { } while(0)
-#endif
-
-#ifdef RTE_LIBRTE_VIRTIO_DEBUG_RX
-#define PMD_RX_LOG(level, fmt, args...) \
- RTE_LOG(level, PMD, "%s() rx: " fmt , __func__, ## args)
-#else
-#define PMD_RX_LOG(level, fmt, args...) do { } while(0)
-#endif
-
-#ifdef RTE_LIBRTE_VIRTIO_DEBUG_TX
-#define PMD_TX_LOG(level, fmt, args...) \
- RTE_LOG(level, PMD, "%s() tx: " fmt , __func__, ## args)
-#else
-#define PMD_TX_LOG(level, fmt, args...) do { } while(0)
-#endif
-
-
-#ifdef RTE_LIBRTE_VIRTIO_DEBUG_DRIVER
-#define PMD_DRV_LOG(level, fmt, args...) \
- RTE_LOG(level, PMD, "%s(): " fmt , __func__, ## args)
-#else
-#define PMD_DRV_LOG(level, fmt, args...) do { } while(0)
-#endif
-
-#endif /* _VIRTIO_LOGS_H_ */
diff --git a/drivers/net/xenvirt/virtqueue.h b/drivers/net/xenvirt/virtqueue.h
deleted file mode 100644
index 1bb6877..0000000
--- a/drivers/net/xenvirt/virtqueue.h
+++ /dev/null
@@ -1,273 +0,0 @@
-/*-
- * BSD LICENSE
- *
- * Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Intel Corporation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _VIRTQUEUE_H_
-#define _VIRTQUEUE_H_
-
-#include <stdint.h>
-#include <linux/virtio_ring.h>
-#include <linux/virtio_net.h>
-
-#include <rte_atomic.h>
-#include <rte_memory.h>
-#include <rte_memzone.h>
-#include <rte_mempool.h>
-
-#include "virtio_logs.h"
-
-struct rte_mbuf;
-
-/* The alignment to use between consumer and producer parts of vring. */
-#define VIRTIO_PCI_VRING_ALIGN 4096
-
-enum { VTNET_RQ = 0, VTNET_TQ = 1, VTNET_CQ = 2 };
-
-/**
- * The maximum virtqueue size is 2^15. Use that value as the end of
- * descriptor chain terminator since it will never be a valid index
- * in the descriptor table. This is used to verify we are correctly
- * handling vq_free_cnt.
- */
-#define VQ_RING_DESC_CHAIN_END 32768
-
-#define VIRTQUEUE_MAX_NAME_SZ 32
-
-struct pmd_internals {
- struct rte_eth_stats eth_stats;
- int port_id;
- int virtio_idx;
-};
-
-
-struct virtqueue {
- char vq_name[VIRTQUEUE_MAX_NAME_SZ];
- struct rte_mempool *mpool; /**< mempool for mbuf allocation */
- uint16_t queue_id; /**< DPDK queue index. */
- uint16_t vq_queue_index; /**< PCI queue index */
- uint8_t port_id; /**< Device port identifier. */
-
- void *vq_ring_virt_mem; /**< virtual address of vring*/
- int vq_alignment;
- int vq_ring_size;
-
- struct vring vq_ring; /**< vring keeping desc, used and avail */
- struct pmd_internals *internals; /**< virtio device internal info. */
- uint16_t vq_nentries; /**< vring desc numbers */
- uint16_t vq_desc_head_idx;
- uint16_t vq_free_cnt; /**< num of desc available */
- uint16_t vq_used_cons_idx; /**< Last consumed desc in used table, trails vq_ring.used->idx*/
-
- struct vq_desc_extra {
- void *cookie;
- uint16_t ndescs;
- } vq_descx[0] __rte_cache_aligned;
-};
-
-
-#ifdef RTE_LIBRTE_XENVIRT_DEBUG_DUMP
-#define VIRTQUEUE_DUMP(vq) do { \
- uint16_t used_idx, nused; \
- used_idx = (vq)->vq_ring.used->idx; \
- nused = (uint16_t)(used_idx - (vq)->vq_used_cons_idx); \
- PMD_INIT_LOG(DEBUG, \
- "VQ: %s - size=%d; free=%d; used=%d; desc_head_idx=%d;" \
- " avail.idx=%d; used_cons_idx=%d; used.idx=%d;" \
- " avail.flags=0x%x; used.flags=0x%x\n", \
- (vq)->vq_name, (vq)->vq_nentries, (vq)->vq_free_cnt, nused, \
- (vq)->vq_desc_head_idx, (vq)->vq_ring.avail->idx, \
- (vq)->vq_used_cons_idx, (vq)->vq_ring.used->idx, \
- (vq)->vq_ring.avail->flags, (vq)->vq_ring.used->flags); \
-} while (0)
-#else
-#define VIRTQUEUE_DUMP(vq) do { } while (0)
-#endif
-
-
-/**
- * Dump virtqueue internal structures, for debug purpose only.
- */
-void virtqueue_dump(struct virtqueue *vq);
-
-/**
- * Get all mbufs to be freed.
- */
-struct rte_mbuf * virtqueue_detatch_unused(struct virtqueue *vq);
-
-static __rte_always_inline int
-virtqueue_full(const struct virtqueue *vq)
-{
- return vq->vq_free_cnt == 0;
-}
-
-#define VIRTQUEUE_NUSED(vq) ((uint16_t)((vq)->vq_ring.used->idx - (vq)->vq_used_cons_idx))
-
-static __rte_always_inline void
-vq_ring_update_avail(struct virtqueue *vq, uint16_t desc_idx)
-{
- uint16_t avail_idx;
- /*
- * Place the head of the descriptor chain into the next slot and make
- * it usable to the host. The chain is made available now rather than
- * deferring to virtqueue_notify() in the hopes that if the host is
- * currently running on another CPU, we can keep it processing the new
- * descriptor.
- */
- avail_idx = (uint16_t)(vq->vq_ring.avail->idx & (vq->vq_nentries - 1));
- vq->vq_ring.avail->ring[avail_idx] = desc_idx;
- rte_smp_wmb();
- vq->vq_ring.avail->idx++;
-}
-
-static __rte_always_inline void
-vq_ring_free_chain(struct virtqueue *vq, uint16_t desc_idx)
-{
- struct vring_desc *dp;
- struct vq_desc_extra *dxp;
-
- dp = &vq->vq_ring.desc[desc_idx];
- dxp = &vq->vq_descx[desc_idx];
- vq->vq_free_cnt = (uint16_t)(vq->vq_free_cnt + dxp->ndescs);
- while (dp->flags & VRING_DESC_F_NEXT) {
- dp = &vq->vq_ring.desc[dp->next];
- }
- dxp->ndescs = 0;
-
- /*
- * We must append the existing free chain, if any, to the end of
- * newly freed chain. If the virtqueue was completely used, then
- * head would be VQ_RING_DESC_CHAIN_END (ASSERTed above).
- */
- dp->next = vq->vq_desc_head_idx;
- vq->vq_desc_head_idx = desc_idx;
-}
-
-static __rte_always_inline int
-virtqueue_enqueue_recv_refill(struct virtqueue *rxvq, struct rte_mbuf *cookie)
-{
- const uint16_t needed = 1;
- const uint16_t head_idx = rxvq->vq_desc_head_idx;
- struct vring_desc *start_dp = rxvq->vq_ring.desc;
- struct vq_desc_extra *dxp;
-
- if (unlikely(rxvq->vq_free_cnt == 0))
- return -ENOSPC;
- if (unlikely(rxvq->vq_free_cnt < needed))
- return -EMSGSIZE;
- if (unlikely(head_idx >= rxvq->vq_nentries))
- return -EFAULT;
-
- dxp = &rxvq->vq_descx[head_idx];
- dxp->cookie = (void *)cookie;
- dxp->ndescs = needed;
-
- start_dp[head_idx].addr =
- (uint64_t) ((uintptr_t)cookie->buf_addr + RTE_PKTMBUF_HEADROOM - sizeof(struct virtio_net_hdr));
- start_dp[head_idx].len = cookie->buf_len - RTE_PKTMBUF_HEADROOM + sizeof(struct virtio_net_hdr);
- start_dp[head_idx].flags = VRING_DESC_F_WRITE;
- rxvq->vq_desc_head_idx = start_dp[head_idx].next;
- rxvq->vq_free_cnt = (uint16_t)(rxvq->vq_free_cnt - needed);
- vq_ring_update_avail(rxvq, head_idx);
-
- return 0;
-}
-
-static __rte_always_inline int
-virtqueue_enqueue_xmit(struct virtqueue *txvq, struct rte_mbuf *cookie)
-{
-
- const uint16_t needed = 2;
- struct vring_desc *start_dp = txvq->vq_ring.desc;
- uint16_t head_idx = txvq->vq_desc_head_idx;
- uint16_t idx = head_idx;
- struct vq_desc_extra *dxp;
-
- if (unlikely(txvq->vq_free_cnt == 0))
- return -ENOSPC;
- if (unlikely(txvq->vq_free_cnt < needed))
- return -EMSGSIZE;
- if (unlikely(head_idx >= txvq->vq_nentries))
- return -EFAULT;
-
- dxp = &txvq->vq_descx[idx];
- dxp->cookie = (void *)cookie;
- dxp->ndescs = needed;
-
- start_dp = txvq->vq_ring.desc;
- start_dp[idx].addr = 0;
-/*
- * TODO: save one desc here?
- */
- start_dp[idx].len = sizeof(struct virtio_net_hdr);
- start_dp[idx].flags = VRING_DESC_F_NEXT;
- start_dp[idx].addr = (uintptr_t)NULL;
- idx = start_dp[idx].next;
- start_dp[idx].addr = (uint64_t)rte_pktmbuf_mtod(cookie, uintptr_t);
- start_dp[idx].len = cookie->data_len;
- start_dp[idx].flags = 0;
- idx = start_dp[idx].next;
- txvq->vq_desc_head_idx = idx;
- txvq->vq_free_cnt = (uint16_t)(txvq->vq_free_cnt - needed);
- vq_ring_update_avail(txvq, head_idx);
-
- return 0;
-}
-
-static __rte_always_inline uint16_t
-virtqueue_dequeue_burst(struct virtqueue *vq, struct rte_mbuf **rx_pkts, uint32_t *len, uint16_t num)
-{
- struct vring_used_elem *uep;
- struct rte_mbuf *cookie;
- uint16_t used_idx, desc_idx;
- uint16_t i;
- /* Caller does the check */
- for (i = 0; i < num ; i ++) {
- used_idx = (uint16_t)(vq->vq_used_cons_idx & (vq->vq_nentries - 1));
- uep = &vq->vq_ring.used->ring[used_idx];
- desc_idx = (uint16_t) uep->id;
- cookie = (struct rte_mbuf *)vq->vq_descx[desc_idx].cookie;
- if (unlikely(cookie == NULL)) {
- PMD_DRV_LOG(ERR, "vring descriptor with no mbuf cookie at %u\n",
- vq->vq_used_cons_idx);
- RTE_LOG(ERR, PMD, "%s: inconsistent (%u, %u)\n", __func__, used_idx , desc_idx);
- break;
- }
- len[i] = uep->len;
- rx_pkts[i] = cookie;
- vq->vq_used_cons_idx++;
- vq_ring_free_chain(vq, desc_idx);
- vq->vq_descx[desc_idx].cookie = NULL;
- }
- return i;
-}
-
-#endif /* _VIRTQUEUE_H_ */
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index c25fdd9..fb6be12 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -144,7 +144,6 @@ ifeq ($(CONFIG_RTE_LIBRTE_VHOST),y)
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_VHOST) += -lrte_pmd_vhost
endif # $(CONFIG_RTE_LIBRTE_VHOST)
_LDLIBS-$(CONFIG_RTE_LIBRTE_VMXNET3_PMD) += -lrte_pmd_vmxnet3_uio
-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_XENVIRT) += -lrte_pmd_xenvirt -lxenstore
ifeq ($(CONFIG_RTE_LIBRTE_CRYPTODEV),y)
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB) += -lrte_pmd_aesni_mb
diff --git a/pkg/dpdk.spec b/pkg/dpdk.spec
index 5ba3431..95c3335 100644
--- a/pkg/dpdk.spec
+++ b/pkg/dpdk.spec
@@ -90,9 +90,6 @@ sed -ri 's,(RTE_BUILD_SHARED_LIB=).*,\1y,' %{target}/.config
sed -ri 's,(RTE_NEXT_ABI=).*,\1n,' %{target}/.config
sed -ri 's,(LIBRTE_VHOST=).*,\1y,' %{target}/.config
sed -ri 's,(LIBRTE_PMD_PCAP=).*,\1y,' %{target}/.config
-%ifarch i686 x86_64
-sed -ri 's,(LIBRTE_PMD_XENVIRT=).*,\1y,' %{target}/.config
-%endif
make O=%{target} %{?_smp_mflags}
make O=%{target} doc
--
2.7.4
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [dpdk-dev] [PATCH 2/6] net/xenvirt: remove
2017-08-30 18:10 ` [dpdk-dev] [PATCH 2/6] net/xenvirt: remove Jianfeng Tan
@ 2017-09-04 14:25 ` Bruce Richardson
2017-09-04 14:50 ` Bruce Richardson
0 siblings, 1 reply; 21+ messages in thread
From: Bruce Richardson @ 2017-09-04 14:25 UTC (permalink / raw)
To: Jianfeng Tan
Cc: dev, xen-devel, thomas, john.mcnamara, oao.m.martins,
jerin.jacob, shahafs
On Wed, Aug 30, 2017 at 06:10:30PM +0000, Jianfeng Tan wrote:
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> ---
> MAINTAINERS | 2 -
> app/test-pmd/Makefile | 4 -
> app/test-pmd/testpmd.c | 12 -
> config/common_base | 5 -
> config/defconfig_arm-armv7a-linuxapp-gcc | 1 -
> doc/guides/nics/features/xenvirt.ini | 6 -
> drivers/net/Makefile | 2 -
> drivers/net/xenvirt/Makefile | 57 --
> drivers/net/xenvirt/rte_eth_xenvirt.c | 766 ------------------------
> drivers/net/xenvirt/rte_eth_xenvirt.h | 61 --
> drivers/net/xenvirt/rte_eth_xenvirt_version.map | 7 -
> drivers/net/xenvirt/rte_mempool_gntalloc.c | 295 ---------
> drivers/net/xenvirt/rte_xen_lib.c | 454 --------------
> drivers/net/xenvirt/rte_xen_lib.h | 116 ----
> drivers/net/xenvirt/virtio_logs.h | 70 ---
> drivers/net/xenvirt/virtqueue.h | 273 ---------
> mk/rte.app.mk | 1 -
> pkg/dpdk.spec | 3 -
> 18 files changed, 2135 deletions(-)
> delete mode 100644 doc/guides/nics/features/xenvirt.ini
> delete mode 100644 drivers/net/xenvirt/Makefile
> delete mode 100644 drivers/net/xenvirt/rte_eth_xenvirt.c
> delete mode 100644 drivers/net/xenvirt/rte_eth_xenvirt.h
> delete mode 100644 drivers/net/xenvirt/rte_eth_xenvirt_version.map
> delete mode 100644 drivers/net/xenvirt/rte_mempool_gntalloc.c
> delete mode 100644 drivers/net/xenvirt/rte_xen_lib.c
> delete mode 100644 drivers/net/xenvirt/rte_xen_lib.h
> delete mode 100644 drivers/net/xenvirt/virtio_logs.h
> delete mode 100644 drivers/net/xenvirt/virtqueue.h
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index fe6c6db..003e72e 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -194,9 +194,7 @@ M: Jianfeng Tan <jianfeng.tan@intel.com>
> F: lib/librte_eal/linuxapp/xen_dom0/
> F: lib/librte_eal/linuxapp/eal/*xen*
> F: lib/librte_eal/linuxapp/eal/include/exec-env/rte_dom0_common.h
> -F: drivers/net/xenvirt/
> F: doc/guides/xen/
> -F: doc/guides/nics/features/xenvirt.ini
>
> FreeBSD EAL (with overlaps)
> M: Bruce Richardson <bruce.richardson@intel.com>
> diff --git a/app/test-pmd/Makefile b/app/test-pmd/Makefile
> index c36be19..b6e80dd 100644
> --- a/app/test-pmd/Makefile
> +++ b/app/test-pmd/Makefile
> @@ -77,10 +77,6 @@ ifeq ($(CONFIG_RTE_LIBRTE_BNXT_PMD),y)
> LDLIBS += -lrte_pmd_bnxt
> endif
>
> -ifeq ($(CONFIG_RTE_LIBRTE_PMD_XENVIRT),y)
> -LDLIBS += -lrte_pmd_xenvirt
> -endif
> -
> endif
>
> CFLAGS_cmdline.o := -D_GNU_SOURCE
> diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
> index 7d40139..f8d02ae 100644
> --- a/app/test-pmd/testpmd.c
> +++ b/app/test-pmd/testpmd.c
> @@ -76,9 +76,6 @@
> #ifdef RTE_LIBRTE_IXGBE_PMD
> #include <rte_pmd_ixgbe.h>
> #endif
> -#ifdef RTE_LIBRTE_PMD_XENVIRT
> -#include <rte_eth_xenvirt.h>
> -#endif
> #ifdef RTE_LIBRTE_PDUMP
> #include <rte_pdump.h>
> #endif
> @@ -497,15 +494,6 @@ mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
> "create a new mbuf pool <%s>: n=%u, size=%u, socket=%u\n",
> pool_name, nb_mbuf, mbuf_seg_size, socket_id);
>
> -#ifdef RTE_LIBRTE_PMD_XENVIRT
> - rte_mp = rte_mempool_gntalloc_create(pool_name, nb_mbuf, mb_size,
> - (unsigned) mb_mempool_cache,
> - sizeof(struct rte_pktmbuf_pool_private),
> - rte_pktmbuf_pool_init, NULL,
> - rte_pktmbuf_init, NULL,
> - socket_id, 0);
> -#endif
> -
> /* if the former XEN allocation failed fall back to normal allocation */
> if (rte_mp == NULL) {
Remove comment and if condition, as there is no way the the variable can
be non-null now.
/Bruce
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [dpdk-dev] [PATCH 2/6] net/xenvirt: remove
2017-09-04 14:25 ` Bruce Richardson
@ 2017-09-04 14:50 ` Bruce Richardson
0 siblings, 0 replies; 21+ messages in thread
From: Bruce Richardson @ 2017-09-04 14:50 UTC (permalink / raw)
To: Jianfeng Tan
Cc: dev, xen-devel, thomas, john.mcnamara, oao.m.martins,
jerin.jacob, shahafs
On Mon, Sep 04, 2017 at 03:25:48PM +0100, Bruce Richardson wrote:
> On Wed, Aug 30, 2017 at 06:10:30PM +0000, Jianfeng Tan wrote:
> > Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> > ---
> > MAINTAINERS | 2 -
> > app/test-pmd/Makefile | 4 -
> > app/test-pmd/testpmd.c | 12 -
> > config/common_base | 5 -
> > config/defconfig_arm-armv7a-linuxapp-gcc | 1 -
> > doc/guides/nics/features/xenvirt.ini | 6 -
> > drivers/net/Makefile | 2 -
> > drivers/net/xenvirt/Makefile | 57 --
> > drivers/net/xenvirt/rte_eth_xenvirt.c | 766 ------------------------
> > drivers/net/xenvirt/rte_eth_xenvirt.h | 61 --
> > drivers/net/xenvirt/rte_eth_xenvirt_version.map | 7 -
> > drivers/net/xenvirt/rte_mempool_gntalloc.c | 295 ---------
> > drivers/net/xenvirt/rte_xen_lib.c | 454 --------------
> > drivers/net/xenvirt/rte_xen_lib.h | 116 ----
> > drivers/net/xenvirt/virtio_logs.h | 70 ---
> > drivers/net/xenvirt/virtqueue.h | 273 ---------
> > mk/rte.app.mk | 1 -
> > pkg/dpdk.spec | 3 -
> > 18 files changed, 2135 deletions(-)
> > delete mode 100644 doc/guides/nics/features/xenvirt.ini
> > delete mode 100644 drivers/net/xenvirt/Makefile
> > delete mode 100644 drivers/net/xenvirt/rte_eth_xenvirt.c
> > delete mode 100644 drivers/net/xenvirt/rte_eth_xenvirt.h
> > delete mode 100644 drivers/net/xenvirt/rte_eth_xenvirt_version.map
> > delete mode 100644 drivers/net/xenvirt/rte_mempool_gntalloc.c
> > delete mode 100644 drivers/net/xenvirt/rte_xen_lib.c
> > delete mode 100644 drivers/net/xenvirt/rte_xen_lib.h
> > delete mode 100644 drivers/net/xenvirt/virtio_logs.h
> > delete mode 100644 drivers/net/xenvirt/virtqueue.h
> >
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index fe6c6db..003e72e 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -194,9 +194,7 @@ M: Jianfeng Tan <jianfeng.tan@intel.com>
> > F: lib/librte_eal/linuxapp/xen_dom0/
> > F: lib/librte_eal/linuxapp/eal/*xen*
> > F: lib/librte_eal/linuxapp/eal/include/exec-env/rte_dom0_common.h
> > -F: drivers/net/xenvirt/
> > F: doc/guides/xen/
> > -F: doc/guides/nics/features/xenvirt.ini
> >
> > FreeBSD EAL (with overlaps)
> > M: Bruce Richardson <bruce.richardson@intel.com>
> > diff --git a/app/test-pmd/Makefile b/app/test-pmd/Makefile
> > index c36be19..b6e80dd 100644
> > --- a/app/test-pmd/Makefile
> > +++ b/app/test-pmd/Makefile
> > @@ -77,10 +77,6 @@ ifeq ($(CONFIG_RTE_LIBRTE_BNXT_PMD),y)
> > LDLIBS += -lrte_pmd_bnxt
> > endif
> >
> > -ifeq ($(CONFIG_RTE_LIBRTE_PMD_XENVIRT),y)
> > -LDLIBS += -lrte_pmd_xenvirt
> > -endif
> > -
> > endif
> >
> > CFLAGS_cmdline.o := -D_GNU_SOURCE
> > diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
> > index 7d40139..f8d02ae 100644
> > --- a/app/test-pmd/testpmd.c
> > +++ b/app/test-pmd/testpmd.c
> > @@ -76,9 +76,6 @@
> > #ifdef RTE_LIBRTE_IXGBE_PMD
> > #include <rte_pmd_ixgbe.h>
> > #endif
> > -#ifdef RTE_LIBRTE_PMD_XENVIRT
> > -#include <rte_eth_xenvirt.h>
> > -#endif
> > #ifdef RTE_LIBRTE_PDUMP
> > #include <rte_pdump.h>
> > #endif
> > @@ -497,15 +494,6 @@ mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
> > "create a new mbuf pool <%s>: n=%u, size=%u, socket=%u\n",
> > pool_name, nb_mbuf, mbuf_seg_size, socket_id);
> >
> > -#ifdef RTE_LIBRTE_PMD_XENVIRT
> > - rte_mp = rte_mempool_gntalloc_create(pool_name, nb_mbuf, mb_size,
> > - (unsigned) mb_mempool_cache,
> > - sizeof(struct rte_pktmbuf_pool_private),
> > - rte_pktmbuf_pool_init, NULL,
> > - rte_pktmbuf_init, NULL,
> > - socket_id, 0);
> > -#endif
> > -
> > /* if the former XEN allocation failed fall back to normal allocation */
> > if (rte_mp == NULL) {
>
> Remove comment and if condition, as there is no way the the variable can
> be non-null now.
>
With this change:
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
^ permalink raw reply [flat|nested] 21+ messages in thread
* [dpdk-dev] [PATCH 3/6] xen: remove xen dependency in app, examples, test
2017-08-30 18:10 [dpdk-dev] [PATCH 0/6] remove xen dom0 support in DPDK Jianfeng Tan
2017-08-30 18:10 ` [dpdk-dev] [PATCH 1/6] example/vhost_xen: remove Jianfeng Tan
2017-08-30 18:10 ` [dpdk-dev] [PATCH 2/6] net/xenvirt: remove Jianfeng Tan
@ 2017-08-30 18:10 ` Jianfeng Tan
2017-09-04 14:24 ` Bruce Richardson
2017-09-04 14:51 ` Bruce Richardson
2017-08-30 18:10 ` [dpdk-dev] [PATCH 4/6] xen: remove xen dependency in drivers, ether, mempool Jianfeng Tan
` (3 subsequent siblings)
6 siblings, 2 replies; 21+ messages in thread
From: Jianfeng Tan @ 2017-08-30 18:10 UTC (permalink / raw)
To: dev
Cc: xen-devel, thomas, john.mcnamara, oao.m.martins, jerin.jacob,
shahafs, Jianfeng Tan
Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
app/test-pmd/testpmd.c | 2 +-
examples/ip_pipeline/app.h | 4 --
examples/ip_pipeline/config_parse.c | 19 ---------
examples/ip_pipeline/init.c | 5 ---
examples/kni/main.c | 3 --
test/test/process.h | 10 -----
test/test/test.c | 4 --
test/test/test_eal_flags.c | 81 -------------------------------------
8 files changed, 1 insertion(+), 127 deletions(-)
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index f8d02ae..d9c785c 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -494,7 +494,7 @@ mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
"create a new mbuf pool <%s>: n=%u, size=%u, socket=%u\n",
pool_name, nb_mbuf, mbuf_seg_size, socket_id);
- /* if the former XEN allocation failed fall back to normal allocation */
+ /* if the former allocation failed fall back to normal allocation */
if (rte_mp == NULL) {
if (mp_anon != 0) {
rte_mp = rte_mempool_create_empty(pool_name, nb_mbuf,
diff --git a/examples/ip_pipeline/app.h b/examples/ip_pipeline/app.h
index e41290e..94e7a6d 100644
--- a/examples/ip_pipeline/app.h
+++ b/examples/ip_pipeline/app.h
@@ -428,10 +428,6 @@ struct app_eal_params {
/* Interrupt mode for VFIO (legacy|msi|msix) */
char *vfio_intr;
- /* Support running on Xen dom0 without hugetlbfs */
- uint32_t xen_dom0_present;
- int xen_dom0;
-
uint32_t parsed;
};
diff --git a/examples/ip_pipeline/config_parse.c b/examples/ip_pipeline/config_parse.c
index 0b76134..3211c6a 100644
--- a/examples/ip_pipeline/config_parse.c
+++ b/examples/ip_pipeline/config_parse.c
@@ -809,21 +809,6 @@ parse_eal(struct app_params *app,
continue;
}
- /* xen_dom0 */
- if (strcmp(entry->name, "xen_dom0") == 0) {
- int val;
-
- PARSE_ERROR_DUPLICATE((p->xen_dom0_present == 0),
- section_name,
- entry->name);
- p->xen_dom0_present = 1;
-
- val = parser_read_arg_bool(entry->value);
- PARSE_ERROR((val >= 0), section_name, entry->name);
- p->xen_dom0 = val;
- continue;
- }
-
/* unrecognized */
PARSE_ERROR_INVALID(0, section_name, entry->name);
}
@@ -2643,10 +2628,6 @@ save_eal_params(struct app_params *app, FILE *f)
if (p->vfio_intr)
fprintf(f, "%s = %s\n", "vfio_intr", p->vfio_intr);
- if (p->xen_dom0_present)
- fprintf(f, "%s = %s\n", "xen_dom0",
- (p->xen_dom0) ? "yes" : "no");
-
fputc('\n', f);
}
diff --git a/examples/ip_pipeline/init.c b/examples/ip_pipeline/init.c
index 7cde49a..034c238 100644
--- a/examples/ip_pipeline/init.c
+++ b/examples/ip_pipeline/init.c
@@ -296,11 +296,6 @@ app_init_eal(struct app_params *app)
app->eal_argv[n_args++] = strdup(buffer);
}
- if ((p->xen_dom0_present) && (p->xen_dom0)) {
- snprintf(buffer, sizeof(buffer), "--xen-dom0");
- app->eal_argv[n_args++] = strdup(buffer);
- }
-
snprintf(buffer, sizeof(buffer), "--");
app->eal_argv[n_args++] = strdup(buffer);
diff --git a/examples/kni/main.c b/examples/kni/main.c
index e3bc2fb..9f9d227 100644
--- a/examples/kni/main.c
+++ b/examples/kni/main.c
@@ -919,9 +919,6 @@ main(int argc, char** argv)
continue;
kni_free_kni(port);
}
-#ifdef RTE_LIBRTE_XEN_DOM0
- rte_kni_close();
-#endif
for (i = 0; i < RTE_MAX_ETHPORTS; i++)
if (kni_port_params_array[i]) {
rte_free(kni_port_params_array[i]);
diff --git a/test/test/process.h b/test/test/process.h
index 4f8d121..51ced12 100644
--- a/test/test/process.h
+++ b/test/test/process.h
@@ -52,11 +52,7 @@ static inline int
process_dup(const char *const argv[], int numargs, const char *env_value)
{
int num;
-#ifdef RTE_LIBRTE_XEN_DOM0
- char *argv_cpy[numargs + 2];
-#else
char *argv_cpy[numargs + 1];
-#endif
int i, fd, status;
char path[32];
@@ -67,14 +63,8 @@ process_dup(const char *const argv[], int numargs, const char *env_value)
/* make a copy of the arguments to be passed to exec */
for (i = 0; i < numargs; i++)
argv_cpy[i] = strdup(argv[i]);
-#ifdef RTE_LIBRTE_XEN_DOM0
- argv_cpy[i] = strdup("--xen-dom0");
- argv_cpy[i + 1] = NULL;
- num = numargs + 1;
-#else
argv_cpy[i] = NULL;
num = numargs;
-#endif
/* close all open file descriptors, check /proc/self/fd to only
* call close on open fds. Exclude fds 0, 1 and 2*/
diff --git a/test/test/test.c b/test/test/test.c
index c561eb5..9accbd1 100644
--- a/test/test/test.c
+++ b/test/test/test.c
@@ -87,11 +87,7 @@ do_recursive_call(void)
{ "test_invalid_b_flag", no_action },
{ "test_invalid_vdev_flag", no_action },
{ "test_invalid_r_flag", no_action },
-#ifdef RTE_LIBRTE_XEN_DOM0
- { "test_dom0_misc_flags", no_action },
-#else
{ "test_misc_flags", no_action },
-#endif
{ "test_memory_flags", no_action },
{ "test_file_prefix", no_action },
{ "test_no_huge_flag", no_action },
diff --git a/test/test/test_eal_flags.c b/test/test/test_eal_flags.c
index 594d79d..310109e 100644
--- a/test/test/test_eal_flags.c
+++ b/test/test/test_eal_flags.c
@@ -51,11 +51,7 @@
#include "process.h"
-#ifdef RTE_LIBRTE_XEN_DOM0
-#define DEFAULT_MEM_SIZE "30"
-#else
#define DEFAULT_MEM_SIZE "18"
-#endif
#define mp_flag "--proc-type=secondary"
#define no_hpet "--no-hpet"
#define no_huge "--no-huge"
@@ -809,72 +805,6 @@ test_no_huge_flag(void)
return 0;
}
-#ifdef RTE_LIBRTE_XEN_DOM0
-static int
-test_dom0_misc_flags(void)
-{
- char prefix[PATH_MAX], tmp[PATH_MAX];
-
- if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
- printf("Error - unable to get current prefix!\n");
- return -1;
- }
- snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
-
- /* check that some general flags don't prevent things from working.
- * All cases, apart from the first, app should run.
- * No further testing of output done.
- */
- /* sanity check - failure with invalid option */
- const char *argv0[] = {prgname, prefix, mp_flag, "-c", "1", "--invalid-opt"};
-
- /* With --no-pci */
- const char *argv1[] = {prgname, prefix, mp_flag, "-c", "1", "--no-pci"};
- /* With -v */
- const char *argv2[] = {prgname, prefix, mp_flag, "-c", "1", "-v"};
- /* With valid --syslog */
- const char *argv3[] = {prgname, prefix, mp_flag, "-c", "1",
- "--syslog", "syslog"};
- /* With empty --syslog (should fail) */
- const char *argv4[] = {prgname, prefix, mp_flag, "-c", "1", "--syslog"};
- /* With invalid --syslog */
- const char *argv5[] = {prgname, prefix, mp_flag, "-c", "1", "--syslog", "error"};
- /* With no-sh-conf */
- const char *argv6[] = {prgname, "-c", "1", "-n", "2", "-m", "20",
- "--no-shconf", "--file-prefix=noshconf" };
-
- if (launch_proc(argv0) == 0) {
- printf("Error - process ran ok with invalid flag\n");
- return -1;
- }
- if (launch_proc(argv1) != 0) {
- printf("Error - process did not run ok with --no-pci flag\n");
- return -1;
- }
- if (launch_proc(argv2) != 0) {
- printf("Error - process did not run ok with -v flag\n");
- return -1;
- }
- if (launch_proc(argv3) != 0) {
- printf("Error - process did not run ok with --syslog flag\n");
- return -1;
- }
- if (launch_proc(argv4) == 0) {
- printf("Error - process run ok with empty --syslog flag\n");
- return -1;
- }
- if (launch_proc(argv5) == 0) {
- printf("Error - process run ok with invalid --syslog flag\n");
- return -1;
- }
- if (launch_proc(argv6) != 0) {
- printf("Error - process did not run ok with --no-shconf flag\n");
- return -1;
- }
-
- return 0;
-}
-#else
static int
test_misc_flags(void)
{
@@ -1061,7 +991,6 @@ test_misc_flags(void)
}
return 0;
}
-#endif
static int
test_file_prefix(void)
@@ -1098,9 +1027,6 @@ test_file_prefix(void)
printf("Error - unable to get current prefix!\n");
return -1;
}
-#ifdef RTE_LIBRTE_XEN_DOM0
- return 0;
-#endif
/* check if files for current prefix are present */
if (process_hugefiles(prefix, HUGEPAGE_CHECK_EXISTS) != 1) {
@@ -1299,9 +1225,6 @@ test_memory_flags(void)
printf("Error - process failed with valid -m flag!\n");
return -1;
}
-#ifdef RTE_LIBRTE_XEN_DOM0
- return 0;
-#endif
if (launch_proc(argv2) == 0) {
printf("Error - process run ok with invalid (zero) --socket-mem!\n");
return -1;
@@ -1427,11 +1350,7 @@ test_eal_flags(void)
return ret;
}
-#ifdef RTE_LIBRTE_XEN_DOM0
- ret = test_dom0_misc_flags();
-#else
ret = test_misc_flags();
-#endif
if (ret < 0) {
printf("Error in test_misc_flags()");
return ret;
--
2.7.4
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [dpdk-dev] [PATCH 3/6] xen: remove xen dependency in app, examples, test
2017-08-30 18:10 ` [dpdk-dev] [PATCH 3/6] xen: remove xen dependency in app, examples, test Jianfeng Tan
@ 2017-09-04 14:24 ` Bruce Richardson
2017-09-04 14:51 ` Bruce Richardson
1 sibling, 0 replies; 21+ messages in thread
From: Bruce Richardson @ 2017-09-04 14:24 UTC (permalink / raw)
To: Jianfeng Tan
Cc: dev, xen-devel, thomas, john.mcnamara, oao.m.martins,
jerin.jacob, shahafs
On Wed, Aug 30, 2017 at 06:10:31PM +0000, Jianfeng Tan wrote:
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> ---
> app/test-pmd/testpmd.c | 2 +-
> examples/ip_pipeline/app.h | 4 --
> examples/ip_pipeline/config_parse.c | 19 ---------
> examples/ip_pipeline/init.c | 5 ---
> examples/kni/main.c | 3 --
> test/test/process.h | 10 -----
> test/test/test.c | 4 --
> test/test/test_eal_flags.c | 81 -------------------------------------
> 8 files changed, 1 insertion(+), 127 deletions(-)
>
> diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
> index f8d02ae..d9c785c 100644
> --- a/app/test-pmd/testpmd.c
> +++ b/app/test-pmd/testpmd.c
> @@ -494,7 +494,7 @@ mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
> "create a new mbuf pool <%s>: n=%u, size=%u, socket=%u\n",
> pool_name, nb_mbuf, mbuf_seg_size, socket_id);
>
> - /* if the former XEN allocation failed fall back to normal allocation */
> + /* if the former allocation failed fall back to normal allocation */
> if (rte_mp == NULL) {
> if (mp_anon != 0) {
> rte_mp = rte_mempool_create_empty(pool_name, nb_mbuf,
There is no former allocation here, so I think the previous patch, which
removed the #ifdef block should also remove this comment entirely, and
the "if (rte_mp == NULL)" too
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [dpdk-dev] [PATCH 3/6] xen: remove xen dependency in app, examples, test
2017-08-30 18:10 ` [dpdk-dev] [PATCH 3/6] xen: remove xen dependency in app, examples, test Jianfeng Tan
2017-09-04 14:24 ` Bruce Richardson
@ 2017-09-04 14:51 ` Bruce Richardson
1 sibling, 0 replies; 21+ messages in thread
From: Bruce Richardson @ 2017-09-04 14:51 UTC (permalink / raw)
To: Jianfeng Tan
Cc: dev, xen-devel, thomas, john.mcnamara, joao.m.martins,
jerin.jacob, shahafs
On Wed, Aug 30, 2017 at 06:10:31PM +0000, Jianfeng Tan wrote:
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> ---
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
^ permalink raw reply [flat|nested] 21+ messages in thread
* [dpdk-dev] [PATCH 4/6] xen: remove xen dependency in drivers, ether, mempool
2017-08-30 18:10 [dpdk-dev] [PATCH 0/6] remove xen dom0 support in DPDK Jianfeng Tan
` (2 preceding siblings ...)
2017-08-30 18:10 ` [dpdk-dev] [PATCH 3/6] xen: remove xen dependency in app, examples, test Jianfeng Tan
@ 2017-08-30 18:10 ` Jianfeng Tan
2017-09-04 14:51 ` Bruce Richardson
2017-08-30 18:10 ` [dpdk-dev] [PATCH 5/6] eal: remove xen dom0 support Jianfeng Tan
` (2 subsequent siblings)
6 siblings, 1 reply; 21+ messages in thread
From: Jianfeng Tan @ 2017-08-30 18:10 UTC (permalink / raw)
To: dev
Cc: xen-devel, thomas, john.mcnamara, oao.m.martins, jerin.jacob,
shahafs, Jianfeng Tan
Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
drivers/crypto/qat/qat_qp.c | 7 +------
drivers/net/i40e/i40e_rxtx.c | 8 ++------
lib/librte_ether/rte_ethdev.c | 7 +------
lib/librte_mempool/rte_mempool.c | 8 ++------
4 files changed, 6 insertions(+), 24 deletions(-)
diff --git a/drivers/crypto/qat/qat_qp.c b/drivers/crypto/qat/qat_qp.c
index 5048d21..34f75ca 100644
--- a/drivers/crypto/qat/qat_qp.c
+++ b/drivers/crypto/qat/qat_qp.c
@@ -122,14 +122,9 @@ queue_dma_zone_reserve(const char *queue_name, uint32_t queue_size,
break;
default:
memzone_flags = RTE_MEMZONE_SIZE_HINT_ONLY;
-}
-#ifdef RTE_LIBRTE_XEN_DOM0
- return rte_memzone_reserve_bounded(queue_name, queue_size,
- socket_id, 0, RTE_CACHE_LINE_SIZE, RTE_PGSIZE_2M);
-#else
+ }
return rte_memzone_reserve_aligned(queue_name, queue_size, socket_id,
memzone_flags, queue_size);
-#endif
}
int qat_crypto_sym_qp_setup(struct rte_cryptodev *dev, uint16_t queue_pair_id,
diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c
index d42c23c..f571e79 100644
--- a/drivers/net/i40e/i40e_rxtx.c
+++ b/drivers/net/i40e/i40e_rxtx.c
@@ -2221,12 +2221,8 @@ i40e_memzone_reserve(const char *name, uint32_t len, int socket_id)
if (mz)
return mz;
- if (rte_xen_dom0_supported())
- mz = rte_memzone_reserve_bounded(name, len,
- socket_id, 0, I40E_RING_BASE_ALIGN, RTE_PGSIZE_2M);
- else
- mz = rte_memzone_reserve_aligned(name, len,
- socket_id, 0, I40E_RING_BASE_ALIGN);
+ mz = rte_memzone_reserve_aligned(name, len,
+ socket_id, 0, I40E_RING_BASE_ALIGN);
return mz;
}
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 0597641..cb0bde7 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -2818,12 +2818,7 @@ rte_eth_dma_zone_reserve(const struct rte_eth_dev *dev, const char *ring_name,
if (mz)
return mz;
- if (rte_xen_dom0_supported())
- return rte_memzone_reserve_bounded(z_name, size, socket_id,
- 0, align, RTE_PGSIZE_2M);
- else
- return rte_memzone_reserve_aligned(z_name, size, socket_id,
- 0, align);
+ return rte_memzone_reserve_aligned(z_name, size, socket_id, 0, align);
}
int
diff --git a/lib/librte_mempool/rte_mempool.c b/lib/librte_mempool/rte_mempool.c
index 6fc3c9c..6d726ae 100644
--- a/lib/librte_mempool/rte_mempool.c
+++ b/lib/librte_mempool/rte_mempool.c
@@ -527,11 +527,7 @@ rte_mempool_populate_default(struct rte_mempool *mp)
if (mp->nb_mem_chunks != 0)
return -EEXIST;
- if (rte_xen_dom0_supported()) {
- pg_sz = RTE_PGSIZE_2M;
- pg_shift = rte_bsf32(pg_sz);
- align = pg_sz;
- } else if (rte_eal_has_hugepages()) {
+ if (rte_eal_has_hugepages()) {
pg_shift = 0; /* not needed, zone is physically contiguous */
pg_sz = 0;
align = RTE_CACHE_LINE_SIZE;
@@ -568,7 +564,7 @@ rte_mempool_populate_default(struct rte_mempool *mp)
else
paddr = mz->phys_addr;
- if (rte_eal_has_hugepages() && !rte_xen_dom0_supported())
+ if (rte_eal_has_hugepages())
ret = rte_mempool_populate_phys(mp, mz->addr,
paddr, mz->len,
rte_mempool_memchunk_mz_free,
--
2.7.4
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [dpdk-dev] [PATCH 4/6] xen: remove xen dependency in drivers, ether, mempool
2017-08-30 18:10 ` [dpdk-dev] [PATCH 4/6] xen: remove xen dependency in drivers, ether, mempool Jianfeng Tan
@ 2017-09-04 14:51 ` Bruce Richardson
0 siblings, 0 replies; 21+ messages in thread
From: Bruce Richardson @ 2017-09-04 14:51 UTC (permalink / raw)
To: Jianfeng Tan
Cc: dev, xen-devel, thomas, john.mcnamara, oao.m.martins,
jerin.jacob, shahafs
On Wed, Aug 30, 2017 at 06:10:32PM +0000, Jianfeng Tan wrote:
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> ---
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
^ permalink raw reply [flat|nested] 21+ messages in thread
* [dpdk-dev] [PATCH 5/6] eal: remove xen dom0 support
2017-08-30 18:10 [dpdk-dev] [PATCH 0/6] remove xen dom0 support in DPDK Jianfeng Tan
` (3 preceding siblings ...)
2017-08-30 18:10 ` [dpdk-dev] [PATCH 4/6] xen: remove xen dependency in drivers, ether, mempool Jianfeng Tan
@ 2017-08-30 18:10 ` Jianfeng Tan
2017-09-04 14:43 ` Bruce Richardson
2017-08-30 18:10 ` [dpdk-dev] [PATCH 6/6] eal: remove API rte_mem_phy2mch Jianfeng Tan
2017-08-31 8:44 ` [dpdk-dev] [Xen-devel] [PATCH 0/6] remove xen dom0 support in DPDK Wei Liu
6 siblings, 1 reply; 21+ messages in thread
From: Jianfeng Tan @ 2017-08-30 18:10 UTC (permalink / raw)
To: dev
Cc: xen-devel, thomas, john.mcnamara, oao.m.martins, jerin.jacob,
shahafs, Jianfeng Tan
We remove xen-specific code in EAL, including the option --xen-dom0,
memory initialization code, compiling dependency, etc.
Besides, related documents are removed or updated.
Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
MAINTAINERS | 7 -
config/common_base | 5 -
doc/guides/index.rst | 1 -
doc/guides/linux_gsg/build_sample_apps.rst | 5 +-
doc/guides/linux_gsg/sys_reqs.rst | 53 --
doc/guides/prog_guide/source_org.rst | 1 -
doc/guides/rel_notes/deprecation.rst | 3 -
doc/guides/rel_notes/release_17_11.rst | 12 +
doc/guides/testpmd_app_ug/run_app.rst | 4 -
doc/guides/xen/img/dpdk_xen_pkt_switch.png | Bin 163842 -> 0 bytes
doc/guides/xen/img/grant_refs.png | Bin 6405 -> 0 bytes
doc/guides/xen/img/grant_table.png | Bin 96762 -> 0 bytes
doc/guides/xen/index.rst | 38 -
doc/guides/xen/pkt_switch.rst | 470 -------------
.../bsdapp/eal/include/exec-env/rte_dom0_common.h | 107 ---
lib/librte_eal/common/eal_common_options.c | 3 -
lib/librte_eal/common/eal_internal_cfg.h | 1 -
lib/librte_eal/common/eal_options.h | 2 -
lib/librte_eal/common/include/rte_memory.h | 66 --
lib/librte_eal/linuxapp/Makefile | 2 -
lib/librte_eal/linuxapp/eal/Makefile | 5 +-
lib/librte_eal/linuxapp/eal/eal.c | 24 -
lib/librte_eal/linuxapp/eal/eal_memory.c | 56 --
lib/librte_eal/linuxapp/eal/eal_xen_memory.c | 381 ----------
.../eal/include/exec-env/rte_dom0_common.h | 108 ---
lib/librte_eal/linuxapp/igb_uio/igb_uio.c | 54 --
lib/librte_eal/linuxapp/xen_dom0/Makefile | 53 --
lib/librte_eal/linuxapp/xen_dom0/compat.h | 15 -
lib/librte_eal/linuxapp/xen_dom0/dom0_mm_dev.h | 107 ---
lib/librte_eal/linuxapp/xen_dom0/dom0_mm_misc.c | 780 ---------------------
pkg/dpdk.spec | 3 -
31 files changed, 14 insertions(+), 2352 deletions(-)
delete mode 100644 doc/guides/xen/img/dpdk_xen_pkt_switch.png
delete mode 100644 doc/guides/xen/img/grant_refs.png
delete mode 100644 doc/guides/xen/img/grant_table.png
delete mode 100644 doc/guides/xen/index.rst
delete mode 100644 doc/guides/xen/pkt_switch.rst
delete mode 100644 lib/librte_eal/bsdapp/eal/include/exec-env/rte_dom0_common.h
delete mode 100644 lib/librte_eal/linuxapp/eal/eal_xen_memory.c
delete mode 100644 lib/librte_eal/linuxapp/eal/include/exec-env/rte_dom0_common.h
delete mode 100644 lib/librte_eal/linuxapp/xen_dom0/Makefile
delete mode 100644 lib/librte_eal/linuxapp/xen_dom0/compat.h
delete mode 100644 lib/librte_eal/linuxapp/xen_dom0/dom0_mm_dev.h
delete mode 100644 lib/librte_eal/linuxapp/xen_dom0/dom0_mm_misc.c
diff --git a/MAINTAINERS b/MAINTAINERS
index 003e72e..2af32ff 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -189,13 +189,6 @@ Linux VFIO
M: Anatoly Burakov <anatoly.burakov@intel.com>
F: lib/librte_eal/linuxapp/eal/*vfio*
-Linux Xen
-M: Jianfeng Tan <jianfeng.tan@intel.com>
-F: lib/librte_eal/linuxapp/xen_dom0/
-F: lib/librte_eal/linuxapp/eal/*xen*
-F: lib/librte_eal/linuxapp/eal/include/exec-env/rte_dom0_common.h
-F: doc/guides/xen/
-
FreeBSD EAL (with overlaps)
M: Bruce Richardson <bruce.richardson@intel.com>
M: Sergio Gonzalez Monroy <sergio.gonzalez.monroy@intel.com>
diff --git a/config/common_base b/config/common_base
index 93928b6..17d3dae 100644
--- a/config/common_base
+++ b/config/common_base
@@ -719,11 +719,6 @@ CONFIG_RTE_LIBRTE_VHOST_DEBUG=n
CONFIG_RTE_LIBRTE_PMD_VHOST=n
#
-#Compile Xen domain0 support
-#
-CONFIG_RTE_LIBRTE_XEN_DOM0=n
-
-#
# Compile the test application
#
CONFIG_RTE_APP_TEST=y
diff --git a/doc/guides/index.rst b/doc/guides/index.rst
index 63716b0..5b6eb7e 100644
--- a/doc/guides/index.rst
+++ b/doc/guides/index.rst
@@ -44,7 +44,6 @@ DPDK documentation
nics/index
cryptodevs/index
eventdevs/index
- xen/index
contributing/index
rel_notes/index
faq/index
diff --git a/doc/guides/linux_gsg/build_sample_apps.rst b/doc/guides/linux_gsg/build_sample_apps.rst
index 0cc5fd1..582984d 100644
--- a/doc/guides/linux_gsg/build_sample_apps.rst
+++ b/doc/guides/linux_gsg/build_sample_apps.rst
@@ -116,7 +116,7 @@ The following is the list of options that can be given to the EAL:
./rte-app [-c COREMASK | -l CORELIST] [-n NUM] [-b <domain:bus:devid.func>] \
[--socket-mem=MB,...] [-d LIB.so|DIR] [-m MB] [-r NUM] [-v] [--file-prefix] \
- [--proc-type <primary|secondary|auto>] [-- xen-dom0]
+ [--proc-type <primary|secondary|auto>]
The EAL options are as follows:
@@ -163,9 +163,6 @@ The EAL options are as follows:
* ``--proc-type``:
The type of process instance.
-* ``--xen-dom0``:
- Support application running on Xen Domain0 without hugetlbfs.
-
* ``--vmware-tsc-map``:
Use VMware TSC map instead of native RDTSC.
diff --git a/doc/guides/linux_gsg/sys_reqs.rst b/doc/guides/linux_gsg/sys_reqs.rst
index eb8442c..3e7fe63 100644
--- a/doc/guides/linux_gsg/sys_reqs.rst
+++ b/doc/guides/linux_gsg/sys_reqs.rst
@@ -228,56 +228,3 @@ The mount point can be made permanent across reboots, by adding the following li
For 1GB pages, the page size must be specified as a mount option::
nodev /mnt/huge_1GB hugetlbfs pagesize=1GB 0 0
-
-Xen Domain0 Support in the Linux Environment
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The existing memory management implementation is based on the Linux kernel hugepage mechanism.
-On the Xen hypervisor, hugepage support for DomainU (DomU) Guests means that DPDK applications work as normal for guests.
-
-However, Domain0 (Dom0) does not support hugepages.
-To work around this limitation, a new kernel module rte_dom0_mm is added to facilitate the allocation and mapping of memory via
-**IOCTL** (allocation) and **MMAP** (mapping).
-
-Enabling Xen Dom0 Mode in the DPDK
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-By default, Xen Dom0 mode is disabled in the DPDK build configuration files.
-To support Xen Dom0, the CONFIG_RTE_LIBRTE_XEN_DOM0 setting should be changed to “y”, which enables the Xen Dom0 mode at compile time.
-
-Furthermore, the CONFIG_RTE_EAL_ALLOW_INV_SOCKET_ID setting should also be changed to “y” in the case of the wrong socket ID being received.
-
-Loading the DPDK rte_dom0_mm Module
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-To run any DPDK application on Xen Dom0, the ``rte_dom0_mm`` module must be loaded into the running kernel with rsv_memsize option.
-The module is found in the kmod sub-directory of the DPDK target directory.
-This module should be loaded using the insmod command as shown below (assuming that the current directory is the DPDK target directory)::
-
- sudo insmod kmod/rte_dom0_mm.ko rsv_memsize=X
-
-The value X cannot be greater than 4096(MB).
-
-Configuring Memory for DPDK Use
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-After the rte_dom0_mm.ko kernel module has been loaded, the user must configure the memory size for DPDK usage.
-This is done by echoing the memory size to a memsize file in the /sys/devices/ directory.
-Use the following command (assuming that 2048 MB is required)::
-
- echo 2048 > /sys/kernel/mm/dom0-mm/memsize-mB/memsize
-
-The user can also check how much memory has already been used::
-
- cat /sys/kernel/mm/dom0-mm/memsize-mB/memsize_rsvd
-
-Xen Domain0 does not support NUMA configuration, as a result the ``--socket-mem`` command line option is invalid for Xen Domain0.
-
-.. note::
-
- The memsize value cannot be greater than the rsv_memsize value.
-
-Running the DPDK Application on Xen Domain0
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-To run the DPDK application on Xen Domain0, an extra command line option ``--xen-dom0`` is required.
diff --git a/doc/guides/prog_guide/source_org.rst b/doc/guides/prog_guide/source_org.rst
index d5d01f3..7aab4b4 100644
--- a/doc/guides/prog_guide/source_org.rst
+++ b/doc/guides/prog_guide/source_org.rst
@@ -108,7 +108,6 @@ The drivers directory has a *net* subdirectory which contains::
+-- szedata2 # SZEDATA2 poll mode driver
+-- virtio # Virtio poll mode driver
+-- vmxnet3 # VMXNET3 poll mode driver
- +-- xenvirt # Xen virtio poll mode driver
.. note::
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 3362f33..7a2d2f2 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -29,9 +29,6 @@ Deprecation Notices
- ``rte_eal_devargs_type_count``
- ``rte_eal_parse_devargs_str``, replaced by ``rte_eal_devargs_parse``
-* eal: the support of Xen dom0 will be removed from EAL in 17.11; and with
- that, drivers/net/xenvirt and examples/vhost_xen will also be removed.
-
* eal: An ABI change is planned for 17.11 to make DPDK aware of IOVA address
translation scheme.
Reference to phys address in EAL data-structure or functions may change to
diff --git a/doc/guides/rel_notes/release_17_11.rst b/doc/guides/rel_notes/release_17_11.rst
index 170f4f9..d211084 100644
--- a/doc/guides/rel_notes/release_17_11.rst
+++ b/doc/guides/rel_notes/release_17_11.rst
@@ -124,7 +124,19 @@ ABI Changes
Also, make sure to start the actual text at the margin.
=========================================================
+Removed Items
+-------------
+.. This section should contain removed items in this release. Sample format:
+
+ * Add a short 1-2 sentence description of the removed item in the past
+ tense.
+
+ This section is a comment. do not overwrite or remove it.
+ Also, make sure to start the actual text at the margin.
+ =========================================================
+
+ * Xen dom0 in EAL was removed, as well as xenvirt PMD and vhost_xen.
Shared Library Versions
-----------------------
diff --git a/doc/guides/testpmd_app_ug/run_app.rst b/doc/guides/testpmd_app_ug/run_app.rst
index e8303f3..bd5ebe6 100644
--- a/doc/guides/testpmd_app_ug/run_app.rst
+++ b/doc/guides/testpmd_app_ug/run_app.rst
@@ -94,10 +94,6 @@ See the DPDK Getting Started Guides for more information on these options.
Display the version information on startup.
-* ``--xen-dom0``
-
- Support application running on Xen Domain0 without hugetlbfs.
-
* ``--syslog``
Set the syslog facility.
diff --git a/doc/guides/xen/img/dpdk_xen_pkt_switch.png b/doc/guides/xen/img/dpdk_xen_pkt_switch.png
deleted file mode 100644
index 32a6d1618820e930b17231f8fe38aab5d5c5d370..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 163842
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	B|4#=x}Zo+o_1hbF9&M<PCUkSvs6!
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
diff --git a/doc/guides/xen/img/grant_refs.png b/doc/guides/xen/img/grant_refs.png
deleted file mode 100644
index baa34e1e3f5e8975ae0516a09f906933b1ac688d..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 6405
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
R9${aAy7JpMP(_Qd{{c{~dJX^p
diff --git a/doc/guides/xen/img/grant_table.png b/doc/guides/xen/img/grant_table.png
deleted file mode 100644
index c23e5fa73e660c5be9c7cd01f55ff34e2917632b..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 96762
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
Z{{xM~vTICa&vpO+002ovPDHLkV1nHvhjah{
diff --git a/doc/guides/xen/index.rst b/doc/guides/xen/index.rst
deleted file mode 100644
index cb43cd2..0000000
--- a/doc/guides/xen/index.rst
+++ /dev/null
@@ -1,38 +0,0 @@
-.. BSD LICENSE
- Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the
- distribution.
- * Neither the name of Intel Corporation nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-Xen Guide
-=========
-
-.. toctree::
- :maxdepth: 2
- :numbered:
-
- pkt_switch
diff --git a/doc/guides/xen/pkt_switch.rst b/doc/guides/xen/pkt_switch.rst
deleted file mode 100644
index 717a04b..0000000
--- a/doc/guides/xen/pkt_switch.rst
+++ /dev/null
@@ -1,470 +0,0 @@
-.. BSD LICENSE
- Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the
- distribution.
- * Neither the name of Intel Corporation nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-DPDK Xen Based Packet-Switching Solution
-========================================
-
-Introduction
-------------
-
-DPDK provides a para-virtualization packet switching solution, based on the Xen hypervisor's Grant Table, Note 1,
-which provides simple and fast packet switching capability between guest domains and host domain based on MAC address or VLAN tag.
-
-This solution is comprised of two components;
-a Poll Mode Driver (PMD) as the front end in the guest domain and a switching back end in the host domain.
-XenStore is used to exchange configure information between the PMD front end and switching back end,
-including grant reference IDs for shared Virtio RX/TX rings,
-MAC address, device state, and so on. XenStore is an information storage space shared between domains,
-see further information on XenStore below.
-
-The front end PMD can be found in the DPDK directory lib/ librte_pmd_xenvirt and back end example in examples/vhost_xen.
-
-The PMD front end and switching back end use shared Virtio RX/TX rings as para- virtualized interface.
-The Virtio ring is created by the front end, and Grant table references for the ring are passed to host.
-The switching back end maps those grant table references and creates shared rings in a mapped address space.
-
-The following diagram describes the functionality of the DPDK Xen Packet- Switching Solution.
-
-
-.. _figure_dpdk_xen_pkt_switch:
-
-.. figure:: img/dpdk_xen_pkt_switch.*
-
- Functionality of the DPDK Xen Packet Switching Solution.
-
-
-Note 1 The Xen hypervisor uses a mechanism called a Grant Table to share memory between domains
-(`http://wiki.xen.org/wiki/Grant Table <http://wiki.xen.org/wiki/Grant%20Table>`_).
-
-A diagram of the design is shown below, where "gva" is the Guest Virtual Address,
-which is the data pointer of the mbuf, and "hva" is the Host Virtual Address:
-
-
-.. _figure_grant_table:
-
-.. figure:: img/grant_table.*
-
- DPDK Xen Layout
-
-
-In this design, a Virtio ring is used as a para-virtualized interface for better performance over a Xen private ring
-when packet switching to and from a VM.
-The additional performance is gained by avoiding a system call and memory map in each memory copy with a XEN private ring.
-
-Device Creation
----------------
-
-Poll Mode Driver Front End
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-* Mbuf pool allocation:
-
- To use a Xen switching solution, the DPDK application should use rte_mempool_gntalloc_create()
- to reserve mbuf pools during initialization.
- rte_mempool_gntalloc_create() creates a mempool with objects from memory allocated and managed via gntalloc/gntdev.
-
- The DPDK now supports construction of mempools from allocated virtual memory through the rte_mempool_xmem_create() API.
-
- This front end constructs mempools based on memory allocated through the xen_gntalloc driver.
- rte_mempool_gntalloc_create() allocates Grant pages, maps them to continuous virtual address space,
- and calls rte_mempool_xmem_create() to build mempools.
- The Grant IDs for all Grant pages are passed to the host through XenStore.
-
-* Virtio Ring Creation:
-
- The Virtio queue size is defined as 256 by default in the VQ_DESC_NUM macro.
- Using the queue setup function,
- Grant pages are allocated based on ring size and are mapped to continuous virtual address space to form the Virtio ring.
- Normally, one ring is comprised of several pages.
- Their Grant IDs are passed to the host through XenStore.
-
- There is no requirement that this memory be physically continuous.
-
-* Interrupt and Kick:
-
- There are no interrupts in DPDK Xen Switching as both front and back ends work in polling mode.
- There is no requirement for notification.
-
-* Feature Negotiation:
-
- Currently, feature negotiation through XenStore is not supported.
-
-* Packet Reception & Transmission:
-
- With mempools and Virtio rings created, the front end can operate Virtio devices,
- as it does in Virtio PMD for KVM Virtio devices with the exception that the host
- does not require notifications or deal with interrupts.
-
-XenStore is a database that stores guest and host information in the form of (key, value) pairs.
-The following is an example of the information generated during the startup of the front end PMD in a guest VM (domain ID 1):
-
-.. code-block:: console
-
- xenstore -ls /local/domain/1/control/dpdk
- 0_mempool_gref="3042,3043,3044,3045"
- 0_mempool_va="0x7fcbc6881000"
- 0_tx_vring_gref="3049"
- 0_rx_vring_gref="3053"
- 0_ether_addr="4e:0b:d0:4e:aa:f1"
- 0_vring_flag="3054"
- ...
-
-Multiple mempools and multiple Virtios may exist in the guest domain, the first number is the index, starting from zero.
-
-The idx#_mempool_va stores the guest virtual address for mempool idx#.
-
-The idx#_ether_adder stores the MAC address of the guest Virtio device.
-
-For idx#_rx_ring_gref, idx#_tx_ring_gref, and idx#_mempool_gref, the value is a list of Grant references.
-Take idx#_mempool_gref node for example, the host maps those Grant references to a continuous virtual address space.
-The real Grant reference information is stored in this virtual address space,
-where (gref, pfn) pairs follow each other with -1 as the terminator.
-
-
-.. _figure_grant_refs:
-
-.. figure:: img/grant_refs.*
-
- Mapping Grant references to a continuous virtual address space
-
-
-After all gref# IDs are retrieved, the host maps them to a continuous virtual address space.
-With the guest mempool virtual address, the host establishes 1:1 address mapping.
-With multiple guest mempools, the host establishes multiple address translation regions.
-
-Switching Back End
-~~~~~~~~~~~~~~~~~~
-
-The switching back end monitors changes in XenStore.
-When the back end detects that a new Virtio device has been created in a guest domain, it will:
-
-#. Retrieve Grant and configuration information from XenStore.
-
-#. Map and create a Virtio ring.
-
-#. Map mempools in the host and establish address translation between the guest address and host address.
-
-#. Select a free VMDQ pool, set its affinity with the Virtio device, and set the MAC/ VLAN filter.
-
-Packet Reception
-~~~~~~~~~~~~~~~~
-
-When packets arrive from an external network, the MAC?VLAN filter classifies packets into queues in one VMDQ pool.
-As each pool is bonded to a Virtio device in some guest domain, the switching back end will:
-
-#. Fetch an available entry from the Virtio RX ring.
-
-#. Get gva, and translate it to hva.
-
-#. Copy the contents of the packet to the memory buffer pointed to by gva.
-
-The DPDK application in the guest domain, based on the PMD front end,
-is polling the shared Virtio RX ring for available packets and receives them on arrival.
-
-Packet Transmission
-~~~~~~~~~~~~~~~~~~~
-
-When a Virtio device in one guest domain is to transmit a packet,
-it puts the virtual address of the packet's data area into the shared Virtio TX ring.
-
-The packet switching back end is continuously polling the Virtio TX ring.
-When new packets are available for transmission from a guest, it will:
-
-#. Fetch an available entry from the Virtio TX ring.
-
-#. Get gva, and translate it to hva.
-
-#. Copy the packet from hva to the host mbuf's data area.
-
-#. Compare the destination MAC address with all the MAC addresses of the Virtio devices it manages.
- If a match exists, it directly copies the packet to the matched VIrtio RX ring.
- Otherwise, it sends the packet out through hardware.
-
-.. note::
-
- The packet switching back end is for demonstration purposes only.
- The user could implement their switching logic based on this example.
- In this example, only one physical port on the host is supported.
- Multiple segments are not supported. The biggest mbuf supported is 4KB.
- When the back end is restarted, all front ends must also be restarted.
-
-Running the Application
------------------------
-
-The following describes the steps required to run the application.
-
-Validated Environment
-~~~~~~~~~~~~~~~~~~~~~
-
-Host:
-
- Xen-hypervisor: 4.2.2
-
- Distribution: Fedora release 18
-
- Kernel: 3.10.0
-
- Xen development package (including Xen, Xen-libs, xen-devel): 4.2.3
-
-Guest:
-
- Distribution: Fedora 16 and 18
-
- Kernel: 3.6.11
-
-Xen Host Prerequisites
-~~~~~~~~~~~~~~~~~~~~~~
-
-Note that the following commands might not be the same on different Linux* distributions.
-
-* Install xen-devel package:
-
- .. code-block:: console
-
- yum install xen-devel.x86_64
-
-* Start xend if not already started:
-
- .. code-block:: console
-
- /etc/init.d/xend start
-
-* Mount xenfs if not already mounted:
-
- .. code-block:: console
-
- mount -t xenfs none /proc/xen
-
-* Enlarge the limit for xen_gntdev driver:
-
- .. code-block:: console
-
- modprobe -r xen_gntdev
- modprobe xen_gntdev limit=1000000
-
-.. note::
-
- The default limit for earlier versions of the xen_gntdev driver is 1024.
- That is insufficient to support the mapping of multiple Virtio devices into multiple VMs,
- so it is necessary to enlarge the limit by reloading this module.
- The default limit of recent versions of xen_gntdev is 1048576.
- The rough calculation of this limit is:
-
- limit=nb_mbuf# * VM#.
-
- In DPDK examples, nb_mbuf# is normally 8192.
-
-Building and Running the Switching Backend
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-#. Edit config/common_linuxapp, and change the default configuration value for the following two items:
-
- .. code-block:: console
-
- CONFIG_RTE_LIBRTE_XEN_DOM0=y
- CONFIG RTE_LIBRTE_PMD_XENVIRT=n
-
-#. Build the target:
-
- .. code-block:: console
-
- make install T=x86_64-native-linuxapp-gcc
-
-#. Ensure that RTE_SDK and RTE_TARGET are correctly set. Build the switching example:
-
- .. code-block:: console
-
- make -C examples/vhost_xen/
-
-#. Load the Xen DPDK memory management module and preallocate memory:
-
- .. code-block:: console
-
- insmod ./x86_64-native-linuxapp-gcc/build/lib/librte_eal/linuxapp/xen_dom0/rte_dom0_mm.ko
- echo 2048> /sys/kernel/mm/dom0-mm/memsize-mB/memsize
-
- .. note::
-
- On Xen Dom0, there is no hugepage support.
- Under Xen Dom0, the DPDK uses a special memory management kernel module
- to allocate chunks of physically continuous memory.
- Refer to the *DPDK Getting Started Guide* for more information on memory management in the DPDK.
- In the above command, 4 GB memory is reserved (2048 of 2 MB pages) for DPDK.
-
-#. Load uio_pci_generic and bind one Intel NIC controller to it:
-
- .. code-block:: console
-
- modprobe uio_pci_generic
- python usertools/dpdk-devbind.py -b uio_pci_generic 0000:09:00:00.0
-
- In this case, 0000:09:00.0 is the PCI address for the NIC controller.
-
-#. Run the switching back end example:
-
- .. code-block:: console
-
- examples/vhost_xen/build/vhost-switch -l 0-3 -n 3 --xen-dom0 -- -p1
-
-.. note::
-
- The -xen-dom0 option instructs the DPDK to use the Xen kernel module to allocate memory.
-
-Other Parameters:
-
-* -vm2vm
-
- The vm2vm parameter enables/disables packet switching in software.
- Disabling vm2vm implies that on a VM packet transmission will always go to the Ethernet port
- and will not be switched to another VM
-
-* -Stats
-
- The Stats parameter controls the printing of Virtio-net device statistics.
- The parameter specifies the interval (in seconds) at which to print statistics,
- an interval of 0 seconds will disable printing statistics.
-
-Xen PMD Frontend Prerequisites
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-#. Install xen-devel package for accessing XenStore:
-
- .. code-block:: console
-
- yum install xen-devel.x86_64
-
-#. Mount xenfs, if it is not already mounted:
-
- .. code-block:: console
-
- mount -t xenfs none /proc/xen
-
-#. Enlarge the default limit for xen_gntalloc driver:
-
- .. code-block:: console
-
- modprobe -r xen_gntalloc
- modprobe xen_gntalloc limit=6000
-
-.. note::
-
- Before the Linux kernel version 3.8-rc5, Jan 15th 2013,
- a critical defect occurs when a guest is heavily allocating Grant pages.
- The Grant driver allocates fewer pages than expected which causes kernel memory corruption.
- This happens, for example, when a guest uses the v1 format of a Grant table entry and allocates
- more than 8192 Grant pages (this number might be different on different hypervisor versions).
- To work around this issue, set the limit for gntalloc driver to 6000.
- (The kernel normally allocates hundreds of Grant pages with one Xen front end per virtualized device).
- If the kernel allocates a lot of Grant pages, for example, if the user uses multiple net front devices,
- it is best to upgrade the Grant alloc driver.
- This defect has been fixed in kernel version 3.8-rc5 and later.
-
-Building and Running the Front End
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-#. Edit config/common_linuxapp, and change the default configuration value:
-
- .. code-block:: console
-
- CONFIG_RTE_LIBRTE_XEN_DOM0=n
- CONFIG_RTE_LIBRTE_PMD_XENVIRT=y
-
-#. Build the package:
-
- .. code-block:: console
-
- make install T=x86_64-native-linuxapp-gcc
-
-#. Enable hugepages. Refer to the *DPDK Getting Started Guide* for instructions on
- how to use hugepages in the DPDK.
-
-#. Run TestPMD. Refer to *DPDK TestPMD Application User Guide* for detailed parameter usage.
-
- .. code-block:: console
-
- ./x86_64-native-linuxapp-gcc/app/testpmd -l 0-3 -n 4 --vdev="net_xenvirt0,mac=00:00:00:00:00:11"
- testpmd>set fwd mac
- testpmd>start
-
- As an example to run two TestPMD instances over 2 Xen Virtio devices:
-
- .. code-block:: console
-
- --vdev="net_xenvirt0,mac=00:00:00:00:00:11" --vdev="net_xenvirt1;mac=00:00:00:00:00:22"
-
-
-Usage Examples: Injecting a Packet Stream Using a Packet Generator
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Loopback Mode
-^^^^^^^^^^^^^
-
-Run TestPMD in a guest VM:
-
-.. code-block:: console
-
- ./x86_64-native-linuxapp-gcc/app/testpmd -l 0-3 -n 4 --vdev="net_xenvirt0,mac=00:00:00:00:00:11" -- -i --eth-peer=0,00:00:00:00:00:22
- testpmd> set fwd mac
- testpmd> start
-
-Example output of the vhost_switch would be:
-
-.. code-block:: console
-
- DATA:(0) MAC_ADDRESS 00:00:00:00:00:11 and VLAN_TAG 1000 registered.
-
-The above message indicates that device 0 has been registered with MAC address 00:00:00:00:00:11 and VLAN tag 1000.
-Any packets received on the NIC with these values is placed on the device's receive queue.
-
-Configure a packet stream in the packet generator, set the destination MAC address to 00:00:00:00:00:11, and VLAN to 1000,
-the guest Virtio receives these packets and sends them out with destination MAC address 00:00:00:00:00:22.
-
-Inter-VM Mode
-^^^^^^^^^^^^^
-
-Run TestPMD in guest VM1:
-
-.. code-block:: console
-
- ./x86_64-native-linuxapp-gcc/app/testpmd -l 0-3 -n 4 --vdev="net_xenvirt0,mac=00:00:00:00:00:11" -- -i --eth-peer=0,00:00:00:00:00:22 -- -i
-
-Run TestPMD in guest VM2:
-
-.. code-block:: console
-
- ./x86_64-native-linuxapp-gcc/app/testpmd -l 0-3 -n 4 --vdev="net_xenvirt0,mac=00:00:00:00:00:22" -- -i --eth-peer=0,00:00:00:00:00:33
-
-Configure a packet stream in the packet generator, and set the destination MAC address to 00:00:00:00:00:11 and VLAN to 1000.
-The packets received in Virtio in guest VM1 will be forwarded to Virtio in guest VM2 and
-then sent out through hardware with destination MAC address 00:00:00:00:00:33.
-
-The packet flow is:
-
-packet generator->Virtio in guest VM1->switching backend->Virtio in guest VM2->switching backend->wire
diff --git a/lib/librte_eal/bsdapp/eal/include/exec-env/rte_dom0_common.h b/lib/librte_eal/bsdapp/eal/include/exec-env/rte_dom0_common.h
deleted file mode 100644
index 99a3343..0000000
--- a/lib/librte_eal/bsdapp/eal/include/exec-env/rte_dom0_common.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*-
- * This file is provided under a dual BSD/LGPLv2 license. When using or
- * redistributing this file, you may do so under either license.
- *
- * GNU LESSER GENERAL PUBLIC LICENSE
- *
- * Copyright(c) 2007-2014 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2.1 of the GNU Lesser General Public License
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Contact Information:
- * Intel Corporation
- *
- *
- * BSD LICENSE
- *
- * Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Intel Corporation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#ifndef _RTE_DOM0_COMMON_H_
-#define _RTE_DOM0_COMMON_H_
-
-#ifdef __KERNEL__
-#include <linux/if.h>
-#endif
-
-#define DOM0_NAME_MAX 256
-#define DOM0_MM_DEV "/dev/dom0_mm"
-
-#define DOM0_CONTIG_NUM_ORDER 9 /**< 2M order */
-#define DOM0_NUM_MEMSEG 512 /**< Maximum nb. of memory segment. */
-#define DOM0_MEMBLOCK_SIZE 0x200000 /**< Maximum nb. of memory block(2M). */
-#define DOM0_CONFIG_MEMSIZE 4096 /**< Maximum config memory size(4G). */
-#define DOM0_NUM_MEMBLOCK (DOM0_CONFIG_MEMSIZE / 2) /**< Maximum nb. of 2M memory block. */
-
-#define RTE_DOM0_IOCTL_PREPARE_MEMSEG _IOWR(0, 1 , struct memory_info)
-#define RTE_DOM0_IOCTL_ATTACH_TO_MEMSEG _IOWR(0, 2 , char *)
-#define RTE_DOM0_IOCTL_GET_NUM_MEMSEG _IOWR(0, 3, int)
-#define RTE_DOM0_IOCTL_GET_MEMSEG_INFO _IOWR(0, 4, void *)
-
-/**
- * A structure used to store memory information.
- */
-struct memory_info {
- char name[DOM0_NAME_MAX];
- uint64_t size;
-};
-
-/**
- * A structure used to store memory segment information.
- */
-struct memseg_info {
- uint32_t idx;
- uint64_t pfn;
- uint64_t size;
- uint64_t mfn[DOM0_NUM_MEMBLOCK];
-};
-
-/**
- * A structure used to store memory block information.
- */
-struct memblock_info {
- uint8_t exchange_flag;
- uint64_t vir_addr;
- uint64_t pfn;
- uint64_t mfn;
-};
-#endif /* _RTE_DOM0_COMMON_H_ */
diff --git a/lib/librte_eal/common/eal_common_options.c b/lib/librte_eal/common/eal_common_options.c
index 1da185e..354cded 100644
--- a/lib/librte_eal/common/eal_common_options.c
+++ b/lib/librte_eal/common/eal_common_options.c
@@ -97,7 +97,6 @@ eal_long_options[] = {
{OPT_VDEV, 1, NULL, OPT_VDEV_NUM },
{OPT_VFIO_INTR, 1, NULL, OPT_VFIO_INTR_NUM },
{OPT_VMWARE_TSC_MAP, 0, NULL, OPT_VMWARE_TSC_MAP_NUM },
- {OPT_XEN_DOM0, 0, NULL, OPT_XEN_DOM0_NUM },
{0, 0, NULL, 0 }
};
@@ -208,8 +207,6 @@ eal_reset_internal_config(struct internal_config *internal_cfg)
internal_cfg->syslog_facility = LOG_DAEMON;
- internal_cfg->xen_dom0_support = 0;
-
/* if set to NONE, interrupt mode is determined automatically */
internal_cfg->vfio_intr_mode = RTE_INTR_MODE_NONE;
diff --git a/lib/librte_eal/common/eal_internal_cfg.h b/lib/librte_eal/common/eal_internal_cfg.h
index 7b7e8c8..f7c885f 100644
--- a/lib/librte_eal/common/eal_internal_cfg.h
+++ b/lib/librte_eal/common/eal_internal_cfg.h
@@ -65,7 +65,6 @@ struct internal_config {
volatile unsigned force_nrank; /**< force number of ranks */
volatile unsigned no_hugetlbfs; /**< true to disable hugetlbfs */
unsigned hugepage_unlink; /**< true to unlink backing files */
- volatile unsigned xen_dom0_support; /**< support app running on Xen Dom0*/
volatile unsigned no_pci; /**< true to disable PCI */
volatile unsigned no_hpet; /**< true to disable HPET */
volatile unsigned vmware_tsc_map; /**< true to use VMware TSC mapping
diff --git a/lib/librte_eal/common/eal_options.h b/lib/librte_eal/common/eal_options.h
index 439a261..8770b85 100644
--- a/lib/librte_eal/common/eal_options.h
+++ b/lib/librte_eal/common/eal_options.h
@@ -81,8 +81,6 @@ enum {
OPT_VFIO_INTR_NUM,
#define OPT_VMWARE_TSC_MAP "vmware-tsc-map"
OPT_VMWARE_TSC_MAP_NUM,
-#define OPT_XEN_DOM0 "xen-dom0"
- OPT_XEN_DOM0_NUM,
OPT_LONG_MAX_NUM
};
diff --git a/lib/librte_eal/common/include/rte_memory.h b/lib/librte_eal/common/include/rte_memory.h
index 4aa5d1f..d8543c0 100644
--- a/lib/librte_eal/common/include/rte_memory.h
+++ b/lib/librte_eal/common/include/rte_memory.h
@@ -46,10 +46,6 @@
#include <rte_config.h>
-#ifdef RTE_EXEC_ENV_LINUXAPP
-#include <exec-env/rte_dom0_common.h>
-#endif
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -116,10 +112,6 @@ struct rte_memseg {
int32_t socket_id; /**< NUMA socket ID. */
uint32_t nchannel; /**< Number of channels. */
uint32_t nrank; /**< Number of ranks. */
-#ifdef RTE_LIBRTE_XEN_DOM0
- /**< store segment MFNs */
- uint64_t mfn[DOM0_NUM_MEMBLOCK];
-#endif
} __rte_packed;
/**
@@ -195,69 +187,11 @@ unsigned rte_memory_get_nchannel(void);
*/
unsigned rte_memory_get_nrank(void);
-#ifdef RTE_LIBRTE_XEN_DOM0
-
-/**< Internal use only - should DOM0 memory mapping be used */
-int rte_xen_dom0_supported(void);
-
-/**< Internal use only - phys to virt mapping for xen */
-phys_addr_t rte_xen_mem_phy2mch(int32_t, const phys_addr_t);
-
-/**
- * Return the physical address of elt, which is an element of the pool mp.
- *
- * @param memseg_id
- * Identifier of the memory segment owning the physical address. If
- * set to -1, find it automatically.
- * @param phy_addr
- * physical address of elt.
- *
- * @return
- * The physical address or RTE_BAD_PHYS_ADDR on error.
- */
-static inline phys_addr_t
-rte_mem_phy2mch(int32_t memseg_id, const phys_addr_t phy_addr)
-{
- if (rte_xen_dom0_supported())
- return rte_xen_mem_phy2mch(memseg_id, phy_addr);
- else
- return phy_addr;
-}
-
-/**
- * Memory init for supporting application running on Xen domain0.
- *
- * @param void
- *
- * @return
- * 0: successfully
- * negative: error
- */
-int rte_xen_dom0_memory_init(void);
-
-/**
- * Attach to memory setments of primary process on Xen domain0.
- *
- * @param void
- *
- * @return
- * 0: successfully
- * negative: error
- */
-int rte_xen_dom0_memory_attach(void);
-#else
-static inline int rte_xen_dom0_supported(void)
-{
- return 0;
-}
-
static inline phys_addr_t
rte_mem_phy2mch(int32_t memseg_id __rte_unused, const phys_addr_t phy_addr)
{
return phy_addr;
}
-#endif
-
#ifdef __cplusplus
}
#endif
diff --git a/lib/librte_eal/linuxapp/Makefile b/lib/librte_eal/linuxapp/Makefile
index 4794696..2ebdf31 100644
--- a/lib/librte_eal/linuxapp/Makefile
+++ b/lib/librte_eal/linuxapp/Makefile
@@ -35,7 +35,5 @@ DIRS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal
DIRS-$(CONFIG_RTE_EAL_IGB_UIO) += igb_uio
DIRS-$(CONFIG_RTE_KNI_KMOD) += kni
DEPDIRS-kni := eal
-DIRS-$(CONFIG_RTE_LIBRTE_XEN_DOM0) += xen_dom0
-DEPDIRS-xen_dom0 := eal
include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index 90bca4d..d9f9985 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -58,9 +58,6 @@ endif
SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) := eal.c
SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_hugepage_info.c
SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_memory.c
-ifeq ($(CONFIG_RTE_LIBRTE_XEN_DOM0),y)
-SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_xen_memory.c
-endif
SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_thread.c
SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_log.c
SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_vfio.c
@@ -130,7 +127,7 @@ ifeq ($(CONFIG_RTE_TOOLCHAIN_GCC),y)
CFLAGS_eal_thread.o += -Wno-return-type
endif
-INC := rte_interrupts.h rte_kni_common.h rte_dom0_common.h
+INC := rte_interrupts.h rte_kni_common.h
SYMLINK-$(CONFIG_RTE_EXEC_ENV_LINUXAPP)-include/exec-env := \
$(addprefix include/exec-env/,$(INC))
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 48f12f4..d995d03 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -354,7 +354,6 @@ eal_usage(const char *prgname)
" --"OPT_BASE_VIRTADDR" Base virtual address\n"
" --"OPT_CREATE_UIO_DEV" Create /dev/uioX (usually done by hotplug)\n"
" --"OPT_VFIO_INTR" Interrupt mode for VFIO (legacy|msi|msix)\n"
- " --"OPT_XEN_DOM0" Support running on Xen dom0 without hugetlbfs\n"
"\n");
/* Allow the application to print its usage message too if hook is set */
if ( rte_application_usage_hook ) {
@@ -555,19 +554,6 @@ eal_parse_args(int argc, char **argv)
eal_usage(prgname);
exit(EXIT_SUCCESS);
- /* long options */
- case OPT_XEN_DOM0_NUM:
-#ifdef RTE_LIBRTE_XEN_DOM0
- internal_config.xen_dom0_support = 1;
-#else
- RTE_LOG(ERR, EAL, "Can't support DPDK app "
- "running on Dom0, please configure"
- " RTE_LIBRTE_XEN_DOM0=y\n");
- ret = -1;
- goto out;
-#endif
- break;
-
case OPT_HUGE_DIR_NUM:
internal_config.hugepage_dir = optarg;
break;
@@ -641,15 +627,6 @@ eal_parse_args(int argc, char **argv)
goto out;
}
- /* --xen-dom0 doesn't make sense with --socket-mem */
- if (internal_config.xen_dom0_support && internal_config.force_sockets == 1) {
- RTE_LOG(ERR, EAL, "Options --"OPT_SOCKET_MEM" cannot be specified "
- "together with --"OPT_XEN_DOM0"\n");
- eal_usage(prgname);
- ret = -1;
- goto out;
- }
-
if (optind >= 0)
argv[optind-1] = prgname;
ret = optind-1;
@@ -794,7 +771,6 @@ rte_eal_init(int argc, char **argv)
if (internal_config.no_hugetlbfs == 0 &&
internal_config.process_type != RTE_PROC_SECONDARY &&
- internal_config.xen_dom0_support == 0 &&
eal_hugepage_info_init() < 0) {
rte_eal_init_alert("Cannot get hugepage information.");
rte_errno = EACCES;
diff --git a/lib/librte_eal/linuxapp/eal/eal_memory.c b/lib/librte_eal/linuxapp/eal/eal_memory.c
index 5279128..087fad4 100644
--- a/lib/librte_eal/linuxapp/eal/eal_memory.c
+++ b/lib/librte_eal/linuxapp/eal/eal_memory.c
@@ -75,13 +75,6 @@
#define PFN_MASK_SIZE 8
-#ifdef RTE_LIBRTE_XEN_DOM0
-int rte_xen_dom0_supported(void)
-{
- return internal_config.xen_dom0_support;
-}
-#endif
-
/**
* @file
* Huge page mapping under linux
@@ -106,10 +99,6 @@ test_phys_addrs_available(void)
uint64_t tmp;
phys_addr_t physaddr;
- /* For dom0, phys addresses can always be available */
- if (rte_xen_dom0_supported())
- return;
-
if (!rte_eal_has_hugepages()) {
RTE_LOG(ERR, EAL,
"Started without hugepages support, physical addresses not available\n");
@@ -139,29 +128,6 @@ rte_mem_virt2phy(const void *virtaddr)
int page_size;
off_t offset;
- /* when using dom0, /proc/self/pagemap always returns 0, check in
- * dpdk memory by browsing the memsegs */
- if (rte_xen_dom0_supported()) {
- struct rte_mem_config *mcfg;
- struct rte_memseg *memseg;
- unsigned i;
-
- mcfg = rte_eal_get_configuration()->mem_config;
- for (i = 0; i < RTE_MAX_MEMSEG; i++) {
- memseg = &mcfg->memseg[i];
- if (memseg->addr == NULL)
- break;
- if (virtaddr > memseg->addr &&
- virtaddr < RTE_PTR_ADD(memseg->addr,
- memseg->len)) {
- return memseg->phys_addr +
- RTE_PTR_DIFF(virtaddr, memseg->addr);
- }
- }
-
- return RTE_BAD_PHYS_ADDR;
- }
-
/* Cannot parse /proc/self/pagemap, no need to log errors everywhere */
if (!phys_addrs_available)
return RTE_BAD_PHYS_ADDR;
@@ -1067,17 +1033,6 @@ rte_eal_hugepage_init(void)
return 0;
}
-/* check if app runs on Xen Dom0 */
- if (internal_config.xen_dom0_support) {
-#ifdef RTE_LIBRTE_XEN_DOM0
- /* use dom0_mm kernel driver to init memory */
- if (rte_xen_dom0_memory_init() < 0)
- return -1;
- else
- return 0;
-#endif
- }
-
/* calculate total number of hugepages available. at this point we haven't
* yet started sorting them so they all are on socket 0 */
for (i = 0; i < (int) internal_config.num_hugepage_sizes; i++) {
@@ -1400,17 +1355,6 @@ rte_eal_hugepage_attach(void)
test_phys_addrs_available();
- if (internal_config.xen_dom0_support) {
-#ifdef RTE_LIBRTE_XEN_DOM0
- if (rte_xen_dom0_memory_attach() < 0) {
- RTE_LOG(ERR, EAL, "Failed to attach memory segments of primary "
- "process\n");
- return -1;
- }
- return 0;
-#endif
- }
-
fd_zero = open("/dev/zero", O_RDONLY);
if (fd_zero < 0) {
RTE_LOG(ERR, EAL, "Could not open /dev/zero\n");
diff --git a/lib/librte_eal/linuxapp/eal/eal_xen_memory.c b/lib/librte_eal/linuxapp/eal/eal_xen_memory.c
deleted file mode 100644
index 19db1cb..0000000
--- a/lib/librte_eal/linuxapp/eal/eal_xen_memory.c
+++ /dev/null
@@ -1,381 +0,0 @@
-/*-
- * BSD LICENSE
- *
- * Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Intel Corporation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <errno.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <inttypes.h>
-#include <string.h>
-#include <sys/mman.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/queue.h>
-#include <sys/file.h>
-#include <unistd.h>
-#include <limits.h>
-#include <sys/ioctl.h>
-#include <sys/time.h>
-
-#include <rte_log.h>
-#include <rte_memory.h>
-#include <rte_memzone.h>
-#include <rte_launch.h>
-#include <rte_eal.h>
-#include <rte_eal_memconfig.h>
-#include <rte_per_lcore.h>
-#include <rte_lcore.h>
-#include <rte_common.h>
-#include <rte_string_fns.h>
-
-#include "eal_private.h"
-#include "eal_internal_cfg.h"
-#include "eal_filesystem.h"
-#include <exec-env/rte_dom0_common.h>
-
-#define PAGE_SIZE RTE_PGSIZE_4K
-#define DEFAUL_DOM0_NAME "dom0-mem"
-
-static int xen_fd = -1;
-static const char sys_dir_path[] = "/sys/kernel/mm/dom0-mm/memsize-mB";
-
-/*
- * Try to mmap *size bytes in /dev/zero. If it is successful, return the
- * pointer to the mmap'd area and keep *size unmodified. Else, retry
- * with a smaller zone: decrease *size by mem_size until it reaches
- * 0. In this case, return NULL. Note: this function returns an address
- * which is a multiple of mem_size size.
- */
-static void *
-xen_get_virtual_area(size_t *size, size_t mem_size)
-{
- void *addr;
- int fd;
- long aligned_addr;
-
- RTE_LOG(DEBUG, EAL, "Ask a virtual area of 0x%zu bytes\n", *size);
-
- fd = open("/dev/zero", O_RDONLY);
- if (fd < 0){
- RTE_LOG(ERR, EAL, "Cannot open /dev/zero\n");
- return NULL;
- }
- do {
- addr = mmap(NULL, (*size) + mem_size, PROT_READ,
- MAP_PRIVATE, fd, 0);
- if (addr == MAP_FAILED)
- *size -= mem_size;
- } while (addr == MAP_FAILED && *size > 0);
-
- if (addr == MAP_FAILED) {
- close(fd);
- RTE_LOG(ERR, EAL, "Cannot get a virtual area\n");
- return NULL;
- }
-
- munmap(addr, (*size) + mem_size);
- close(fd);
-
- /* align addr to a mem_size boundary */
- aligned_addr = (uintptr_t)addr;
- aligned_addr = RTE_ALIGN_CEIL(aligned_addr, mem_size);
- addr = (void *)(aligned_addr);
-
- RTE_LOG(DEBUG, EAL, "Virtual area found at %p (size = 0x%zx)\n",
- addr, *size);
-
- return addr;
-}
-
-/**
- * Get memory size configuration from /sys/devices/virtual/misc/dom0_mm
- * /memsize-mB/memsize file, and the size unit is mB.
- */
-static int
-get_xen_memory_size(void)
-{
- char path[PATH_MAX];
- unsigned long mem_size = 0;
- static const char *file_name;
-
- file_name = "memsize";
- snprintf(path, sizeof(path), "%s/%s",
- sys_dir_path, file_name);
-
- if (eal_parse_sysfs_value(path, &mem_size) < 0)
- return -1;
-
- if (mem_size == 0)
- rte_exit(EXIT_FAILURE,"XEN-DOM0:the %s/%s was not"
- " configured.\n",sys_dir_path, file_name);
- if (mem_size % 2)
- rte_exit(EXIT_FAILURE,"XEN-DOM0:the %s/%s must be"
- " even number.\n",sys_dir_path, file_name);
-
- if (mem_size > DOM0_CONFIG_MEMSIZE)
- rte_exit(EXIT_FAILURE,"XEN-DOM0:the %s/%s should not be larger"
- " than %d mB\n",sys_dir_path, file_name, DOM0_CONFIG_MEMSIZE);
-
- return mem_size;
-}
-
-/**
- * Based on physical address to caculate MFN in Xen Dom0.
- */
-phys_addr_t
-rte_xen_mem_phy2mch(int32_t memseg_id, const phys_addr_t phy_addr)
-{
- int mfn_id, i;
- uint64_t mfn, mfn_offset;
- struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
- struct rte_memseg *memseg = mcfg->memseg;
-
- /* find the memory segment owning the physical address */
- if (memseg_id == -1) {
- for (i = 0; i < RTE_MAX_MEMSEG; i++) {
- if ((phy_addr >= memseg[i].phys_addr) &&
- (phy_addr < memseg[i].phys_addr +
- memseg[i].len)) {
- memseg_id = i;
- break;
- }
- }
- if (memseg_id == -1)
- return RTE_BAD_PHYS_ADDR;
- }
-
- mfn_id = (phy_addr - memseg[memseg_id].phys_addr) / RTE_PGSIZE_2M;
-
- /*the MFN is contiguous in 2M */
- mfn_offset = (phy_addr - memseg[memseg_id].phys_addr) %
- RTE_PGSIZE_2M / PAGE_SIZE;
- mfn = mfn_offset + memseg[memseg_id].mfn[mfn_id];
-
- /** return mechine address */
- return mfn * PAGE_SIZE + phy_addr % PAGE_SIZE;
-}
-
-int
-rte_xen_dom0_memory_init(void)
-{
- void *vir_addr, *vma_addr = NULL;
- int err, ret = 0;
- uint32_t i, requested, mem_size, memseg_idx, num_memseg = 0;
- size_t vma_len = 0;
- struct memory_info meminfo;
- struct memseg_info seginfo[RTE_MAX_MEMSEG];
- int flags, page_size = getpagesize();
- struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
- struct rte_memseg *memseg = mcfg->memseg;
- uint64_t total_mem = internal_config.memory;
-
- memset(seginfo, 0, sizeof(seginfo));
- memset(&meminfo, 0, sizeof(struct memory_info));
-
- mem_size = get_xen_memory_size();
- requested = (unsigned) (total_mem / 0x100000);
- if (requested > mem_size)
- /* if we didn't satisfy total memory requirements */
- rte_exit(EXIT_FAILURE,"Not enough memory available! Requested: %uMB,"
- " available: %uMB\n", requested, mem_size);
- else if (total_mem != 0)
- mem_size = requested;
-
- /* Check FD and open once */
- if (xen_fd < 0) {
- xen_fd = open(DOM0_MM_DEV, O_RDWR);
- if (xen_fd < 0) {
- RTE_LOG(ERR, EAL, "Can not open %s\n",DOM0_MM_DEV);
- return -1;
- }
- }
-
- meminfo.size = mem_size;
-
- /* construct memory mangement name for Dom0 */
- snprintf(meminfo.name, DOM0_NAME_MAX, "%s-%s",
- internal_config.hugefile_prefix, DEFAUL_DOM0_NAME);
-
- /* Notify kernel driver to allocate memory */
- ret = ioctl(xen_fd, RTE_DOM0_IOCTL_PREPARE_MEMSEG, &meminfo);
- if (ret < 0) {
- RTE_LOG(ERR, EAL, "XEN DOM0:failed to get memory\n");
- err = -EIO;
- goto fail;
- }
-
- /* Get number of memory segment from driver */
- ret = ioctl(xen_fd, RTE_DOM0_IOCTL_GET_NUM_MEMSEG, &num_memseg);
- if (ret < 0) {
- RTE_LOG(ERR, EAL, "XEN DOM0:failed to get memseg count.\n");
- err = -EIO;
- goto fail;
- }
-
- if(num_memseg > RTE_MAX_MEMSEG){
- RTE_LOG(ERR, EAL, "XEN DOM0: the memseg count %d is greater"
- " than max memseg %d.\n",num_memseg, RTE_MAX_MEMSEG);
- err = -EIO;
- goto fail;
- }
-
- /* get all memory segements information */
- ret = ioctl(xen_fd, RTE_DOM0_IOCTL_GET_MEMSEG_INFO, seginfo);
- if (ret < 0) {
- RTE_LOG(ERR, EAL, "XEN DOM0:failed to get memseg info.\n");
- err = -EIO;
- goto fail;
- }
-
- /* map all memory segments to contiguous user space */
- for (memseg_idx = 0; memseg_idx < num_memseg; memseg_idx++)
- {
- vma_len = seginfo[memseg_idx].size;
-
- /**
- * get the biggest virtual memory area up to vma_len. If it fails,
- * vma_addr is NULL, so let the kernel provide the address.
- */
- vma_addr = xen_get_virtual_area(&vma_len, RTE_PGSIZE_2M);
- if (vma_addr == NULL) {
- flags = MAP_SHARED;
- vma_len = RTE_PGSIZE_2M;
- } else
- flags = MAP_SHARED | MAP_FIXED;
-
- seginfo[memseg_idx].size = vma_len;
- vir_addr = mmap(vma_addr, seginfo[memseg_idx].size,
- PROT_READ|PROT_WRITE, flags, xen_fd,
- memseg_idx * page_size);
- if (vir_addr == MAP_FAILED) {
- RTE_LOG(ERR, EAL, "XEN DOM0:Could not mmap %s\n",
- DOM0_MM_DEV);
- err = -EIO;
- goto fail;
- }
-
- memseg[memseg_idx].addr = vir_addr;
- memseg[memseg_idx].phys_addr = page_size *
- seginfo[memseg_idx].pfn ;
- memseg[memseg_idx].len = seginfo[memseg_idx].size;
- for ( i = 0; i < seginfo[memseg_idx].size / RTE_PGSIZE_2M; i++)
- memseg[memseg_idx].mfn[i] = seginfo[memseg_idx].mfn[i];
-
- /* MFNs are continuous in 2M, so assume that page size is 2M */
- memseg[memseg_idx].hugepage_sz = RTE_PGSIZE_2M;
-
- memseg[memseg_idx].nchannel = mcfg->nchannel;
- memseg[memseg_idx].nrank = mcfg->nrank;
-
- /* NUMA is not suppoted in Xen Dom0, so only set socket 0*/
- memseg[memseg_idx].socket_id = 0;
- }
-
- return 0;
-fail:
- if (xen_fd > 0) {
- close(xen_fd);
- xen_fd = -1;
- }
- return err;
-}
-
-/*
- * This creates the memory mappings in the secondary process to match that of
- * the server process. It goes through each memory segment in the DPDK runtime
- * configuration, mapping them in order to form a contiguous block in the
- * virtual memory space
- */
-int
-rte_xen_dom0_memory_attach(void)
-{
- const struct rte_mem_config *mcfg;
- unsigned s = 0; /* s used to track the segment number */
- int xen_fd = -1;
- int ret = -1;
- void *vir_addr;
- char name[DOM0_NAME_MAX] = {0};
- int page_size = getpagesize();
-
- mcfg = rte_eal_get_configuration()->mem_config;
-
- /* Check FD and open once */
- if (xen_fd < 0) {
- xen_fd = open(DOM0_MM_DEV, O_RDWR);
- if (xen_fd < 0) {
- RTE_LOG(ERR, EAL, "Can not open %s\n",DOM0_MM_DEV);
- goto error;
- }
- }
-
- /* construct memory mangement name for Dom0 */
- snprintf(name, DOM0_NAME_MAX, "%s-%s",
- internal_config.hugefile_prefix, DEFAUL_DOM0_NAME);
- /* attach to memory segments of primary process */
- ret = ioctl(xen_fd, RTE_DOM0_IOCTL_ATTACH_TO_MEMSEG, name);
- if (ret) {
- RTE_LOG(ERR, EAL,"attach memory segments fail.\n");
- goto error;
- }
-
- /* map all segments into memory to make sure we get the addrs */
- for (s = 0; s < RTE_MAX_MEMSEG; ++s) {
-
- /*
- * the first memory segment with len==0 is the one that
- * follows the last valid segment.
- */
- if (mcfg->memseg[s].len == 0)
- break;
-
- vir_addr = mmap(mcfg->memseg[s].addr, mcfg->memseg[s].len,
- PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, xen_fd,
- s * page_size);
- if (vir_addr == MAP_FAILED) {
- RTE_LOG(ERR, EAL, "Could not mmap %llu bytes "
- "in %s to requested address [%p]\n",
- (unsigned long long)mcfg->memseg[s].len, DOM0_MM_DEV,
- mcfg->memseg[s].addr);
- goto error;
- }
- }
- return 0;
-
-error:
- if (xen_fd >= 0) {
- close(xen_fd);
- xen_fd = -1;
- }
- return -1;
-}
diff --git a/lib/librte_eal/linuxapp/eal/include/exec-env/rte_dom0_common.h b/lib/librte_eal/linuxapp/eal/include/exec-env/rte_dom0_common.h
deleted file mode 100644
index d970778..0000000
--- a/lib/librte_eal/linuxapp/eal/include/exec-env/rte_dom0_common.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/*-
- * This file is provided under a dual BSD/LGPLv2 license. When using or
- * redistributing this file, you may do so under either license.
- *
- * GNU LESSER GENERAL PUBLIC LICENSE
- *
- * Copyright(c) 2007-2014 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2.1 of the GNU Lesser General Public License
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Contact Information:
- * Intel Corporation
- *
- *
- * BSD LICENSE
- *
- * Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Intel Corporation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#ifndef _RTE_DOM0_COMMON_H_
-#define _RTE_DOM0_COMMON_H_
-
-#ifdef __KERNEL__
-#include <linux/if.h>
-#endif
-
-#define DOM0_NAME_MAX 256
-#define DOM0_MM_DEV "/dev/dom0_mm"
-
-#define DOM0_CONTIG_NUM_ORDER 9 /**< order of 2M */
-#define DOM0_NUM_MEMSEG 512 /**< Maximum nb. of memory segment. */
-#define DOM0_MEMBLOCK_SIZE 0x200000 /**< size of memory block(2M). */
-#define DOM0_CONFIG_MEMSIZE 4096 /**< Maximum config memory size(4G). */
-#define DOM0_NUM_MEMBLOCK (DOM0_CONFIG_MEMSIZE / 2) /**< Maximum nb. of 2M memory block. */
-
-#define RTE_DOM0_IOCTL_PREPARE_MEMSEG _IOWR(0, 1 , struct memory_info)
-#define RTE_DOM0_IOCTL_ATTACH_TO_MEMSEG _IOWR(0, 2 , char *)
-#define RTE_DOM0_IOCTL_GET_NUM_MEMSEG _IOWR(0, 3, int)
-#define RTE_DOM0_IOCTL_GET_MEMSEG_INFO _IOWR(0, 4, void *)
-
-/**
- * A structure used to store memory information.
- */
-struct memory_info {
- char name[DOM0_NAME_MAX];
- uint64_t size;
-};
-
-/**
- * A structure used to store memory segment information.
- */
-struct memseg_info {
- uint32_t idx;
- uint64_t pfn;
- uint64_t size;
- uint64_t mfn[DOM0_NUM_MEMBLOCK];
-};
-
-/**
- * A structure used to store memory block information.
- */
-struct memblock_info {
- uint8_t exchange_flag;
- uint8_t used;
- uint64_t vir_addr;
- uint64_t pfn;
- uint64_t mfn;
-};
-#endif /* _RTE_DOM0_COMMON_H_ */
diff --git a/lib/librte_eal/linuxapp/igb_uio/igb_uio.c b/lib/librte_eal/linuxapp/igb_uio/igb_uio.c
index 07a19a3..3d5c2f3 100644
--- a/lib/librte_eal/linuxapp/igb_uio/igb_uio.c
+++ b/lib/librte_eal/linuxapp/igb_uio/igb_uio.c
@@ -33,9 +33,6 @@
#include <linux/version.h>
#include <linux/slab.h>
-#ifdef CONFIG_XEN_DOM0
-#include <xen/xen.h>
-#endif
#include <rte_pci_dev_features.h>
#include "compat.h"
@@ -201,52 +198,6 @@ igbuio_pci_release(struct uio_info *info, struct inode *inode)
return 0;
}
-#ifdef CONFIG_XEN_DOM0
-static int
-igbuio_dom0_mmap_phys(struct uio_info *info, struct vm_area_struct *vma)
-{
- int idx;
-
- idx = (int)vma->vm_pgoff;
- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-#ifdef HAVE_PTE_MASK_PAGE_IOMAP
- vma->vm_page_prot.pgprot |= _PAGE_IOMAP;
-#endif
-
- return remap_pfn_range(vma,
- vma->vm_start,
- info->mem[idx].addr >> PAGE_SHIFT,
- vma->vm_end - vma->vm_start,
- vma->vm_page_prot);
-}
-
-/**
- * This is uio device mmap method which will use igbuio mmap for Xen
- * Dom0 environment.
- */
-static int
-igbuio_dom0_pci_mmap(struct uio_info *info, struct vm_area_struct *vma)
-{
- int idx;
-
- if (vma->vm_pgoff >= MAX_UIO_MAPS)
- return -EINVAL;
-
- if (info->mem[vma->vm_pgoff].size == 0)
- return -EINVAL;
-
- idx = (int)vma->vm_pgoff;
- switch (info->mem[idx].memtype) {
- case UIO_MEM_PHYS:
- return igbuio_dom0_mmap_phys(info, vma);
- case UIO_MEM_LOGICAL:
- case UIO_MEM_VIRTUAL:
- default:
- return -EINVAL;
- }
-}
-#endif
-
/* Remap pci resources described by bar #pci_bar in uio resource n. */
static int
igbuio_pci_setup_iomem(struct pci_dev *dev, struct uio_info *info,
@@ -405,11 +356,6 @@ igbuio_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
udev->info.irqcontrol = igbuio_pci_irqcontrol;
udev->info.open = igbuio_pci_open;
udev->info.release = igbuio_pci_release;
-#ifdef CONFIG_XEN_DOM0
- /* check if the driver run on Xen Dom0 */
- if (xen_initial_domain())
- udev->info.mmap = igbuio_dom0_pci_mmap;
-#endif
udev->info.priv = udev;
udev->pdev = dev;
diff --git a/lib/librte_eal/linuxapp/xen_dom0/Makefile b/lib/librte_eal/linuxapp/xen_dom0/Makefile
deleted file mode 100644
index be51a82..0000000
--- a/lib/librte_eal/linuxapp/xen_dom0/Makefile
+++ /dev/null
@@ -1,53 +0,0 @@
-# BSD LICENSE
-#
-# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in
-# the documentation and/or other materials provided with the
-# distribution.
-# * Neither the name of Intel Corporation nor the names of its
-# contributors may be used to endorse or promote products derived
-# from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-include $(RTE_SDK)/mk/rte.vars.mk
-
-#
-# module name and path
-#
-MODULE = rte_dom0_mm
-
-#
-# CFLAGS
-#
-MODULE_CFLAGS += -I$(SRCDIR) --param max-inline-insns-single=50
-MODULE_CFLAGS += -I$(RTE_OUTPUT)/include
-MODULE_CFLAGS += -include $(RTE_OUTPUT)/include/rte_config.h
-MODULE_CFLAGS += -Wall -Werror
-
-#
-# all source are stored in SRCS-y
-#
-
-SRCS-y += dom0_mm_misc.c
-
-include $(RTE_SDK)/mk/rte.module.mk
diff --git a/lib/librte_eal/linuxapp/xen_dom0/compat.h b/lib/librte_eal/linuxapp/xen_dom0/compat.h
deleted file mode 100644
index e6eb97f..0000000
--- a/lib/librte_eal/linuxapp/xen_dom0/compat.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Minimal wrappers to allow compiling xen_dom0 on older kernels.
- */
-
-#ifndef RHEL_RELEASE_VERSION
-#define RHEL_RELEASE_VERSION(a, b) (((a) << 8) + (b))
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39) && \
- (!(defined(RHEL_RELEASE_CODE) && \
- RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6, 4)))
-
-#define kstrtoul strict_strtoul
-
-#endif /* < 2.6.39 */
diff --git a/lib/librte_eal/linuxapp/xen_dom0/dom0_mm_dev.h b/lib/librte_eal/linuxapp/xen_dom0/dom0_mm_dev.h
deleted file mode 100644
index 9d5ffb2..0000000
--- a/lib/librte_eal/linuxapp/xen_dom0/dom0_mm_dev.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*-
- * This file is provided under a dual BSD/GPLv2 license. When using or
- * redistributing this file, you may do so under either license.
- *
- * GPL LICENSE SUMMARY
- *
- * Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- * The full GNU General Public License is included in this distribution
- * in the file called LICENSE.GPL.
- *
- * Contact Information:
- * Intel Corporation
- *
- * BSD LICENSE
- *
- * Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Intel Corporation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-#ifndef _DOM0_MM_DEV_H_
-#define _DOM0_MM_DEV_H_
-
-#include <linux/wait.h>
-#include <linux/mutex.h>
-#include <linux/sched.h>
-#include <linux/spinlock.h>
-#include <exec-env/rte_dom0_common.h>
-
-#define NUM_MEM_CTX 256 /**< Maximum number of memory context*/
-#define MAX_EXCHANGE_FAIL_TIME 5 /**< Maximum times of allowing exchange fail .*/
-#define MAX_MEMBLOCK_SIZE (2 * DOM0_MEMBLOCK_SIZE)
-#define MAX_NUM_ORDER (DOM0_CONTIG_NUM_ORDER + 1)
-#define SIZE_PER_BLOCK 2 /**< Size of memory block (2MB).*/
-
-/**
- * A structure describing the private information for a dom0 device.
- */
-struct dom0_mm_dev {
- struct miscdevice miscdev;
- uint8_t fail_times;
- uint32_t used_memsize;
- uint32_t num_mem_ctx;
- uint32_t config_memsize;
- uint32_t num_bigblock;
- struct dom0_mm_data *mm_data[NUM_MEM_CTX];
- struct mutex data_lock;
-};
-
-struct dom0_mm_data{
- uint32_t refcnt;
- uint32_t num_memseg; /**< Number of memory segment. */
- uint32_t mem_size; /**< Size of requesting memory. */
-
- char name[DOM0_NAME_MAX];
-
- /** Store global memory block IDs used by an instance */
- uint32_t block_num[DOM0_NUM_MEMBLOCK];
-
- /** Store memory block information.*/
- struct memblock_info block_info[DOM0_NUM_MEMBLOCK];
-
- /** Store memory segment information.*/
- struct memseg_info seg_info[DOM0_NUM_MEMSEG];
-};
-
-#define XEN_ERR(args...) printk(KERN_DEBUG "XEN_DOM0: Error: " args)
-#define XEN_PRINT(args...) printk(KERN_DEBUG "XEN_DOM0: " args)
-#endif
diff --git a/lib/librte_eal/linuxapp/xen_dom0/dom0_mm_misc.c b/lib/librte_eal/linuxapp/xen_dom0/dom0_mm_misc.c
deleted file mode 100644
index 79630ba..0000000
--- a/lib/librte_eal/linuxapp/xen_dom0/dom0_mm_misc.c
+++ /dev/null
@@ -1,780 +0,0 @@
-/*-
- * This file is provided under a dual BSD/GPLv2 license. When using or
- * redistributing this file, you may do so under either license.
- *
- * GPL LICENSE SUMMARY
- *
- * Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- * The full GNU General Public License is included in this distribution
- * in the file called LICENSE.GPL.
- *
- * Contact Information:
- * Intel Corporation
- *
- * BSD LICENSE
- *
- * Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Intel Corporation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include <linux/module.h>
-#include <linux/miscdevice.h>
-#include <linux/fs.h>
-#include <linux/device.h>
-#include <linux/errno.h>
-#include <linux/vmalloc.h>
-#include <linux/mm.h>
-#include <linux/version.h>
-
-#include <xen/xen.h>
-#include <xen/page.h>
-#include <xen/xen-ops.h>
-#include <xen/interface/memory.h>
-
-#include <exec-env/rte_dom0_common.h>
-
-#include "compat.h"
-#include "dom0_mm_dev.h"
-
-MODULE_LICENSE("Dual BSD/GPL");
-MODULE_AUTHOR("Intel Corporation");
-MODULE_DESCRIPTION("Kernel Module for supporting DPDK running on Xen Dom0");
-
-static struct dom0_mm_dev dom0_dev;
-static struct kobject *dom0_kobj = NULL;
-
-static struct memblock_info *rsv_mm_info;
-
-/* Default configuration for reserved memory size(2048 MB). */
-static uint32_t rsv_memsize = 2048;
-
-static int dom0_open(struct inode *inode, struct file *file);
-static int dom0_release(struct inode *inode, struct file *file);
-static int dom0_ioctl(struct file *file, unsigned int ioctl_num,
- unsigned long ioctl_param);
-static int dom0_mmap(struct file *file, struct vm_area_struct *vma);
-static int dom0_memory_free(uint32_t size);
-static int dom0_memory_release(struct dom0_mm_data *mm_data);
-
-static const struct file_operations data_fops = {
- .owner = THIS_MODULE,
- .open = dom0_open,
- .release = dom0_release,
- .mmap = dom0_mmap,
- .unlocked_ioctl = (void *)dom0_ioctl,
-};
-
-static ssize_t
-show_memsize_rsvd(struct device *dev, struct device_attribute *attr, char *buf)
-{
- return snprintf(buf, 10, "%u\n", dom0_dev.used_memsize);
-}
-
-static ssize_t
-show_memsize(struct device *dev, struct device_attribute *attr, char *buf)
-{
- return snprintf(buf, 10, "%u\n", dom0_dev.config_memsize);
-}
-
-static ssize_t
-store_memsize(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
-{
- int err = 0;
- unsigned long mem_size;
-
- if (0 != kstrtoul(buf, 0, &mem_size))
- return -EINVAL;
-
- mutex_lock(&dom0_dev.data_lock);
- if (0 == mem_size) {
- err = -EINVAL;
- goto fail;
- } else if (mem_size > (rsv_memsize - dom0_dev.used_memsize)) {
- XEN_ERR("configure memory size fail\n");
- err = -EINVAL;
- goto fail;
- } else
- dom0_dev.config_memsize = mem_size;
-
-fail:
- mutex_unlock(&dom0_dev.data_lock);
- return err ? err : count;
-}
-
-static DEVICE_ATTR(memsize, S_IRUGO | S_IWUSR, show_memsize, store_memsize);
-static DEVICE_ATTR(memsize_rsvd, S_IRUGO, show_memsize_rsvd, NULL);
-
-static struct attribute *dev_attrs[] = {
- &dev_attr_memsize.attr,
- &dev_attr_memsize_rsvd.attr,
- NULL,
-};
-
-/* the memory size unit is MB */
-static const struct attribute_group dev_attr_grp = {
- .name = "memsize-mB",
- .attrs = dev_attrs,
-};
-
-
-static void
-sort_viraddr(struct memblock_info *mb, int cnt)
-{
- int i,j;
- uint64_t tmp_pfn;
- uint64_t tmp_viraddr;
-
- /*sort virtual address and pfn */
- for(i = 0; i < cnt; i ++) {
- for(j = cnt - 1; j > i; j--) {
- if(mb[j].pfn < mb[j - 1].pfn) {
- tmp_pfn = mb[j - 1].pfn;
- mb[j - 1].pfn = mb[j].pfn;
- mb[j].pfn = tmp_pfn;
-
- tmp_viraddr = mb[j - 1].vir_addr;
- mb[j - 1].vir_addr = mb[j].vir_addr;
- mb[j].vir_addr = tmp_viraddr;
- }
- }
- }
-}
-
-static int
-dom0_find_memdata(const char * mem_name)
-{
- unsigned i;
- int idx = -1;
- for(i = 0; i< NUM_MEM_CTX; i++) {
- if(dom0_dev.mm_data[i] == NULL)
- continue;
- if (!strncmp(dom0_dev.mm_data[i]->name, mem_name,
- sizeof(char) * DOM0_NAME_MAX)) {
- idx = i;
- break;
- }
- }
-
- return idx;
-}
-
-static int
-dom0_find_mempos(void)
-{
- unsigned i;
- int idx = -1;
-
- for(i = 0; i< NUM_MEM_CTX; i++) {
- if(dom0_dev.mm_data[i] == NULL){
- idx = i;
- break;
- }
- }
-
- return idx;
-}
-
-static int
-dom0_memory_release(struct dom0_mm_data *mm_data)
-{
- int idx;
- uint32_t num_block, block_id;
-
- /* each memory block is 2M */
- num_block = mm_data->mem_size / SIZE_PER_BLOCK;
- if (num_block == 0)
- return -EINVAL;
-
- /* reset global memory data */
- idx = dom0_find_memdata(mm_data->name);
- if (idx >= 0) {
- dom0_dev.used_memsize -= mm_data->mem_size;
- dom0_dev.mm_data[idx] = NULL;
- dom0_dev.num_mem_ctx--;
- }
-
- /* reset these memory blocks status as free */
- for (idx = 0; idx < num_block; idx++) {
- block_id = mm_data->block_num[idx];
- rsv_mm_info[block_id].used = 0;
- }
-
- memset(mm_data, 0, sizeof(struct dom0_mm_data));
- vfree(mm_data);
- return 0;
-}
-
-static int
-dom0_memory_free(uint32_t rsv_size)
-{
- uint64_t vstart, vaddr;
- uint32_t i, num_block, size;
-
- if (!xen_pv_domain())
- return -1;
-
- /* each memory block is 2M */
- num_block = rsv_size / SIZE_PER_BLOCK;
- if (num_block == 0)
- return -EINVAL;
-
- /* free all memory blocks of size of 4M and destroy contiguous region */
- for (i = 0; i < dom0_dev.num_bigblock * 2; i += 2) {
- vstart = rsv_mm_info[i].vir_addr;
- if (vstart) {
- #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
- if (rsv_mm_info[i].exchange_flag)
- xen_destroy_contiguous_region(vstart,
- DOM0_CONTIG_NUM_ORDER);
- if (rsv_mm_info[i + 1].exchange_flag)
- xen_destroy_contiguous_region(vstart +
- DOM0_MEMBLOCK_SIZE,
- DOM0_CONTIG_NUM_ORDER);
- #else
- if (rsv_mm_info[i].exchange_flag)
- xen_destroy_contiguous_region(rsv_mm_info[i].pfn
- * PAGE_SIZE,
- DOM0_CONTIG_NUM_ORDER);
- if (rsv_mm_info[i + 1].exchange_flag)
- xen_destroy_contiguous_region(rsv_mm_info[i].pfn
- * PAGE_SIZE + DOM0_MEMBLOCK_SIZE,
- DOM0_CONTIG_NUM_ORDER);
- #endif
-
- size = DOM0_MEMBLOCK_SIZE * 2;
- vaddr = vstart;
- while (size > 0) {
- ClearPageReserved(virt_to_page(vaddr));
- vaddr += PAGE_SIZE;
- size -= PAGE_SIZE;
- }
- free_pages(vstart, MAX_NUM_ORDER);
- }
- }
-
- /* free all memory blocks size of 2M and destroy contiguous region */
- for (; i < num_block; i++) {
- vstart = rsv_mm_info[i].vir_addr;
- if (vstart) {
- if (rsv_mm_info[i].exchange_flag)
- xen_destroy_contiguous_region(vstart,
- DOM0_CONTIG_NUM_ORDER);
-
- size = DOM0_MEMBLOCK_SIZE;
- vaddr = vstart;
- while (size > 0) {
- ClearPageReserved(virt_to_page(vaddr));
- vaddr += PAGE_SIZE;
- size -= PAGE_SIZE;
- }
- free_pages(vstart, DOM0_CONTIG_NUM_ORDER);
- }
- }
-
- memset(rsv_mm_info, 0, sizeof(struct memblock_info) * num_block);
- vfree(rsv_mm_info);
- rsv_mm_info = NULL;
-
- return 0;
-}
-
-static void
-find_free_memory(uint32_t count, struct dom0_mm_data *mm_data)
-{
- uint32_t i = 0;
- uint32_t j = 0;
-
- while ((i < count) && (j < rsv_memsize / SIZE_PER_BLOCK)) {
- if (rsv_mm_info[j].used == 0) {
- mm_data->block_info[i].pfn = rsv_mm_info[j].pfn;
- mm_data->block_info[i].vir_addr =
- rsv_mm_info[j].vir_addr;
- mm_data->block_info[i].mfn = rsv_mm_info[j].mfn;
- mm_data->block_info[i].exchange_flag =
- rsv_mm_info[j].exchange_flag;
- mm_data->block_num[i] = j;
- rsv_mm_info[j].used = 1;
- i++;
- }
- j++;
- }
-}
-
-/**
- * Find all memory segments in which physical addresses are contiguous.
- */
-static void
-find_memseg(int count, struct dom0_mm_data * mm_data)
-{
- int i = 0;
- int j, k, idx = 0;
- uint64_t zone_len, pfn, num_block;
-
- while(i < count) {
- if (mm_data->block_info[i].exchange_flag == 0) {
- i++;
- continue;
- }
- k = 0;
- pfn = mm_data->block_info[i].pfn;
- mm_data->seg_info[idx].pfn = pfn;
- mm_data->seg_info[idx].mfn[k] = mm_data->block_info[i].mfn;
-
- for (j = i + 1; j < count; j++) {
-
- /* ignore exchange fail memory block */
- if (mm_data->block_info[j].exchange_flag == 0)
- break;
-
- if (mm_data->block_info[j].pfn !=
- (mm_data->block_info[j - 1].pfn +
- DOM0_MEMBLOCK_SIZE / PAGE_SIZE))
- break;
- ++k;
- mm_data->seg_info[idx].mfn[k] = mm_data->block_info[j].mfn;
- }
-
- num_block = j - i;
- zone_len = num_block * DOM0_MEMBLOCK_SIZE;
- mm_data->seg_info[idx].size = zone_len;
-
- XEN_PRINT("memseg id=%d, size=0x%llx\n", idx, zone_len);
- i = i+ num_block;
- idx++;
- if (idx == DOM0_NUM_MEMSEG)
- break;
- }
- mm_data->num_memseg = idx;
-}
-
-static int
-dom0_memory_reserve(uint32_t rsv_size)
-{
- uint64_t pfn, vstart, vaddr;
- uint32_t i, num_block, size, allocated_size = 0;
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0)
- dma_addr_t dma_handle;
-#endif
-
- /* 2M as memory block */
- num_block = rsv_size / SIZE_PER_BLOCK;
-
- rsv_mm_info = vmalloc(sizeof(struct memblock_info) * num_block);
- if (!rsv_mm_info) {
- XEN_ERR("Unable to allocate device memory information\n");
- return -ENOMEM;
- }
- memset(rsv_mm_info, 0, sizeof(struct memblock_info) * num_block);
-
- /* try alloc size of 4M once */
- for (i = 0; i < num_block; i += 2) {
- vstart = (unsigned long)
- __get_free_pages(GFP_ATOMIC, MAX_NUM_ORDER);
- if (vstart == 0)
- break;
-
- dom0_dev.num_bigblock = i / 2 + 1;
- allocated_size = SIZE_PER_BLOCK * (i + 2);
-
- /* size of 4M */
- size = DOM0_MEMBLOCK_SIZE * 2;
-
- vaddr = vstart;
- while (size > 0) {
- SetPageReserved(virt_to_page(vaddr));
- vaddr += PAGE_SIZE;
- size -= PAGE_SIZE;
- }
-
- pfn = virt_to_pfn(vstart);
- rsv_mm_info[i].pfn = pfn;
- rsv_mm_info[i].vir_addr = vstart;
- rsv_mm_info[i + 1].pfn =
- pfn + DOM0_MEMBLOCK_SIZE / PAGE_SIZE;
- rsv_mm_info[i + 1].vir_addr =
- vstart + DOM0_MEMBLOCK_SIZE;
- }
-
- /*if it failed to alloc 4M, and continue to alloc 2M once */
- for (; i < num_block; i++) {
- vstart = (unsigned long)
- __get_free_pages(GFP_ATOMIC, DOM0_CONTIG_NUM_ORDER);
- if (vstart == 0) {
- XEN_ERR("allocate memory fail.\n");
- dom0_memory_free(allocated_size);
- return -ENOMEM;
- }
-
- allocated_size += SIZE_PER_BLOCK;
-
- size = DOM0_MEMBLOCK_SIZE;
- vaddr = vstart;
- while (size > 0) {
- SetPageReserved(virt_to_page(vaddr));
- vaddr += PAGE_SIZE;
- size -= PAGE_SIZE;
- }
- pfn = virt_to_pfn(vstart);
- rsv_mm_info[i].pfn = pfn;
- rsv_mm_info[i].vir_addr = vstart;
- }
-
- sort_viraddr(rsv_mm_info, num_block);
-
- for (i = 0; i< num_block; i++) {
-
- /*
- * This API is used to exchage MFN for getting a block of
- * contiguous physical addresses, its maximum size is 2M.
- */
- #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
- if (xen_create_contiguous_region(rsv_mm_info[i].vir_addr,
- DOM0_CONTIG_NUM_ORDER, 0) == 0) {
- #else
- if (xen_create_contiguous_region(rsv_mm_info[i].pfn * PAGE_SIZE,
- DOM0_CONTIG_NUM_ORDER, 0, &dma_handle) == 0) {
- #endif
- rsv_mm_info[i].exchange_flag = 1;
- rsv_mm_info[i].mfn =
- pfn_to_mfn(rsv_mm_info[i].pfn);
- rsv_mm_info[i].used = 0;
- } else {
- XEN_ERR("exchange memeory fail\n");
- rsv_mm_info[i].exchange_flag = 0;
- dom0_dev.fail_times++;
- if (dom0_dev.fail_times > MAX_EXCHANGE_FAIL_TIME) {
- dom0_memory_free(rsv_size);
- return -EFAULT;
- }
- }
- }
-
- return 0;
-}
-
-static int
-dom0_prepare_memsegs(struct memory_info *meminfo, struct dom0_mm_data *mm_data)
-{
- uint32_t num_block;
- int idx;
-
- /* check if there is a free name buffer */
- memcpy(mm_data->name, meminfo->name, DOM0_NAME_MAX);
- mm_data->name[DOM0_NAME_MAX - 1] = '\0';
- idx = dom0_find_mempos();
- if (idx < 0)
- return -1;
-
- num_block = meminfo->size / SIZE_PER_BLOCK;
- /* find free memory and new memory segments*/
- find_free_memory(num_block, mm_data);
- find_memseg(num_block, mm_data);
-
- /* update private memory data */
- mm_data->refcnt++;
- mm_data->mem_size = meminfo->size;
-
- /* update global memory data */
- dom0_dev.mm_data[idx] = mm_data;
- dom0_dev.num_mem_ctx++;
- dom0_dev.used_memsize += mm_data->mem_size;
-
- return 0;
-}
-
-static int
-dom0_check_memory (struct memory_info *meminfo)
-{
- int idx;
- uint64_t mem_size;
-
- /* round memory size to the next even number. */
- if (meminfo->size % 2)
- ++meminfo->size;
-
- mem_size = meminfo->size;
- if (dom0_dev.num_mem_ctx > NUM_MEM_CTX) {
- XEN_ERR("Memory data space is full in Dom0 driver\n");
- return -1;
- }
- idx = dom0_find_memdata(meminfo->name);
- if (idx >= 0) {
- XEN_ERR("Memory data name %s has already exsited in Dom0 driver.\n",
- meminfo->name);
- return -1;
- }
- if ((dom0_dev.used_memsize + mem_size) > rsv_memsize) {
- XEN_ERR("Total size can't be larger than reserved size.\n");
- return -1;
- }
-
- return 0;
-}
-
-static int __init
-dom0_init(void)
-{
- if (!xen_domain())
- return -ENODEV;
-
- if (rsv_memsize > DOM0_CONFIG_MEMSIZE) {
- XEN_ERR("The reserved memory size cannot be greater than %d\n",
- DOM0_CONFIG_MEMSIZE);
- return -EINVAL;
- }
-
- /* Setup the misc device */
- dom0_dev.miscdev.minor = MISC_DYNAMIC_MINOR;
- dom0_dev.miscdev.name = "dom0_mm";
- dom0_dev.miscdev.fops = &data_fops;
-
- /* register misc char device */
- if (misc_register(&dom0_dev.miscdev) != 0) {
- XEN_ERR("Misc device registration failed\n");
- return -EPERM;
- }
-
- mutex_init(&dom0_dev.data_lock);
- dom0_kobj = kobject_create_and_add("dom0-mm", mm_kobj);
-
- if (!dom0_kobj) {
- XEN_ERR("dom0-mm object creation failed\n");
- misc_deregister(&dom0_dev.miscdev);
- return -ENOMEM;
- }
-
- if (sysfs_create_group(dom0_kobj, &dev_attr_grp)) {
- kobject_put(dom0_kobj);
- misc_deregister(&dom0_dev.miscdev);
- return -EPERM;
- }
-
- if (dom0_memory_reserve(rsv_memsize) < 0) {
- sysfs_remove_group(dom0_kobj, &dev_attr_grp);
- kobject_put(dom0_kobj);
- misc_deregister(&dom0_dev.miscdev);
- return -ENOMEM;
- }
-
- XEN_PRINT("####### DPDK Xen Dom0 module loaded #######\n");
-
- return 0;
-}
-
-static void __exit
-dom0_exit(void)
-{
- if (rsv_mm_info != NULL)
- dom0_memory_free(rsv_memsize);
-
- sysfs_remove_group(dom0_kobj, &dev_attr_grp);
- kobject_put(dom0_kobj);
- misc_deregister(&dom0_dev.miscdev);
-
- XEN_PRINT("####### DPDK Xen Dom0 module unloaded #######\n");
-}
-
-static int
-dom0_open(struct inode *inode, struct file *file)
-{
- file->private_data = NULL;
-
- XEN_PRINT(KERN_INFO "/dev/dom0_mm opened\n");
- return 0;
-}
-
-static int
-dom0_release(struct inode *inode, struct file *file)
-{
- int ret = 0;
- struct dom0_mm_data *mm_data = file->private_data;
-
- if (mm_data == NULL)
- return ret;
-
- mutex_lock(&dom0_dev.data_lock);
- if (--mm_data->refcnt == 0)
- ret = dom0_memory_release(mm_data);
- mutex_unlock(&dom0_dev.data_lock);
-
- file->private_data = NULL;
- XEN_PRINT(KERN_INFO "/dev/dom0_mm closed\n");
- return ret;
-}
-
-static int
-dom0_mmap(struct file *file, struct vm_area_struct *vm)
-{
- int status = 0;
- uint32_t idx = vm->vm_pgoff;
- uint64_t pfn, size = vm->vm_end - vm->vm_start;
- struct dom0_mm_data *mm_data = file->private_data;
-
- if(mm_data == NULL)
- return -EINVAL;
-
- mutex_lock(&dom0_dev.data_lock);
- if (idx >= mm_data->num_memseg) {
- mutex_unlock(&dom0_dev.data_lock);
- return -EINVAL;
- }
-
- if (size > mm_data->seg_info[idx].size){
- mutex_unlock(&dom0_dev.data_lock);
- return -EINVAL;
- }
-
- XEN_PRINT("mmap memseg idx =%d,size = 0x%llx\n", idx, size);
-
- pfn = mm_data->seg_info[idx].pfn;
- mutex_unlock(&dom0_dev.data_lock);
-
- status = remap_pfn_range(vm, vm->vm_start, pfn, size, PAGE_SHARED);
-
- return status;
-}
-static int
-dom0_ioctl(struct file *file,
- unsigned int ioctl_num,
- unsigned long ioctl_param)
-{
- int idx, ret;
- char name[DOM0_NAME_MAX] = {0};
- struct memory_info meminfo;
- struct dom0_mm_data *mm_data = file->private_data;
-
- XEN_PRINT("IOCTL num=0x%0x param=0x%0lx \n", ioctl_num, ioctl_param);
-
- /**
- * Switch according to the ioctl called
- */
- switch _IOC_NR(ioctl_num) {
- case _IOC_NR(RTE_DOM0_IOCTL_PREPARE_MEMSEG):
- ret = copy_from_user(&meminfo, (void *)ioctl_param,
- sizeof(struct memory_info));
- if (ret)
- return -EFAULT;
-
- if (mm_data != NULL) {
- XEN_ERR("Cannot create memory segment for the same"
- " file descriptor\n");
- return -EINVAL;
- }
-
- /* Allocate private data */
- mm_data = vmalloc(sizeof(struct dom0_mm_data));
- if (!mm_data) {
- XEN_ERR("Unable to allocate device private data\n");
- return -ENOMEM;
- }
- memset(mm_data, 0, sizeof(struct dom0_mm_data));
-
- mutex_lock(&dom0_dev.data_lock);
- /* check if we can allocate memory*/
- if (dom0_check_memory(&meminfo) < 0) {
- mutex_unlock(&dom0_dev.data_lock);
- vfree(mm_data);
- return -EINVAL;
- }
-
- /* allocate memory and created memory segments*/
- if (dom0_prepare_memsegs(&meminfo, mm_data) < 0) {
- XEN_ERR("create memory segment fail.\n");
- mutex_unlock(&dom0_dev.data_lock);
- return -EIO;
- }
-
- file->private_data = mm_data;
- mutex_unlock(&dom0_dev.data_lock);
- break;
-
- /* support multiple process in term of memory mapping*/
- case _IOC_NR(RTE_DOM0_IOCTL_ATTACH_TO_MEMSEG):
- ret = copy_from_user(name, (void *)ioctl_param,
- sizeof(char) * DOM0_NAME_MAX);
- if (ret)
- return -EFAULT;
-
- mutex_lock(&dom0_dev.data_lock);
- idx = dom0_find_memdata(name);
- if (idx < 0) {
- mutex_unlock(&dom0_dev.data_lock);
- return -EINVAL;
- }
-
- mm_data = dom0_dev.mm_data[idx];
- mm_data->refcnt++;
- file->private_data = mm_data;
- mutex_unlock(&dom0_dev.data_lock);
- break;
-
- case _IOC_NR(RTE_DOM0_IOCTL_GET_NUM_MEMSEG):
- ret = copy_to_user((void *)ioctl_param, &mm_data->num_memseg,
- sizeof(int));
- if (ret)
- return -EFAULT;
- break;
-
- case _IOC_NR(RTE_DOM0_IOCTL_GET_MEMSEG_INFO):
- ret = copy_to_user((void *)ioctl_param,
- &mm_data->seg_info[0],
- sizeof(struct memseg_info) *
- mm_data->num_memseg);
- if (ret)
- return -EFAULT;
- break;
- default:
- XEN_PRINT("IOCTL default \n");
- break;
- }
-
- return 0;
-}
-
-module_init(dom0_init);
-module_exit(dom0_exit);
-
-module_param(rsv_memsize, uint, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(rsv_memsize, "Xen-dom0 reserved memory size(MB).\n");
diff --git a/pkg/dpdk.spec b/pkg/dpdk.spec
index 95c3335..fd1b5ef 100644
--- a/pkg/dpdk.spec
+++ b/pkg/dpdk.spec
@@ -52,9 +52,6 @@ ExclusiveArch: i686 x86_64 aarch64
%endif
BuildRequires: kernel-devel, kernel-headers, libpcap-devel
-%ifarch i686 x86_64
-BuildRequires: xen-devel
-%endif
BuildRequires: doxygen, python-sphinx, inkscape
BuildRequires: texlive-collection-latexextra
--
2.7.4
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [dpdk-dev] [PATCH 5/6] eal: remove xen dom0 support
2017-08-30 18:10 ` [dpdk-dev] [PATCH 5/6] eal: remove xen dom0 support Jianfeng Tan
@ 2017-09-04 14:43 ` Bruce Richardson
2017-09-04 14:49 ` Bruce Richardson
0 siblings, 1 reply; 21+ messages in thread
From: Bruce Richardson @ 2017-09-04 14:43 UTC (permalink / raw)
To: Jianfeng Tan
Cc: dev, xen-devel, thomas, john.mcnamara, joao.m.martins,
jerin.jacob, shahafs
On Wed, Aug 30, 2017 at 06:10:33PM +0000, Jianfeng Tan wrote:
> We remove xen-specific code in EAL, including the option --xen-dom0,
> memory initialization code, compiling dependency, etc.
>
> Besides, related documents are removed or updated.
>
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> ---
> MAINTAINERS | 7 -
> config/common_base | 5 -
> doc/guides/index.rst | 1 -
> doc/guides/linux_gsg/build_sample_apps.rst | 5 +-
> doc/guides/linux_gsg/sys_reqs.rst | 53 --
> doc/guides/prog_guide/source_org.rst | 1 -
> doc/guides/rel_notes/deprecation.rst | 3 -
> doc/guides/rel_notes/release_17_11.rst | 12 +
> doc/guides/testpmd_app_ug/run_app.rst | 4 -
> doc/guides/xen/img/dpdk_xen_pkt_switch.png | Bin 163842 -> 0 bytes
> doc/guides/xen/img/grant_refs.png | Bin 6405 -> 0 bytes
> doc/guides/xen/img/grant_table.png | Bin 96762 -> 0 bytes
> doc/guides/xen/index.rst | 38 -
> doc/guides/xen/pkt_switch.rst | 470 -------------
> .../bsdapp/eal/include/exec-env/rte_dom0_common.h | 107 ---
> lib/librte_eal/common/eal_common_options.c | 3 -
> lib/librte_eal/common/eal_internal_cfg.h | 1 -
> lib/librte_eal/common/eal_options.h | 2 -
> lib/librte_eal/common/include/rte_memory.h | 66 --
> lib/librte_eal/linuxapp/Makefile | 2 -
> lib/librte_eal/linuxapp/eal/Makefile | 5 +-
> lib/librte_eal/linuxapp/eal/eal.c | 24 -
> lib/librte_eal/linuxapp/eal/eal_memory.c | 56 --
> lib/librte_eal/linuxapp/eal/eal_xen_memory.c | 381 ----------
> .../eal/include/exec-env/rte_dom0_common.h | 108 ---
> lib/librte_eal/linuxapp/igb_uio/igb_uio.c | 54 --
> lib/librte_eal/linuxapp/xen_dom0/Makefile | 53 --
> lib/librte_eal/linuxapp/xen_dom0/compat.h | 15 -
> lib/librte_eal/linuxapp/xen_dom0/dom0_mm_dev.h | 107 ---
> lib/librte_eal/linuxapp/xen_dom0/dom0_mm_misc.c | 780 ---------------------
> pkg/dpdk.spec | 3 -
The xen functions that were removed are still listed in the linux/bsd
version.map files. Not an ABI versioning expert, but I believe they
should be removed as they are no longer present.
Also, I spot a reference to xen still in
doc/guides/contributing/documentation.rst.
/Bruce
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [dpdk-dev] [PATCH 5/6] eal: remove xen dom0 support
2017-09-04 14:43 ` Bruce Richardson
@ 2017-09-04 14:49 ` Bruce Richardson
2017-09-05 3:41 ` Tan, Jianfeng
0 siblings, 1 reply; 21+ messages in thread
From: Bruce Richardson @ 2017-09-04 14:49 UTC (permalink / raw)
To: Jianfeng Tan
Cc: dev, xen-devel, thomas, john.mcnamara, joao.m.martins,
jerin.jacob, shahafs
On Mon, Sep 04, 2017 at 03:43:02PM +0100, Bruce Richardson wrote:
> On Wed, Aug 30, 2017 at 06:10:33PM +0000, Jianfeng Tan wrote:
> > We remove xen-specific code in EAL, including the option --xen-dom0,
> > memory initialization code, compiling dependency, etc.
> >
> > Besides, related documents are removed or updated.
> >
> > Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> > ---
> > MAINTAINERS | 7 -
> > config/common_base | 5 -
> > doc/guides/index.rst | 1 -
> > doc/guides/linux_gsg/build_sample_apps.rst | 5 +-
> > doc/guides/linux_gsg/sys_reqs.rst | 53 --
> > doc/guides/prog_guide/source_org.rst | 1 -
> > doc/guides/rel_notes/deprecation.rst | 3 -
> > doc/guides/rel_notes/release_17_11.rst | 12 +
> > doc/guides/testpmd_app_ug/run_app.rst | 4 -
> > doc/guides/xen/img/dpdk_xen_pkt_switch.png | Bin 163842 -> 0 bytes
> > doc/guides/xen/img/grant_refs.png | Bin 6405 -> 0 bytes
> > doc/guides/xen/img/grant_table.png | Bin 96762 -> 0 bytes
> > doc/guides/xen/index.rst | 38 -
> > doc/guides/xen/pkt_switch.rst | 470 -------------
> > .../bsdapp/eal/include/exec-env/rte_dom0_common.h | 107 ---
> > lib/librte_eal/common/eal_common_options.c | 3 -
> > lib/librte_eal/common/eal_internal_cfg.h | 1 -
> > lib/librte_eal/common/eal_options.h | 2 -
> > lib/librte_eal/common/include/rte_memory.h | 66 --
> > lib/librte_eal/linuxapp/Makefile | 2 -
> > lib/librte_eal/linuxapp/eal/Makefile | 5 +-
> > lib/librte_eal/linuxapp/eal/eal.c | 24 -
> > lib/librte_eal/linuxapp/eal/eal_memory.c | 56 --
> > lib/librte_eal/linuxapp/eal/eal_xen_memory.c | 381 ----------
> > .../eal/include/exec-env/rte_dom0_common.h | 108 ---
> > lib/librte_eal/linuxapp/igb_uio/igb_uio.c | 54 --
> > lib/librte_eal/linuxapp/xen_dom0/Makefile | 53 --
> > lib/librte_eal/linuxapp/xen_dom0/compat.h | 15 -
> > lib/librte_eal/linuxapp/xen_dom0/dom0_mm_dev.h | 107 ---
> > lib/librte_eal/linuxapp/xen_dom0/dom0_mm_misc.c | 780 ---------------------
> > pkg/dpdk.spec | 3 -
>
> The xen functions that were removed are still listed in the linux/bsd
> version.map files. Not an ABI versioning expert, but I believe they
> should be removed as they are no longer present.
>
Reading the contributors guide section on ABI, specifically
http://dpdk.org/doc/guides/contributing/versioning.html#deprecating-an-entire-abi-version
it seems like we should collapse down the versions to a single one
following the function removal, and also increment the whole library so
version.
/Bruce
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [dpdk-dev] [PATCH 5/6] eal: remove xen dom0 support
2017-09-04 14:49 ` Bruce Richardson
@ 2017-09-05 3:41 ` Tan, Jianfeng
2017-09-05 7:31 ` Thomas Monjalon
0 siblings, 1 reply; 21+ messages in thread
From: Tan, Jianfeng @ 2017-09-05 3:41 UTC (permalink / raw)
To: Richardson, Bruce
Cc: dev, xen-devel, thomas, Mcnamara, John, joao.m.martins,
jerin.jacob, shahafs
> -----Original Message-----
> From: Richardson, Bruce
> Sent: Monday, September 4, 2017 10:49 PM
> To: Tan, Jianfeng
> Cc: dev@dpdk.org; xen-devel@lists.xenproject.org; thomas@monjalon.net;
> Mcnamara, John; joao.m.martins@oracle.com;
> jerin.jacob@caviumnetworks.com; shahafs@mellanox.com
> Subject: Re: [dpdk-dev] [PATCH 5/6] eal: remove xen dom0 support
>
> On Mon, Sep 04, 2017 at 03:43:02PM +0100, Bruce Richardson wrote:
> > On Wed, Aug 30, 2017 at 06:10:33PM +0000, Jianfeng Tan wrote:
> > > We remove xen-specific code in EAL, including the option --xen-dom0,
> > > memory initialization code, compiling dependency, etc.
> > >
> > > Besides, related documents are removed or updated.
> > >
> > > Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> > > ---
> > > MAINTAINERS | 7 -
> > > config/common_base | 5 -
> > > doc/guides/index.rst | 1 -
> > > doc/guides/linux_gsg/build_sample_apps.rst | 5 +-
> > > doc/guides/linux_gsg/sys_reqs.rst | 53 --
> > > doc/guides/prog_guide/source_org.rst | 1 -
> > > doc/guides/rel_notes/deprecation.rst | 3 -
> > > doc/guides/rel_notes/release_17_11.rst | 12 +
> > > doc/guides/testpmd_app_ug/run_app.rst | 4 -
> > > doc/guides/xen/img/dpdk_xen_pkt_switch.png | Bin 163842 -> 0
> bytes
> > > doc/guides/xen/img/grant_refs.png | Bin 6405 -> 0 bytes
> > > doc/guides/xen/img/grant_table.png | Bin 96762 -> 0 bytes
> > > doc/guides/xen/index.rst | 38 -
> > > doc/guides/xen/pkt_switch.rst | 470 -------------
> > > .../bsdapp/eal/include/exec-env/rte_dom0_common.h | 107 ---
> > > lib/librte_eal/common/eal_common_options.c | 3 -
> > > lib/librte_eal/common/eal_internal_cfg.h | 1 -
> > > lib/librte_eal/common/eal_options.h | 2 -
> > > lib/librte_eal/common/include/rte_memory.h | 66 --
> > > lib/librte_eal/linuxapp/Makefile | 2 -
> > > lib/librte_eal/linuxapp/eal/Makefile | 5 +-
> > > lib/librte_eal/linuxapp/eal/eal.c | 24 -
> > > lib/librte_eal/linuxapp/eal/eal_memory.c | 56 --
> > > lib/librte_eal/linuxapp/eal/eal_xen_memory.c | 381 ----------
> > > .../eal/include/exec-env/rte_dom0_common.h | 108 ---
> > > lib/librte_eal/linuxapp/igb_uio/igb_uio.c | 54 --
> > > lib/librte_eal/linuxapp/xen_dom0/Makefile | 53 --
> > > lib/librte_eal/linuxapp/xen_dom0/compat.h | 15 -
> > > lib/librte_eal/linuxapp/xen_dom0/dom0_mm_dev.h | 107 ---
> > > lib/librte_eal/linuxapp/xen_dom0/dom0_mm_misc.c | 780 --------------
> -------
> > > pkg/dpdk.spec | 3 -
> >
> > The xen functions that were removed are still listed in the linux/bsd
> > version.map files. Not an ABI versioning expert, but I believe they
> > should be removed as they are no longer present.
> >
> Reading the contributors guide section on ABI, specifically
> http://dpdk.org/doc/guides/contributing/versioning.html#deprecating-an-
> entire-abi-version
> it seems like we should collapse down the versions to a single one
> following the function removal, and also increment the whole library so
> version.
So for lib/librte_eal/linuxapp/eal/rte_eal_version.map, we should change it in below way?
DPDK_2.1 {
{APIs in DPDK_2.0 except xen APIs}
...
};
DPDK_16.04 {
{APIs in DPDK_2.1 except xen APIs}
...
} DPDK_2.1;
DPDK_16.07 {
...
} DPDK_16.04;
...
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [dpdk-dev] [PATCH 5/6] eal: remove xen dom0 support
2017-09-05 3:41 ` Tan, Jianfeng
@ 2017-09-05 7:31 ` Thomas Monjalon
2017-09-05 8:07 ` Tan, Jianfeng
0 siblings, 1 reply; 21+ messages in thread
From: Thomas Monjalon @ 2017-09-05 7:31 UTC (permalink / raw)
To: Tan, Jianfeng
Cc: Richardson, Bruce, dev, xen-devel, Mcnamara, John,
joao.m.martins, jerin.jacob, shahafs
05/09/2017 05:41, Tan, Jianfeng:
> From: Richardson, Bruce
> >
> > Reading the contributors guide section on ABI, specifically
> > http://dpdk.org/doc/guides/contributing/versioning.html#deprecating-an-
> > entire-abi-version
> > it seems like we should collapse down the versions to a single one
> > following the function removal, and also increment the whole library so
> > version.
>
> So for lib/librte_eal/linuxapp/eal/rte_eal_version.map, we should change it in below way?
>
> DPDK_2.1 {
> {APIs in DPDK_2.0 except xen APIs}
> ...
> };
>
> DPDK_16.04 {
> {APIs in DPDK_2.1 except xen APIs}
> ...
> } DPDK_2.1;
No, you don't need to collapse. You can just remove Xen functions.
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [dpdk-dev] [PATCH 5/6] eal: remove xen dom0 support
2017-09-05 7:31 ` Thomas Monjalon
@ 2017-09-05 8:07 ` Tan, Jianfeng
2017-09-05 8:34 ` Thomas Monjalon
0 siblings, 1 reply; 21+ messages in thread
From: Tan, Jianfeng @ 2017-09-05 8:07 UTC (permalink / raw)
To: Thomas Monjalon
Cc: Richardson, Bruce, dev, xen-devel, Mcnamara, John,
joao.m.martins, jerin.jacob, shahafs
> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas@monjalon.net]
> Sent: Tuesday, September 5, 2017 3:31 PM
> To: Tan, Jianfeng
> Cc: Richardson, Bruce; dev@dpdk.org; xen-devel@lists.xenproject.org;
> Mcnamara, John; joao.m.martins@oracle.com;
> jerin.jacob@caviumnetworks.com; shahafs@mellanox.com
> Subject: Re: [dpdk-dev] [PATCH 5/6] eal: remove xen dom0 support
>
> 05/09/2017 05:41, Tan, Jianfeng:
> > From: Richardson, Bruce
> > >
> > > Reading the contributors guide section on ABI, specifically
> > > http://dpdk.org/doc/guides/contributing/versioning.html#deprecating-
> an-
> > > entire-abi-version
> > > it seems like we should collapse down the versions to a single one
> > > following the function removal, and also increment the whole library so
> > > version.
> >
> > So for lib/librte_eal/linuxapp/eal/rte_eal_version.map, we should change
> it in below way?
> >
> > DPDK_2.1 {
> > {APIs in DPDK_2.0 except xen APIs}
> > ...
> > };
> >
> > DPDK_16.04 {
> > {APIs in DPDK_2.1 except xen APIs}
> > ...
> > } DPDK_2.1;
>
> No, you don't need to collapse. You can just remove Xen functions.
Thanks.
Besides, two more things:
1. Shall we increase the so version?
2. This patch is about 8K lines long, do we need to split?
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [dpdk-dev] [PATCH 5/6] eal: remove xen dom0 support
2017-09-05 8:07 ` Tan, Jianfeng
@ 2017-09-05 8:34 ` Thomas Monjalon
0 siblings, 0 replies; 21+ messages in thread
From: Thomas Monjalon @ 2017-09-05 8:34 UTC (permalink / raw)
To: Tan, Jianfeng
Cc: Richardson, Bruce, dev, xen-devel, Mcnamara, John,
joao.m.martins, jerin.jacob, shahafs
05/09/2017 10:07, Tan, Jianfeng:
> From: Thomas Monjalon [mailto:thomas@monjalon.net]
> > 05/09/2017 05:41, Tan, Jianfeng:
> > > From: Richardson, Bruce
> > > >
> > > > Reading the contributors guide section on ABI, specifically
> > > > http://dpdk.org/doc/guides/contributing/versioning.html#deprecating-
> > an-
> > > > entire-abi-version
> > > > it seems like we should collapse down the versions to a single one
> > > > following the function removal, and also increment the whole library so
> > > > version.
> > >
> > > So for lib/librte_eal/linuxapp/eal/rte_eal_version.map, we should change
> > it in below way?
> > >
> > > DPDK_2.1 {
> > > {APIs in DPDK_2.0 except xen APIs}
> > > ...
> > > };
> > >
> > > DPDK_16.04 {
> > > {APIs in DPDK_2.1 except xen APIs}
> > > ...
> > > } DPDK_2.1;
> >
> > No, you don't need to collapse. You can just remove Xen functions.
>
> Thanks.
>
> Besides, two more things:
> 1. Shall we increase the so version?
Yes
> 2. This patch is about 8K lines long, do we need to split?
I do not know how you can split a removal.
If you have ideas, feel free.
^ permalink raw reply [flat|nested] 21+ messages in thread
* [dpdk-dev] [PATCH 6/6] eal: remove API rte_mem_phy2mch
2017-08-30 18:10 [dpdk-dev] [PATCH 0/6] remove xen dom0 support in DPDK Jianfeng Tan
` (4 preceding siblings ...)
2017-08-30 18:10 ` [dpdk-dev] [PATCH 5/6] eal: remove xen dom0 support Jianfeng Tan
@ 2017-08-30 18:10 ` Jianfeng Tan
2017-09-04 14:52 ` Bruce Richardson
2017-08-31 8:44 ` [dpdk-dev] [Xen-devel] [PATCH 0/6] remove xen dom0 support in DPDK Wei Liu
6 siblings, 1 reply; 21+ messages in thread
From: Jianfeng Tan @ 2017-08-30 18:10 UTC (permalink / raw)
To: dev
Cc: xen-devel, thomas, john.mcnamara, oao.m.martins, jerin.jacob,
shahafs, Jianfeng Tan
Previously, to get MFN address in dom0, this API is a wrapper to
obtain the "physical address".
As we removed xen dom0 support, this API is not necessary.
Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
doc/guides/rel_notes/release_17_11.rst | 2 ++
drivers/net/e1000/em_rxtx.c | 4 ++--
drivers/net/e1000/igb_rxtx.c | 4 ++--
drivers/net/fm10k/fm10k_ethdev.c | 4 ++--
drivers/net/i40e/i40e_ethdev.c | 2 +-
drivers/net/i40e/i40e_fdir.c | 2 +-
drivers/net/i40e/i40e_rxtx.c | 8 ++++----
drivers/net/ixgbe/ixgbe_rxtx.c | 4 ++--
drivers/net/sfc/sfc.c | 2 +-
lib/librte_eal/common/include/rte_memory.h | 5 -----
lib/librte_mempool/rte_mempool.c | 3 ---
11 files changed, 17 insertions(+), 23 deletions(-)
diff --git a/doc/guides/rel_notes/release_17_11.rst b/doc/guides/rel_notes/release_17_11.rst
index d211084..06c334b 100644
--- a/doc/guides/rel_notes/release_17_11.rst
+++ b/doc/guides/rel_notes/release_17_11.rst
@@ -110,6 +110,8 @@ API Changes
Also, make sure to start the actual text at the margin.
=========================================================
+ * ``rte_mem_phy2mch`` was used in xen dom0 to obtain the physical address;
+ remove this API as xen dom0 support was removed.
ABI Changes
-----------
diff --git a/drivers/net/e1000/em_rxtx.c b/drivers/net/e1000/em_rxtx.c
index 31819c5..a0f63a7 100644
--- a/drivers/net/e1000/em_rxtx.c
+++ b/drivers/net/e1000/em_rxtx.c
@@ -1289,7 +1289,7 @@ eth_em_tx_queue_setup(struct rte_eth_dev *dev,
txq->port_id = dev->data->port_id;
txq->tdt_reg_addr = E1000_PCI_REG_ADDR(hw, E1000_TDT(queue_idx));
- txq->tx_ring_phys_addr = rte_mem_phy2mch(tz->memseg_id, tz->phys_addr);
+ txq->tx_ring_phys_addr = tz->phys_addr;
txq->tx_ring = (struct e1000_data_desc *) tz->addr;
PMD_INIT_LOG(DEBUG, "sw_ring=%p hw_ring=%p dma_addr=0x%"PRIx64,
@@ -1416,7 +1416,7 @@ eth_em_rx_queue_setup(struct rte_eth_dev *dev,
rxq->rdt_reg_addr = E1000_PCI_REG_ADDR(hw, E1000_RDT(queue_idx));
rxq->rdh_reg_addr = E1000_PCI_REG_ADDR(hw, E1000_RDH(queue_idx));
- rxq->rx_ring_phys_addr = rte_mem_phy2mch(rz->memseg_id, rz->phys_addr);
+ rxq->rx_ring_phys_addr = rz->phys_addr;
rxq->rx_ring = (struct e1000_rx_desc *) rz->addr;
PMD_INIT_LOG(DEBUG, "sw_ring=%p hw_ring=%p dma_addr=0x%"PRIx64,
diff --git a/drivers/net/e1000/igb_rxtx.c b/drivers/net/e1000/igb_rxtx.c
index 1c80a2a..0fccb5d 100644
--- a/drivers/net/e1000/igb_rxtx.c
+++ b/drivers/net/e1000/igb_rxtx.c
@@ -1530,7 +1530,7 @@ eth_igb_tx_queue_setup(struct rte_eth_dev *dev,
txq->port_id = dev->data->port_id;
txq->tdt_reg_addr = E1000_PCI_REG_ADDR(hw, E1000_TDT(txq->reg_idx));
- txq->tx_ring_phys_addr = rte_mem_phy2mch(tz->memseg_id, tz->phys_addr);
+ txq->tx_ring_phys_addr = tz->phys_addr;
txq->tx_ring = (union e1000_adv_tx_desc *) tz->addr;
/* Allocate software ring */
@@ -1667,7 +1667,7 @@ eth_igb_rx_queue_setup(struct rte_eth_dev *dev,
}
rxq->rdt_reg_addr = E1000_PCI_REG_ADDR(hw, E1000_RDT(rxq->reg_idx));
rxq->rdh_reg_addr = E1000_PCI_REG_ADDR(hw, E1000_RDH(rxq->reg_idx));
- rxq->rx_ring_phys_addr = rte_mem_phy2mch(rz->memseg_id, rz->phys_addr);
+ rxq->rx_ring_phys_addr = rz->phys_addr;
rxq->rx_ring = (union e1000_adv_rx_desc *) rz->addr;
/* Allocate software ring. */
diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index e60d3a3..15ea2a5 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -1887,7 +1887,7 @@ fm10k_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_id,
return -ENOMEM;
}
q->hw_ring = mz->addr;
- q->hw_ring_phys_addr = rte_mem_phy2mch(mz->memseg_id, mz->phys_addr);
+ q->hw_ring_phys_addr = mz->phys_addr;
/* Check if number of descs satisfied Vector requirement */
if (!rte_is_power_of_2(nb_desc)) {
@@ -2047,7 +2047,7 @@ fm10k_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_id,
return -ENOMEM;
}
q->hw_ring = mz->addr;
- q->hw_ring_phys_addr = rte_mem_phy2mch(mz->memseg_id, mz->phys_addr);
+ q->hw_ring_phys_addr = mz->phys_addr;
/*
* allocate memory for the RS bit tracker. Enough slots to hold the
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 5f26e24..dc5458d 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -3741,7 +3741,7 @@ i40e_allocate_dma_mem_d(__attribute__((unused)) struct i40e_hw *hw,
mem->size = size;
mem->va = mz->addr;
- mem->pa = rte_mem_phy2mch(mz->memseg_id, mz->phys_addr);
+ mem->pa = mz->phys_addr;
mem->zone = (const void *)mz;
PMD_DRV_LOG(DEBUG,
"memzone %s allocated with physical address: %"PRIu64,
diff --git a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c
index 8013add..70dae92 100644
--- a/drivers/net/i40e/i40e_fdir.c
+++ b/drivers/net/i40e/i40e_fdir.c
@@ -249,7 +249,7 @@ i40e_fdir_setup(struct i40e_pf *pf)
goto fail_mem;
}
pf->fdir.prg_pkt = mz->addr;
- pf->fdir.dma_addr = rte_mem_phy2mch(mz->memseg_id, mz->phys_addr);
+ pf->fdir.dma_addr = mz->phys_addr;
pf->fdir.match_counter_index = I40E_COUNTER_INDEX_FDIR(hw->pf_id);
PMD_DRV_LOG(INFO, "FDIR setup successfully, with programming queue %u.",
diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c
index f571e79..344c11c 100644
--- a/drivers/net/i40e/i40e_rxtx.c
+++ b/drivers/net/i40e/i40e_rxtx.c
@@ -1822,7 +1822,7 @@ i40e_dev_rx_queue_setup(struct rte_eth_dev *dev,
/* Zero all the descriptors in the ring. */
memset(rz->addr, 0, ring_size);
- rxq->rx_ring_phys_addr = rte_mem_phy2mch(rz->memseg_id, rz->phys_addr);
+ rxq->rx_ring_phys_addr = rz->phys_addr;
rxq->rx_ring = (union i40e_rx_desc *)rz->addr;
len = (uint16_t)(nb_desc + RTE_PMD_I40E_RX_MAX_BURST);
@@ -2159,7 +2159,7 @@ i40e_dev_tx_queue_setup(struct rte_eth_dev *dev,
txq->vsi = vsi;
txq->tx_deferred_start = tx_conf->tx_deferred_start;
- txq->tx_ring_phys_addr = rte_mem_phy2mch(tz->memseg_id, tz->phys_addr);
+ txq->tx_ring_phys_addr = tz->phys_addr;
txq->tx_ring = (struct i40e_tx_desc *)tz->addr;
/* Allocate software ring */
@@ -2671,7 +2671,7 @@ i40e_fdir_setup_tx_resources(struct i40e_pf *pf)
txq->reg_idx = pf->fdir.fdir_vsi->base_queue;
txq->vsi = pf->fdir.fdir_vsi;
- txq->tx_ring_phys_addr = rte_mem_phy2mch(tz->memseg_id, tz->phys_addr);
+ txq->tx_ring_phys_addr = tz->phys_addr;
txq->tx_ring = (struct i40e_tx_desc *)tz->addr;
/*
* don't need to allocate software ring and reset for the fdir
@@ -2727,7 +2727,7 @@ i40e_fdir_setup_rx_resources(struct i40e_pf *pf)
rxq->reg_idx = pf->fdir.fdir_vsi->base_queue;
rxq->vsi = pf->fdir.fdir_vsi;
- rxq->rx_ring_phys_addr = rte_mem_phy2mch(rz->memseg_id, rz->phys_addr);
+ rxq->rx_ring_phys_addr = rz->phys_addr;
rxq->rx_ring = (union i40e_rx_desc *)rz->addr;
/*
diff --git a/drivers/net/ixgbe/ixgbe_rxtx.c b/drivers/net/ixgbe/ixgbe_rxtx.c
index 64bff25..ac1415b 100644
--- a/drivers/net/ixgbe/ixgbe_rxtx.c
+++ b/drivers/net/ixgbe/ixgbe_rxtx.c
@@ -2548,7 +2548,7 @@ ixgbe_dev_tx_queue_setup(struct rte_eth_dev *dev,
else
txq->tdt_reg_addr = IXGBE_PCI_REG_ADDR(hw, IXGBE_TDT(txq->reg_idx));
- txq->tx_ring_phys_addr = rte_mem_phy2mch(tz->memseg_id, tz->phys_addr);
+ txq->tx_ring_phys_addr = tz->phys_addr;
txq->tx_ring = (union ixgbe_adv_tx_desc *) tz->addr;
/* Allocate software ring */
@@ -2850,7 +2850,7 @@ ixgbe_dev_rx_queue_setup(struct rte_eth_dev *dev,
IXGBE_PCI_REG_ADDR(hw, IXGBE_RDH(rxq->reg_idx));
}
- rxq->rx_ring_phys_addr = rte_mem_phy2mch(rz->memseg_id, rz->phys_addr);
+ rxq->rx_ring_phys_addr = rz->phys_addr;
rxq->rx_ring = (union ixgbe_adv_rx_desc *) rz->addr;
/*
diff --git a/drivers/net/sfc/sfc.c b/drivers/net/sfc/sfc.c
index 6cecfc0..f9e9916 100644
--- a/drivers/net/sfc/sfc.c
+++ b/drivers/net/sfc/sfc.c
@@ -61,7 +61,7 @@ sfc_dma_alloc(const struct sfc_adapter *sa, const char *name, uint16_t id,
return ENOMEM;
}
- esmp->esm_addr = rte_mem_phy2mch(mz->memseg_id, mz->phys_addr);
+ esmp->esm_addr = mz->phys_addr;
if (esmp->esm_addr == RTE_BAD_PHYS_ADDR) {
(void)rte_memzone_free(mz);
return EFAULT;
diff --git a/lib/librte_eal/common/include/rte_memory.h b/lib/librte_eal/common/include/rte_memory.h
index d8543c0..c545963 100644
--- a/lib/librte_eal/common/include/rte_memory.h
+++ b/lib/librte_eal/common/include/rte_memory.h
@@ -187,11 +187,6 @@ unsigned rte_memory_get_nchannel(void);
*/
unsigned rte_memory_get_nrank(void);
-static inline phys_addr_t
-rte_mem_phy2mch(int32_t memseg_id __rte_unused, const phys_addr_t phy_addr)
-{
- return phy_addr;
-}
#ifdef __cplusplus
}
#endif
diff --git a/lib/librte_mempool/rte_mempool.c b/lib/librte_mempool/rte_mempool.c
index 6d726ae..892a1ac 100644
--- a/lib/librte_mempool/rte_mempool.c
+++ b/lib/librte_mempool/rte_mempool.c
@@ -473,8 +473,6 @@ rte_mempool_populate_virt(struct rte_mempool *mp, char *addr,
mp->populated_size < mp->size; off += phys_len) {
paddr = rte_mem_virt2phy(addr + off);
- /* required for xen_dom0 to get the machine address */
- paddr = rte_mem_phy2mch(-1, paddr);
if (paddr == RTE_BAD_PHYS_ADDR && rte_eal_has_hugepages()) {
ret = -EINVAL;
@@ -486,7 +484,6 @@ rte_mempool_populate_virt(struct rte_mempool *mp, char *addr,
phys_addr_t paddr_tmp;
paddr_tmp = rte_mem_virt2phy(addr + off + phys_len);
- paddr_tmp = rte_mem_phy2mch(-1, paddr_tmp);
if (paddr_tmp != paddr + phys_len)
break;
--
2.7.4
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [dpdk-dev] [PATCH 6/6] eal: remove API rte_mem_phy2mch
2017-08-30 18:10 ` [dpdk-dev] [PATCH 6/6] eal: remove API rte_mem_phy2mch Jianfeng Tan
@ 2017-09-04 14:52 ` Bruce Richardson
0 siblings, 0 replies; 21+ messages in thread
From: Bruce Richardson @ 2017-09-04 14:52 UTC (permalink / raw)
To: Jianfeng Tan
Cc: dev, xen-devel, thomas, john.mcnamara, joao.m.martins,
jerin.jacob, shahafs
On Wed, Aug 30, 2017 at 06:10:34PM +0000, Jianfeng Tan wrote:
> Previously, to get MFN address in dom0, this API is a wrapper to
> obtain the "physical address".
>
> As we removed xen dom0 support, this API is not necessary.
>
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [dpdk-dev] [Xen-devel] [PATCH 0/6] remove xen dom0 support in DPDK
2017-08-30 18:10 [dpdk-dev] [PATCH 0/6] remove xen dom0 support in DPDK Jianfeng Tan
` (5 preceding siblings ...)
2017-08-30 18:10 ` [dpdk-dev] [PATCH 6/6] eal: remove API rte_mem_phy2mch Jianfeng Tan
@ 2017-08-31 8:44 ` Wei Liu
6 siblings, 0 replies; 21+ messages in thread
From: Wei Liu @ 2017-08-31 8:44 UTC (permalink / raw)
To: Jianfeng Tan
Cc: dev, jerin.jacob, shahafs, john.mcnamara, thomas, xen-devel,
Wei Liu, joao.m.martins
CC Joao's correct address
On Wed, Aug 30, 2017 at 06:10:28PM +0000, Jianfeng Tan wrote:
> Following the calls on the mailing list:
> http://dpdk.org/ml/archives/dev/2017-June/068151.html
> The Technical Board decided to drop Xen dom0 support from EAL:
> http://dpdk.org/ml/archives/dev/2017-June/068615.html
>
> This series remove xen dom0 support in DPDK, as well as xenvirt PMD and
> vhost_xen example.
>
> What are effected?
>
> After these patches, users cannot run DPDK applications inside xen dom0.
>
> What are not effected?
>
> Users can still run DPDK applications inside xen domU on pass-throughed
> physical devices and virtio devices; on the host, users still can run
> DPDK applications same as before.
>
> Jianfeng Tan (6):
> example/vhost_xen: remove
> net/xenvirt: remove
> xen: remove xen dependency in app, examples, test
> xen: remove xen dependency in drivers, ether, mempool
> eal: remove xen dom0 support
> eal: remove API rte_mem_phy2mch
>
> MAINTAINERS | 10 -
> app/test-pmd/Makefile | 4 -
> app/test-pmd/testpmd.c | 14 +-
> config/common_base | 10 -
> config/defconfig_arm-armv7a-linuxapp-gcc | 1 -
> doc/guides/index.rst | 1 -
> doc/guides/linux_gsg/build_sample_apps.rst | 5 +-
> doc/guides/linux_gsg/sys_reqs.rst | 53 -
> doc/guides/nics/features/xenvirt.ini | 6 -
> doc/guides/prog_guide/source_org.rst | 1 -
> doc/guides/rel_notes/deprecation.rst | 3 -
> doc/guides/rel_notes/release_17_11.rst | 14 +
> doc/guides/testpmd_app_ug/run_app.rst | 4 -
> doc/guides/xen/img/dpdk_xen_pkt_switch.png | Bin 163842 -> 0 bytes
> doc/guides/xen/img/grant_refs.png | Bin 6405 -> 0 bytes
> doc/guides/xen/img/grant_table.png | Bin 96762 -> 0 bytes
> doc/guides/xen/index.rst | 38 -
> doc/guides/xen/pkt_switch.rst | 470 ------
> drivers/crypto/qat/qat_qp.c | 7 +-
> drivers/net/Makefile | 2 -
> drivers/net/e1000/em_rxtx.c | 4 +-
> drivers/net/e1000/igb_rxtx.c | 4 +-
> drivers/net/fm10k/fm10k_ethdev.c | 4 +-
> drivers/net/i40e/i40e_ethdev.c | 2 +-
> drivers/net/i40e/i40e_fdir.c | 2 +-
> drivers/net/i40e/i40e_rxtx.c | 16 +-
> drivers/net/ixgbe/ixgbe_rxtx.c | 4 +-
> drivers/net/sfc/sfc.c | 2 +-
> drivers/net/xenvirt/Makefile | 57 -
> drivers/net/xenvirt/rte_eth_xenvirt.c | 766 ----------
> drivers/net/xenvirt/rte_eth_xenvirt.h | 61 -
> drivers/net/xenvirt/rte_eth_xenvirt_version.map | 7 -
> drivers/net/xenvirt/rte_mempool_gntalloc.c | 295 ----
> drivers/net/xenvirt/rte_xen_lib.c | 454 ------
> drivers/net/xenvirt/rte_xen_lib.h | 116 --
> drivers/net/xenvirt/virtio_logs.h | 70 -
> drivers/net/xenvirt/virtqueue.h | 273 ----
> examples/Makefile | 1 -
> examples/ip_pipeline/app.h | 4 -
> examples/ip_pipeline/config_parse.c | 19 -
> examples/ip_pipeline/init.c | 5 -
> examples/kni/main.c | 3 -
> examples/vhost_xen/Makefile | 52 -
> examples/vhost_xen/main.c | 1522 --------------------
> examples/vhost_xen/main.h | 66 -
> examples/vhost_xen/vhost_monitor.c | 595 --------
> examples/vhost_xen/virtio-net.h | 113 --
> examples/vhost_xen/xen_vhost.h | 148 --
> examples/vhost_xen/xenstore_parse.c | 775 ----------
> .../bsdapp/eal/include/exec-env/rte_dom0_common.h | 107 --
> lib/librte_eal/common/eal_common_options.c | 3 -
> lib/librte_eal/common/eal_internal_cfg.h | 1 -
> lib/librte_eal/common/eal_options.h | 2 -
> lib/librte_eal/common/include/rte_memory.h | 71 -
> lib/librte_eal/linuxapp/Makefile | 2 -
> lib/librte_eal/linuxapp/eal/Makefile | 5 +-
> lib/librte_eal/linuxapp/eal/eal.c | 24 -
> lib/librte_eal/linuxapp/eal/eal_memory.c | 56 -
> lib/librte_eal/linuxapp/eal/eal_xen_memory.c | 381 -----
> .../eal/include/exec-env/rte_dom0_common.h | 108 --
> lib/librte_eal/linuxapp/igb_uio/igb_uio.c | 54 -
> lib/librte_eal/linuxapp/xen_dom0/Makefile | 53 -
> lib/librte_eal/linuxapp/xen_dom0/compat.h | 15 -
> lib/librte_eal/linuxapp/xen_dom0/dom0_mm_dev.h | 107 --
> lib/librte_eal/linuxapp/xen_dom0/dom0_mm_misc.c | 780 ----------
> lib/librte_ether/rte_ethdev.c | 7 +-
> lib/librte_mempool/rte_mempool.c | 11 +-
> mk/rte.app.mk | 1 -
> pkg/dpdk.spec | 6 -
> test/test/process.h | 10 -
> test/test/test.c | 4 -
> test/test/test_eal_flags.c | 81 --
> 72 files changed, 38 insertions(+), 7934 deletions(-)
> delete mode 100644 doc/guides/nics/features/xenvirt.ini
> delete mode 100644 doc/guides/xen/img/dpdk_xen_pkt_switch.png
> delete mode 100644 doc/guides/xen/img/grant_refs.png
> delete mode 100644 doc/guides/xen/img/grant_table.png
> delete mode 100644 doc/guides/xen/index.rst
> delete mode 100644 doc/guides/xen/pkt_switch.rst
> delete mode 100644 drivers/net/xenvirt/Makefile
> delete mode 100644 drivers/net/xenvirt/rte_eth_xenvirt.c
> delete mode 100644 drivers/net/xenvirt/rte_eth_xenvirt.h
> delete mode 100644 drivers/net/xenvirt/rte_eth_xenvirt_version.map
> delete mode 100644 drivers/net/xenvirt/rte_mempool_gntalloc.c
> delete mode 100644 drivers/net/xenvirt/rte_xen_lib.c
> delete mode 100644 drivers/net/xenvirt/rte_xen_lib.h
> delete mode 100644 drivers/net/xenvirt/virtio_logs.h
> delete mode 100644 drivers/net/xenvirt/virtqueue.h
> delete mode 100644 examples/vhost_xen/Makefile
> delete mode 100644 examples/vhost_xen/main.c
> delete mode 100644 examples/vhost_xen/main.h
> delete mode 100644 examples/vhost_xen/vhost_monitor.c
> delete mode 100644 examples/vhost_xen/virtio-net.h
> delete mode 100644 examples/vhost_xen/xen_vhost.h
> delete mode 100644 examples/vhost_xen/xenstore_parse.c
> delete mode 100644 lib/librte_eal/bsdapp/eal/include/exec-env/rte_dom0_common.h
> delete mode 100644 lib/librte_eal/linuxapp/eal/eal_xen_memory.c
> delete mode 100644 lib/librte_eal/linuxapp/eal/include/exec-env/rte_dom0_common.h
> delete mode 100644 lib/librte_eal/linuxapp/xen_dom0/Makefile
> delete mode 100644 lib/librte_eal/linuxapp/xen_dom0/compat.h
> delete mode 100644 lib/librte_eal/linuxapp/xen_dom0/dom0_mm_dev.h
> delete mode 100644 lib/librte_eal/linuxapp/xen_dom0/dom0_mm_misc.c
>
> --
> 2.7.4
>
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> https://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 21+ messages in thread