From patchwork Mon Jul 4 10:12:47 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ciara Loftus X-Patchwork-Id: 644065 X-Patchwork-Delegate: diproiettod@vmware.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from archives.nicira.com (archives.nicira.com [96.126.127.54]) by ozlabs.org (Postfix) with ESMTP id 3rjjWb6tvqz9sdn for ; Mon, 4 Jul 2016 20:12:59 +1000 (AEST) Received: from archives.nicira.com (localhost [127.0.0.1]) by archives.nicira.com (Postfix) with ESMTP id 28C0110CBA; Mon, 4 Jul 2016 03:12:56 -0700 (PDT) X-Original-To: dev@openvswitch.org Delivered-To: dev@openvswitch.org Received: from mx3v3.cudamail.com (mx3.cudamail.com [64.34.241.5]) by archives.nicira.com (Postfix) with ESMTPS id 49C4B10C74 for ; Mon, 4 Jul 2016 03:12:54 -0700 (PDT) Received: from bar6.cudamail.com (localhost [127.0.0.1]) by mx3v3.cudamail.com (Postfix) with ESMTPS id D58AE162545 for ; Mon, 4 Jul 2016 04:12:53 -0600 (MDT) X-ASG-Debug-ID: 1467627172-0b32373f7d2b12d0001-byXFYA Received: from mx3-pf2.cudamail.com ([192.168.14.1]) by bar6.cudamail.com with ESMTP id B24OJ2Am9CVLRHGC (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Mon, 04 Jul 2016 04:12:52 -0600 (MDT) X-Barracuda-Envelope-From: cloftus@ecsmtp.ir.intel.com X-Barracuda-RBL-Trusted-Forwarder: 192.168.14.1 Received: from unknown (HELO mga14.intel.com) (192.55.52.115) by mx3-pf2.cudamail.com with SMTP; 4 Jul 2016 10:12:51 -0000 Received-SPF: none (mx3-pf2.cudamail.com: domain at ecsmtp.ir.intel.com does not designate permitted sender hosts) X-Barracuda-Apparent-Source-IP: 192.55.52.115 X-Barracuda-RBL-IP: 192.55.52.115 Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga103.fm.intel.com with ESMTP; 04 Jul 2016 03:12:51 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.26,574,1459839600"; d="scan'208";a="988678399" Received: from irvmail001.ir.intel.com ([163.33.26.43]) by orsmga001.jf.intel.com with ESMTP; 04 Jul 2016 03:12:49 -0700 Received: from sivswdev01.ir.intel.com (sivswdev01.ir.intel.com [10.237.217.45]) by irvmail001.ir.intel.com (8.14.3/8.13.6/MailSET/Hub) with ESMTP id u64ACmvC024518 for ; Mon, 4 Jul 2016 11:12:48 +0100 Received: from sivswdev01.ir.intel.com (localhost [127.0.0.1]) by sivswdev01.ir.intel.com with ESMTP id u64AClNf024490 for ; Mon, 4 Jul 2016 11:12:47 +0100 Received: (from cloftus@localhost) by sivswdev01.ir.intel.com with id u64ACl8P024486 for dev@openvswitch.org; Mon, 4 Jul 2016 11:12:47 +0100 X-CudaMail-Envelope-Sender: cloftus@ecsmtp.ir.intel.com From: Ciara Loftus To: dev@openvswitch.org X-CudaMail-MID: CM-V2-703002523 X-CudaMail-DTE: 070416 X-CudaMail-Originating-IP: 192.55.52.115 Date: Mon, 4 Jul 2016 11:12:47 +0100 X-ASG-Orig-Subj: [##CM-V2-703002523##][RFC PATCH 1/1] netdev-dpdk: Add support for DPDK 16.07 Message-Id: <1467627167-24440-2-git-send-email-ciara.loftus@intel.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1467627167-24440-1-git-send-email-ciara.loftus@intel.com> References: <1467627167-24440-1-git-send-email-ciara.loftus@intel.com> X-GBUdb-Analysis: 0, 192.55.52.115, Ugly c=0.113212 p=-0.333333 Source Normal X-MessageSniffer-Rules: 0-0-0-32767-c X-Barracuda-Connect: UNKNOWN[192.168.14.1] X-Barracuda-Start-Time: 1467627172 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://web.cudamail.com:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at cudamail.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.60 X-Barracuda-Spam-Status: No, SCORE=0.60 using global scores of TAG_LEVEL=3.5 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=4.0 tests=BSF_SC5_MJ1963, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.31000 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 Subject: [ovs-dev] [RFC PATCH 1/1] netdev-dpdk: Add support for DPDK 16.07 X-BeenThere: dev@openvswitch.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dev-bounces@openvswitch.org Sender: "dev" This commit introduces support for DPDK 16.07 and consequently breaks compatibility with DPDK 16.04. DPDK 16.07 introduces some changes to various APIs. These have been updated in OVS, including: * xstats API: changes to structure of xstats * vhost API: replace virtio-net references with 'vid' Signed-off-by: Ciara Loftus Reviewed-by: Aaron Conole --- .travis/linux-build.sh | 2 +- INSTALL.DPDK.md | 12 +-- lib/netdev-dpdk.c | 247 ++++++++++++++++++++++++------------------------- 3 files changed, 128 insertions(+), 133 deletions(-) diff --git a/.travis/linux-build.sh b/.travis/linux-build.sh index 065de39..1b3d43d 100755 --- a/.travis/linux-build.sh +++ b/.travis/linux-build.sh @@ -68,7 +68,7 @@ fi if [ "$DPDK" ]; then if [ -z "$DPDK_VER" ]; then - DPDK_VER="16.04" + DPDK_VER="16.07" fi install_dpdk $DPDK_VER if [ "$CC" = "clang" ]; then diff --git a/INSTALL.DPDK.md b/INSTALL.DPDK.md index 00e75bd..5e63365 100644 --- a/INSTALL.DPDK.md +++ b/INSTALL.DPDK.md @@ -16,7 +16,7 @@ OVS needs a system with 1GB hugepages support. Building and Installing: ------------------------ -Required: DPDK 16.04, libnuma +Required: DPDK 16.07, libnuma Optional (if building with vhost-cuse): `fuse`, `fuse-devel` (`libfuse-dev` on Debian/Ubuntu) @@ -24,7 +24,7 @@ on Debian/Ubuntu) 1. Set `$DPDK_DIR` ``` - export DPDK_DIR=/usr/src/dpdk-16.04 + export DPDK_DIR=/usr/src/dpdk-16.07 cd $DPDK_DIR ``` @@ -563,7 +563,7 @@ the vswitchd. DPDK vhost: ----------- -DPDK 16.04 supports two types of vhost: +DPDK 16.07 supports two types of vhost: 1. vhost-user 2. vhost-cuse @@ -584,7 +584,7 @@ with OVS. DPDK vhost-user Prerequisites: ------------------------- -1. DPDK 16.04 with vhost support enabled as documented in the "Building and +1. DPDK 16.07 with vhost support enabled as documented in the "Building and Installing section" 2. QEMU version v2.1.0+ @@ -703,7 +703,7 @@ with OVS. DPDK vhost-cuse Prerequisites: ------------------------- -1. DPDK 16.04 with vhost support enabled as documented in the "Building and +1. DPDK 16.07 with vhost support enabled as documented in the "Building and Installing section" As an additional step, you must enable vhost-cuse in DPDK by setting the following additional flag in `config/common_base`: @@ -1005,7 +1005,7 @@ Restrictions: this with smaller page sizes. Platform and Network Interface: - - By default with DPDK 16.04, a maximum of 64 TX queues can be used with an + - By default with DPDK 16.07, a maximum of 64 TX queues can be used with an Intel XL710 Network Interface on a platform with more than 64 logical cores. If a user attempts to add an XL710 interface as a DPDK port type to a system as described above, an error will be reported that initialization diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c index 02e2c58..4968d80 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -364,8 +364,8 @@ struct netdev_dpdk { int real_n_rxq; bool txq_needs_locking; - /* virtio-net structure for vhost device */ - OVSRCU_TYPE(struct virtio_net *) virtio_dev; + /* virtio identifier for vhost devices */ + int vid; /* Identifier used to distinguish vhost devices from each other */ char vhost_id[PATH_MAX]; @@ -401,8 +401,6 @@ static bool dpdk_thread_is_pmd(void); static int netdev_dpdk_construct(struct netdev *); -struct virtio_net * netdev_dpdk_get_virtio(const struct netdev_dpdk *dev); - struct ingress_policer * netdev_dpdk_get_ingress_policer(const struct netdev_dpdk *dev); @@ -770,6 +768,7 @@ netdev_dpdk_init(struct netdev *netdev, unsigned int port_no, dev->flags = 0; dev->mtu = ETHER_MTU; dev->max_packet_len = MTU_TO_FRAME_LEN(dev->mtu); + dev->vid = -1; buf_size = dpdk_buf_size(dev->mtu); dev->dpdk_mp = dpdk_mp_get(dev->socket_id, FRAME_LEN_TO_MTU(buf_size)); @@ -869,6 +868,7 @@ netdev_dpdk_vhost_user_construct(struct netdev *netdev) struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); const char *name = netdev->name; int err; + uint64_t flags = 0; /* 'name' is appended to 'vhost_sock_dir' and used to create a socket in * the file system. '/' or '\' would traverse directories, so they're not @@ -891,7 +891,7 @@ netdev_dpdk_vhost_user_construct(struct netdev *netdev) snprintf(dev->vhost_id, sizeof(dev->vhost_id), "%s/%s", vhost_sock_dir, name); - err = rte_vhost_driver_register(dev->vhost_id); + err = rte_vhost_driver_register(dev->vhost_id, flags); if (err) { VLOG_ERR("vhost-user socket device setup failure for socket %s\n", dev->vhost_id); @@ -946,13 +946,19 @@ netdev_dpdk_destruct(struct netdev *netdev) ovs_mutex_unlock(&dpdk_mutex); } +static bool +is_vhost_running(int vid) +{ + return vid >= 0; +} + static void netdev_dpdk_vhost_destruct(struct netdev *netdev) { struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); /* Guest becomes an orphan if still attached. */ - if (netdev_dpdk_get_virtio(dev) != NULL) { + if (is_vhost_running(dev->vid)) { VLOG_ERR("Removing port '%s' while vhost device still attached.", netdev->name); VLOG_ERR("To restore connectivity after re-adding of port, VM on socket" @@ -1181,12 +1187,6 @@ ingress_policer_run(struct ingress_policer *policer, struct rte_mbuf **pkts, return cnt; } -static bool -is_vhost_running(struct virtio_net *virtio_dev) -{ - return (virtio_dev != NULL && (virtio_dev->flags & VIRTIO_DEV_RUNNING)); -} - static inline void netdev_dpdk_vhost_update_rx_size_counters(struct netdev_stats *stats, unsigned int packet_size) @@ -1256,13 +1256,12 @@ netdev_dpdk_vhost_rxq_recv(struct netdev_rxq *rxq, struct dp_packet **packets, int *c) { struct netdev_dpdk *dev = netdev_dpdk_cast(rxq->netdev); - struct virtio_net *virtio_dev = netdev_dpdk_get_virtio(dev); int qid = rxq->queue_id; struct ingress_policer *policer = netdev_dpdk_get_ingress_policer(dev); uint16_t nb_rx = 0; uint16_t dropped = 0; - if (OVS_UNLIKELY(!is_vhost_running(virtio_dev) + if (OVS_UNLIKELY(!is_vhost_running(dev->vid) || !(dev->flags & NETDEV_UP))) { return EAGAIN; } @@ -1271,7 +1270,7 @@ netdev_dpdk_vhost_rxq_recv(struct netdev_rxq *rxq, return EOPNOTSUPP; } - nb_rx = rte_vhost_dequeue_burst(virtio_dev, qid * VIRTIO_QNUM + VIRTIO_TXQ, + nb_rx = rte_vhost_dequeue_burst(dev->vid, qid * VIRTIO_QNUM + VIRTIO_TXQ, dev->dpdk_mp->mp, (struct rte_mbuf **)packets, NETDEV_MAX_BURST); @@ -1377,7 +1376,6 @@ __netdev_dpdk_vhost_send(struct netdev *netdev, int qid, bool may_steal) { struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); - struct virtio_net *virtio_dev = netdev_dpdk_get_virtio(dev); struct rte_mbuf **cur_pkts = (struct rte_mbuf **) pkts; unsigned int total_pkts = cnt; unsigned int qos_pkts = cnt; @@ -1385,7 +1383,7 @@ __netdev_dpdk_vhost_send(struct netdev *netdev, int qid, qid = dev->tx_q[qid % dev->real_n_txq].map; - if (OVS_UNLIKELY(!is_vhost_running(virtio_dev) || qid < 0 + if (OVS_UNLIKELY(!is_vhost_running(dev->vid) || qid < 0 || !(dev->flags & NETDEV_UP))) { rte_spinlock_lock(&dev->stats_lock); dev->stats.tx_dropped+= cnt; @@ -1403,7 +1401,7 @@ __netdev_dpdk_vhost_send(struct netdev *netdev, int qid, int vhost_qid = qid * VIRTIO_QNUM + VIRTIO_RXQ; unsigned int tx_pkts; - tx_pkts = rte_vhost_enqueue_burst(virtio_dev, vhost_qid, + tx_pkts = rte_vhost_enqueue_burst(dev->vid, vhost_qid, cur_pkts, cnt); if (OVS_LIKELY(tx_pkts)) { /* Packets have been sent.*/ @@ -1787,60 +1785,50 @@ netdev_dpdk_vhost_get_stats(const struct netdev *netdev, static void netdev_dpdk_convert_xstats(struct netdev_stats *stats, - const struct rte_eth_xstats *xstats, + const struct rte_eth_xstat *xstats, + const struct rte_eth_xstat_name *names, const unsigned int size) { - /* XXX Current implementation is simple search through an array - * to find hardcoded counter names. In future DPDK release (TBD) - * XSTATS API will change so each counter will be represented by - * unique ID instead of String. */ - for (unsigned int i = 0; i < size; i++) { - if (strcmp(XSTAT_RX_64_PACKETS, xstats[i].name) == 0) { + if (strcmp(XSTAT_RX_64_PACKETS, names[i].name) == 0) { stats->rx_1_to_64_packets = xstats[i].value; - } else if (strcmp(XSTAT_RX_65_TO_127_PACKETS, xstats[i].name) == 0) { + } else if (strcmp(XSTAT_RX_65_TO_127_PACKETS, names[i].name) == 0) { stats->rx_65_to_127_packets = xstats[i].value; - } else if (strcmp(XSTAT_RX_128_TO_255_PACKETS, xstats[i].name) == 0) { + } else if (strcmp(XSTAT_RX_128_TO_255_PACKETS, names[i].name) == 0) { stats->rx_128_to_255_packets = xstats[i].value; - } else if (strcmp(XSTAT_RX_256_TO_511_PACKETS, xstats[i].name) == 0) { + } else if (strcmp(XSTAT_RX_256_TO_511_PACKETS, names[i].name) == 0) { stats->rx_256_to_511_packets = xstats[i].value; - } else if (strcmp(XSTAT_RX_512_TO_1023_PACKETS, - xstats[i].name) == 0) { + } else if (strcmp(XSTAT_RX_512_TO_1023_PACKETS, names[i].name) == 0) { stats->rx_512_to_1023_packets = xstats[i].value; - } else if (strcmp(XSTAT_RX_1024_TO_1522_PACKETS, - xstats[i].name) == 0) { + } else if (strcmp(XSTAT_RX_1024_TO_1522_PACKETS, names[i].name) == 0) { stats->rx_1024_to_1522_packets = xstats[i].value; - } else if (strcmp(XSTAT_RX_1523_TO_MAX_PACKETS, - xstats[i].name) == 0) { + } else if (strcmp(XSTAT_RX_1523_TO_MAX_PACKETS, names[i].name) == 0) { stats->rx_1523_to_max_packets = xstats[i].value; - } else if (strcmp(XSTAT_TX_64_PACKETS, xstats[i].name) == 0) { + } else if (strcmp(XSTAT_TX_64_PACKETS, names[i].name) == 0) { stats->tx_1_to_64_packets = xstats[i].value; - } else if (strcmp(XSTAT_TX_65_TO_127_PACKETS, xstats[i].name) == 0) { + } else if (strcmp(XSTAT_TX_65_TO_127_PACKETS, names[i].name) == 0) { stats->tx_65_to_127_packets = xstats[i].value; - } else if (strcmp(XSTAT_TX_128_TO_255_PACKETS, xstats[i].name) == 0) { + } else if (strcmp(XSTAT_TX_128_TO_255_PACKETS, names[i].name) == 0) { stats->tx_128_to_255_packets = xstats[i].value; - } else if (strcmp(XSTAT_TX_256_TO_511_PACKETS, xstats[i].name) == 0) { + } else if (strcmp(XSTAT_TX_256_TO_511_PACKETS, names[i].name) == 0) { stats->tx_256_to_511_packets = xstats[i].value; - } else if (strcmp(XSTAT_TX_512_TO_1023_PACKETS, - xstats[i].name) == 0) { + } else if (strcmp(XSTAT_TX_512_TO_1023_PACKETS, names[i].name) == 0) { stats->tx_512_to_1023_packets = xstats[i].value; - } else if (strcmp(XSTAT_TX_1024_TO_1522_PACKETS, - xstats[i].name) == 0) { + } else if (strcmp(XSTAT_TX_1024_TO_1522_PACKETS, names[i].name) == 0) { stats->tx_1024_to_1522_packets = xstats[i].value; - } else if (strcmp(XSTAT_TX_1523_TO_MAX_PACKETS, - xstats[i].name) == 0) { + } else if (strcmp(XSTAT_TX_1523_TO_MAX_PACKETS, names[i].name) == 0) { stats->tx_1523_to_max_packets = xstats[i].value; - } else if (strcmp(XSTAT_TX_MULTICAST_PACKETS, xstats[i].name) == 0) { + } else if (strcmp(XSTAT_TX_MULTICAST_PACKETS, names[i].name) == 0) { stats->tx_multicast_packets = xstats[i].value; - } else if (strcmp(XSTAT_RX_BROADCAST_PACKETS, xstats[i].name) == 0) { + } else if (strcmp(XSTAT_RX_BROADCAST_PACKETS, names[i].name) == 0) { stats->rx_broadcast_packets = xstats[i].value; - } else if (strcmp(XSTAT_TX_BROADCAST_PACKETS, xstats[i].name) == 0) { + } else if (strcmp(XSTAT_TX_BROADCAST_PACKETS, names[i].name) == 0) { stats->tx_broadcast_packets = xstats[i].value; - } else if (strcmp(XSTAT_RX_UNDERSIZED_ERRORS, xstats[i].name) == 0) { + } else if (strcmp(XSTAT_RX_UNDERSIZED_ERRORS, names[i].name) == 0) { stats->rx_undersized_errors = xstats[i].value; - } else if (strcmp(XSTAT_RX_FRAGMENTED_ERRORS, xstats[i].name) == 0) { + } else if (strcmp(XSTAT_RX_FRAGMENTED_ERRORS, names[i].name) == 0) { stats->rx_fragmented_errors = xstats[i].value; - } else if (strcmp(XSTAT_RX_JABBER_ERRORS, xstats[i].name) == 0) { + } else if (strcmp(XSTAT_RX_JABBER_ERRORS, names[i].name) == 0) { stats->rx_jabber_errors = xstats[i].value; } } @@ -1856,7 +1844,8 @@ netdev_dpdk_get_stats(const struct netdev *netdev, struct netdev_stats *stats) netdev_dpdk_get_carrier(netdev, &gg); ovs_mutex_lock(&dev->mutex); - struct rte_eth_xstats *rte_xstats; + struct rte_eth_xstat *rte_xstats; + struct rte_eth_xstat_name *rte_xstats_names; int rte_xstats_len, rte_xstats_ret; if (rte_eth_stats_get(dev->port_id, &rte_stats)) { @@ -1865,20 +1854,51 @@ netdev_dpdk_get_stats(const struct netdev *netdev, struct netdev_stats *stats) return EPROTO; } - rte_xstats_len = rte_eth_xstats_get(dev->port_id, NULL, 0); - if (rte_xstats_len > 0) { - rte_xstats = dpdk_rte_mzalloc(sizeof(*rte_xstats) * rte_xstats_len); - memset(rte_xstats, 0xff, sizeof(*rte_xstats) * rte_xstats_len); - rte_xstats_ret = rte_eth_xstats_get(dev->port_id, rte_xstats, - rte_xstats_len); - if (rte_xstats_ret > 0 && rte_xstats_ret <= rte_xstats_len) { - netdev_dpdk_convert_xstats(stats, rte_xstats, rte_xstats_ret); - } + /* Get length of statistics */ + rte_xstats_len = rte_eth_xstats_get_names(dev->port_id, NULL, 0); + if (rte_xstats_len < 0) { + VLOG_WARN("Cannot get XSTATS values for port: %i", dev->port_id); + goto out; + } + /* Reserve memory for xstats names */ + rte_xstats_names = dpdk_rte_mzalloc(sizeof(*rte_xstats_names) + * rte_xstats_len); + if (rte_xstats_names == NULL) { + VLOG_WARN("Cannot allocate memory for XSTATS names for port %i", + dev->port_id); + rte_free(rte_xstats_names); + goto out; + } + /* Reserve memory for xstats values */ + rte_xstats = dpdk_rte_mzalloc(sizeof(*rte_xstats) * rte_xstats_len); + if (rte_xstats == NULL) { + VLOG_WARN("Cannot allocate memory for XSTATS values for port %i", + dev->port_id); rte_free(rte_xstats); + goto out; + } + /* Retreive xstats names */ + if (rte_xstats_len != rte_eth_xstats_get_names(dev->port_id, + rte_xstats_names, rte_xstats_len)) { + VLOG_WARN("Cannot get XSTATS names for port: %i.", dev->port_id); + rte_free(rte_xstats); + rte_free(rte_xstats_names); + goto out; + } + /* Retreive xstats values */ + memset(rte_xstats, 0xff, sizeof(*rte_xstats) * rte_xstats_len); + rte_xstats_ret = rte_eth_xstats_get(dev->port_id, rte_xstats, + rte_xstats_len); + if (rte_xstats_ret > 0 && rte_xstats_ret <= rte_xstats_len) { + netdev_dpdk_convert_xstats(stats, rte_xstats, rte_xstats_names, + rte_xstats_len); } else { - VLOG_WARN("Can't get XSTATS counters for port: %i.", dev->port_id); + VLOG_WARN("Cannot get XSTATS values for port: %i.", dev->port_id); + rte_free(rte_xstats); + rte_free(rte_xstats_names); } +out: stats->rx_packets = rte_stats.ipackets; stats->tx_packets = rte_stats.opackets; stats->rx_bytes = rte_stats.ibytes; @@ -1886,7 +1906,6 @@ netdev_dpdk_get_stats(const struct netdev *netdev, struct netdev_stats *stats) /* DPDK counts imissed as errors, but count them here as dropped instead */ stats->rx_errors = rte_stats.ierrors - rte_stats.imissed; stats->tx_errors = rte_stats.oerrors; - stats->multicast = rte_stats.imcasts; rte_spinlock_lock(&dev->stats_lock); stats->tx_dropped = dev->stats.tx_dropped; @@ -2053,11 +2072,10 @@ static int netdev_dpdk_vhost_get_carrier(const struct netdev *netdev, bool *carrier) { struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); - struct virtio_net *virtio_dev = netdev_dpdk_get_virtio(dev); ovs_mutex_lock(&dev->mutex); - if (is_vhost_running(virtio_dev)) { + if (is_vhost_running(dev->vid)) { *carrier = 1; } else { *carrier = 0; @@ -2125,10 +2143,9 @@ netdev_dpdk_update_flags__(struct netdev_dpdk *dev, /* If DPDK_DEV_VHOST device's NETDEV_UP flag was changed and vhost is * running then change netdev's change_seq to trigger link state * update. */ - struct virtio_net *virtio_dev = netdev_dpdk_get_virtio(dev); if ((NETDEV_UP & ((*old_flagsp ^ on) | (*old_flagsp ^ off))) - && is_vhost_running(virtio_dev)) { + && is_vhost_running(dev->vid)){ netdev_change_seq_changed(&dev->up); /* Clear statistics if device is getting up. */ @@ -2256,15 +2273,15 @@ netdev_dpdk_set_admin_state(struct unixctl_conn *conn, int argc, * Set virtqueue flags so that we do not receive interrupts. */ static void -set_irq_status(struct virtio_net *virtio_dev) +set_irq_status(int vid) { uint32_t i; uint64_t idx; - for (i = 0; i < virtio_dev->virt_qp_nb; i++) { + for (i = 0; i < rte_vhost_get_queue_num(vid); i++) { idx = i * VIRTIO_QNUM; - rte_vhost_enable_guest_notification(virtio_dev, idx + VIRTIO_RXQ, 0); - rte_vhost_enable_guest_notification(virtio_dev, idx + VIRTIO_TXQ, 0); + rte_vhost_enable_guest_notification(vid, idx + VIRTIO_RXQ, 0); + rte_vhost_enable_guest_notification(vid, idx + VIRTIO_TXQ, 0); } } @@ -2310,16 +2327,15 @@ netdev_dpdk_remap_txqs(struct netdev_dpdk *dev) } static int -netdev_dpdk_vhost_set_queues(struct netdev_dpdk *dev, struct virtio_net *virtio_dev) +netdev_dpdk_vhost_set_queues(struct netdev_dpdk *dev, int vid) OVS_REQUIRES(dev->mutex) { uint32_t qp_num; - qp_num = virtio_dev->virt_qp_nb; + qp_num = rte_vhost_get_queue_num(vid); if (qp_num > dev->up.n_rxq) { - VLOG_ERR("vHost Device '%s' %"PRIu64" can't be added - " - "too many queues %d > %d", virtio_dev->ifname, virtio_dev->device_fh, - qp_num, dev->up.n_rxq); + VLOG_ERR("vHost Device '%s' can't be added - too many queues %d > %d", + dev->vhost_id, qp_num, dev->up.n_rxq); return -1; } @@ -2340,41 +2356,37 @@ netdev_dpdk_vhost_set_queues(struct netdev_dpdk *dev, struct virtio_net *virtio_ * A new virtio-net device is added to a vhost port. */ static int -new_device(struct virtio_net *virtio_dev) +new_device(int vid) { struct netdev_dpdk *dev; bool exists = false; int newnode = 0; - long err = 0; + char ifname[PATH_MAX]; + + rte_vhost_get_ifname(vid, ifname, sizeof(ifname)); ovs_mutex_lock(&dpdk_mutex); /* Add device to the vhost port with the same name as that passed down. */ LIST_FOR_EACH(dev, list_node, &dpdk_list) { - if (strncmp(virtio_dev->ifname, dev->vhost_id, IF_NAME_SZ) == 0) { + if (strncmp(ifname, dev->vhost_id, PATH_MAX) == 0) { ovs_mutex_lock(&dev->mutex); - if (netdev_dpdk_vhost_set_queues(dev, virtio_dev)) { + if (netdev_dpdk_vhost_set_queues(dev, vid)) { ovs_mutex_unlock(&dev->mutex); ovs_mutex_unlock(&dpdk_mutex); return -1; } - ovsrcu_set(&dev->virtio_dev, virtio_dev); + dev->vid = vid; exists = true; /* Get NUMA information */ - err = get_mempolicy(&newnode, NULL, 0, virtio_dev, - MPOL_F_NODE | MPOL_F_ADDR); - if (err) { - VLOG_INFO("Error getting NUMA info for vHost Device '%s'", - virtio_dev->ifname); - newnode = dev->socket_id; - } else if (newnode != dev->socket_id) { + newnode = rte_vhost_get_numa_node(vid); + if ((newnode != -1) && (newnode != dev->socket_id)) { dev->requested_socket_id = newnode; netdev_request_reconfigure(&dev->up); } - virtio_dev->flags |= VIRTIO_DEV_RUNNING; /* Disable notifications. */ - set_irq_status(virtio_dev); + set_irq_status(dev->vid); netdev_change_seq_changed(&dev->up); ovs_mutex_unlock(&dev->mutex); break; @@ -2383,14 +2395,14 @@ new_device(struct virtio_net *virtio_dev) ovs_mutex_unlock(&dpdk_mutex); if (!exists) { - VLOG_INFO("vHost Device '%s' %"PRIu64" can't be added - name not " - "found", virtio_dev->ifname, virtio_dev->device_fh); + VLOG_INFO("vHost Device '%s' can't be added - name not found", ifname); return -1; } - VLOG_INFO("vHost Device '%s' %"PRIu64" has been added on numa node %i", - virtio_dev->ifname, virtio_dev->device_fh, newnode); + VLOG_INFO("vHost Device '%s' has been added on numa node %i", + ifname, newnode); + return 0; } @@ -2413,19 +2425,20 @@ netdev_dpdk_txq_map_clear(struct netdev_dpdk *dev) * the device. */ static void -destroy_device(volatile struct virtio_net *virtio_dev) +destroy_device(int vid) { struct netdev_dpdk *dev; bool exists = false; + char ifname[PATH_MAX]; + + rte_vhost_get_ifname(vid, ifname, sizeof(ifname)); ovs_mutex_lock(&dpdk_mutex); LIST_FOR_EACH (dev, list_node, &dpdk_list) { - if (netdev_dpdk_get_virtio(dev) == virtio_dev) { - + if (dev->vid == vid) { ovs_mutex_lock(&dev->mutex); - virtio_dev->flags &= ~VIRTIO_DEV_RUNNING; - ovsrcu_set(&dev->virtio_dev, NULL); netdev_dpdk_txq_map_clear(dev); + dev->vid = -1; exists = true; netdev_change_seq_changed(&dev->up); ovs_mutex_unlock(&dev->mutex); @@ -2436,31 +2449,21 @@ destroy_device(volatile struct virtio_net *virtio_dev) ovs_mutex_unlock(&dpdk_mutex); if (exists == true) { - /* - * Wait for other threads to quiesce after setting the 'virtio_dev' - * to NULL, before returning. - */ - ovsrcu_synchronize(); - /* - * As call to ovsrcu_synchronize() will end the quiescent state, - * put thread back into quiescent state before returning. - */ - ovsrcu_quiesce_start(); - VLOG_INFO("vHost Device '%s' %"PRIu64" has been removed", - virtio_dev->ifname, virtio_dev->device_fh); + VLOG_INFO("vHost Device '%s' has been removed", ifname); } else { - VLOG_INFO("vHost Device '%s' %"PRIu64" not found", virtio_dev->ifname, - virtio_dev->device_fh); + VLOG_INFO("vHost Device '%s' not found", ifname); } } static int -vring_state_changed(struct virtio_net *virtio_dev, uint16_t queue_id, - int enable) +vring_state_changed(int vid, uint16_t queue_id, int enable) { struct netdev_dpdk *dev; bool exists = false; int qid = queue_id / VIRTIO_QNUM; + char ifname[PATH_MAX]; + + rte_vhost_get_ifname(vid, ifname, sizeof(ifname)); if (queue_id % VIRTIO_QNUM == VIRTIO_TXQ) { return 0; @@ -2468,7 +2471,7 @@ vring_state_changed(struct virtio_net *virtio_dev, uint16_t queue_id, ovs_mutex_lock(&dpdk_mutex); LIST_FOR_EACH (dev, list_node, &dpdk_list) { - if (strncmp(virtio_dev->ifname, dev->vhost_id, IF_NAME_SZ) == 0) { + if (strncmp(ifname, dev->vhost_id, PATH_MAX) == 0) { ovs_mutex_lock(&dev->mutex); if (enable) { dev->tx_q[qid].map = qid; @@ -2484,25 +2487,17 @@ vring_state_changed(struct virtio_net *virtio_dev, uint16_t queue_id, ovs_mutex_unlock(&dpdk_mutex); if (exists) { - VLOG_INFO("State of queue %d ( tx_qid %d ) of vhost device '%s' %" - PRIu64" changed to \'%s\'", queue_id, qid, - virtio_dev->ifname, virtio_dev->device_fh, + VLOG_INFO("State of queue %d ( tx_qid %d ) of vhost device '%s'" + "changed to \'%s\'", queue_id, qid, ifname, (enable == 1) ? "enabled" : "disabled"); } else { - VLOG_INFO("vHost Device '%s' %"PRIu64" not found", virtio_dev->ifname, - virtio_dev->device_fh); + VLOG_INFO("vHost Device '%s' not found", ifname); return -1; } return 0; } -struct virtio_net * -netdev_dpdk_get_virtio(const struct netdev_dpdk *dev) -{ - return ovsrcu_get(struct virtio_net *, &dev->virtio_dev); -} - struct ingress_policer * netdev_dpdk_get_ingress_policer(const struct netdev_dpdk *dev) {