From patchwork Sat Sep 21 02:40:07 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Li,Rongqing via dev" X-Patchwork-Id: 1165763 X-Patchwork-Delegate: i.maximets@samsung.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=openvswitch.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=altencalsoftlabs.com header.i=@altencalsoftlabs.com header.b="uWpfLgMd"; dkim-atps=neutral Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46btRl5KNMz9sNF for ; Mon, 23 Sep 2019 02:38:10 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id C6C4A7F6; Sun, 22 Sep 2019 16:38:05 +0000 (UTC) X-Original-To: ovs-dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 5457C3EE for ; Sun, 22 Sep 2019 16:38:04 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mail.altencalsoftlabs.com (mail.altencalsoftlabs.com [182.73.72.41]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 27867844 for ; Sun, 22 Sep 2019 16:38:02 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by mail.altencalsoftlabs.com (Postfix) with ESMTP id 0B8E04420103; Sun, 22 Sep 2019 22:07:59 +0530 (IST) Received: from mail.altencalsoftlabs.com ([127.0.0.1]) by localhost (mail.altencalsoftlabs.com [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id 5QSCZT6OWJ3D; Sun, 22 Sep 2019 22:07:57 +0530 (IST) Received: from localhost (localhost [127.0.0.1]) by mail.altencalsoftlabs.com (Postfix) with ESMTP id CC54444200E8; Sun, 22 Sep 2019 22:07:57 +0530 (IST) DKIM-Filter: OpenDKIM Filter v2.10.3 mail.altencalsoftlabs.com CC54444200E8 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=altencalsoftlabs.com; s=selector; t=1569170277; bh=7gwR+IrSNPPwovzfbVVTnme8Ro9AKEOmp9i/4TGhV0g=; h=From:To:Date:Message-Id:MIME-Version; b=uWpfLgMdxK3K08GkGpXReVQgOOKxLk08LBJSfP2cyx6v+QwKaim0fwAdDnAhcZxx4 uH21Me2jXZU9lsmp0xmxBBDEVLvtuUGRE52bD6usv0WZWgWg1O8dGyEUv9bzDHJnf/ IPfhZn0BrdeRmcu3+/7lTPJvpUcwtD2inMDS8/kM= X-Virus-Scanned: amavisd-new at altencalsoftlabs.com Received: from mail.altencalsoftlabs.com ([127.0.0.1]) by localhost (mail.altencalsoftlabs.com [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id Da3kR3sYdlgw; Sun, 22 Sep 2019 22:07:57 +0530 (IST) Received: from ubuntu.domain.name (unknown [10.1.0.4]) by mail.altencalsoftlabs.com (Postfix) with ESMTPSA id 7271644200A9; Sun, 22 Sep 2019 22:07:56 +0530 (IST) To: ovs-dev@openvswitch.org, i.maximets@samsung.com Date: Sat, 21 Sep 2019 08:10:07 +0530 Message-Id: <20190921024008.11355-1-sriram.v@altencalsoftlabs.com> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 X-Spam-Status: No, score=-0.7 required=5.0 tests=BAYES_00, DATE_IN_PAST_24_48, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, RCVD_IN_DNSWL_NONE autolearn=no version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v9 1/2] netdev-dpdk: Reuse vhost function for dpdk ETH custom stats. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Sriram Vatala via dev From: "Li,Rongqing via dev" Reply-To: Sriram Vatala Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org From: Ilya Maximets This is yet another refactoring for upcoming detailed drop stats. It allowes to use single function for all the software calculated statistics in netdev-dpdk for both vhost and ETH ports. UINT64_MAX used as a marker for non-supported statistics in a same way as it's done in bridge.c for common netdev stats. Cc: Sriram Vatala Signed-off-by: Ilya Maximets Signed-off-by: Sriram Vatala Acked-by: Kevin Traynor Acked-by: Kevin Traynor --- lib/netdev-dpdk.c | 67 +++++++++++++++++++++++++++-------------------- 1 file changed, 39 insertions(+), 28 deletions(-) diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c index bc20d6843..652b57e3b 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -471,6 +471,8 @@ struct netdev_rxq_dpdk { static void netdev_dpdk_destruct(struct netdev *netdev); static void netdev_dpdk_vhost_destruct(struct netdev *netdev); +static int netdev_dpdk_get_sw_custom_stats(const struct netdev *, + struct netdev_custom_stats *); static void netdev_dpdk_clear_xstats(struct netdev_dpdk *dev); int netdev_dpdk_get_vid(const struct netdev_dpdk *dev); @@ -1171,7 +1173,7 @@ common_construct(struct netdev *netdev, dpdk_port_t port_no, dev->rte_xstats_ids = NULL; dev->rte_xstats_ids_size = 0; - dev->tx_retries = 0; + dev->tx_retries = (dev->type == DPDK_DEV_VHOST) ? 0 : UINT64_MAX; return 0; } @@ -2771,7 +2773,9 @@ netdev_dpdk_get_custom_stats(const struct netdev *netdev, uint32_t i; struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); - int rte_xstats_ret; + int rte_xstats_ret, sw_stats_size; + + netdev_dpdk_get_sw_custom_stats(netdev, custom_stats); ovs_mutex_lock(&dev->mutex); @@ -2786,12 +2790,13 @@ netdev_dpdk_get_custom_stats(const struct netdev *netdev, if (rte_xstats_ret > 0 && rte_xstats_ret <= dev->rte_xstats_ids_size) { - custom_stats->size = rte_xstats_ret; - custom_stats->counters = - (struct netdev_custom_counter *) xcalloc(rte_xstats_ret, - sizeof(struct netdev_custom_counter)); + sw_stats_size = custom_stats->size; + custom_stats->size += rte_xstats_ret; + custom_stats->counters = xrealloc(custom_stats->counters, + custom_stats->size * + sizeof *custom_stats->counters); - for (i = 0; i < rte_xstats_ret; i++) { + for (i = sw_stats_size; i < sw_stats_size + rte_xstats_ret; i++) { ovs_strlcpy(custom_stats->counters[i].name, netdev_dpdk_get_xstat_name(dev, dev->rte_xstats_ids[i]), @@ -2801,8 +2806,6 @@ netdev_dpdk_get_custom_stats(const struct netdev *netdev, } else { VLOG_WARN("Cannot get XSTATS values for port: "DPDK_PORT_ID_FMT, dev->port_id); - custom_stats->counters = NULL; - custom_stats->size = 0; /* Let's clear statistics cache, so it will be * reconfigured */ netdev_dpdk_clear_xstats(dev); @@ -2817,39 +2820,47 @@ netdev_dpdk_get_custom_stats(const struct netdev *netdev, } static int -netdev_dpdk_vhost_get_custom_stats(const struct netdev *netdev, - struct netdev_custom_stats *custom_stats) +netdev_dpdk_get_sw_custom_stats(const struct netdev *netdev, + struct netdev_custom_stats *custom_stats) { struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); - int i; + int i, n; -#define VHOST_CSTATS \ - VHOST_CSTAT(tx_retries) +#define SW_CSTATS \ + SW_CSTAT(tx_retries) -#define VHOST_CSTAT(NAME) + 1 - custom_stats->size = VHOST_CSTATS; -#undef VHOST_CSTAT +#define SW_CSTAT(NAME) + 1 + custom_stats->size = SW_CSTATS; +#undef SW_CSTAT custom_stats->counters = xcalloc(custom_stats->size, sizeof *custom_stats->counters); - i = 0; -#define VHOST_CSTAT(NAME) \ - ovs_strlcpy(custom_stats->counters[i++].name, #NAME, \ - NETDEV_CUSTOM_STATS_NAME_SIZE); - VHOST_CSTATS; -#undef VHOST_CSTAT ovs_mutex_lock(&dev->mutex); rte_spinlock_lock(&dev->stats_lock); i = 0; -#define VHOST_CSTAT(NAME) \ +#define SW_CSTAT(NAME) \ custom_stats->counters[i++].value = dev->NAME; - VHOST_CSTATS; -#undef VHOST_CSTAT + SW_CSTATS; +#undef SW_CSTAT rte_spinlock_unlock(&dev->stats_lock); ovs_mutex_unlock(&dev->mutex); + i = 0; + n = 0; +#define SW_CSTAT(NAME) \ + if (custom_stats->counters[i].value != UINT64_MAX) { \ + ovs_strlcpy(custom_stats->counters[n].name, #NAME, \ + NETDEV_CUSTOM_STATS_NAME_SIZE); \ + custom_stats->counters[n].value = custom_stats->counters[i].value; \ + n++; \ + } \ + i++; + SW_CSTATS; +#undef SW_CSTAT + + custom_stats->size = n; return 0; } @@ -4433,7 +4444,7 @@ static const struct netdev_class dpdk_vhost_class = { .send = netdev_dpdk_vhost_send, .get_carrier = netdev_dpdk_vhost_get_carrier, .get_stats = netdev_dpdk_vhost_get_stats, - .get_custom_stats = netdev_dpdk_vhost_get_custom_stats, + .get_custom_stats = netdev_dpdk_get_sw_custom_stats, .get_status = netdev_dpdk_vhost_user_get_status, .reconfigure = netdev_dpdk_vhost_reconfigure, .rxq_recv = netdev_dpdk_vhost_rxq_recv, @@ -4449,7 +4460,7 @@ static const struct netdev_class dpdk_vhost_client_class = { .send = netdev_dpdk_vhost_send, .get_carrier = netdev_dpdk_vhost_get_carrier, .get_stats = netdev_dpdk_vhost_get_stats, - .get_custom_stats = netdev_dpdk_vhost_get_custom_stats, + .get_custom_stats = netdev_dpdk_get_sw_custom_stats, .get_status = netdev_dpdk_vhost_user_get_status, .reconfigure = netdev_dpdk_vhost_client_reconfigure, .rxq_recv = netdev_dpdk_vhost_rxq_recv, From patchwork Sat Sep 21 02:40:08 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Li,Rongqing via dev" X-Patchwork-Id: 1165764 X-Patchwork-Delegate: i.maximets@samsung.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=openvswitch.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=altencalsoftlabs.com header.i=@altencalsoftlabs.com header.b="B9wNIDoO"; dkim-atps=neutral Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46btSP3FGjz9sNF for ; Mon, 23 Sep 2019 02:38:45 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 9411FACD; Sun, 22 Sep 2019 16:38:07 +0000 (UTC) X-Original-To: ovs-dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id C60BE49F for ; Sun, 22 Sep 2019 16:38:05 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mail.altencalsoftlabs.com (mail.altencalsoftlabs.com [182.73.72.41]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 7DF37844 for ; Sun, 22 Sep 2019 16:38:04 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by mail.altencalsoftlabs.com (Postfix) with ESMTP id A7B154420139; Sun, 22 Sep 2019 22:08:02 +0530 (IST) Received: from mail.altencalsoftlabs.com ([127.0.0.1]) by localhost (mail.altencalsoftlabs.com [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id cLd-hYEs2KKQ; Sun, 22 Sep 2019 22:08:01 +0530 (IST) Received: from localhost (localhost [127.0.0.1]) by mail.altencalsoftlabs.com (Postfix) with ESMTP id 7676B44200E8; Sun, 22 Sep 2019 22:08:01 +0530 (IST) DKIM-Filter: OpenDKIM Filter v2.10.3 mail.altencalsoftlabs.com 7676B44200E8 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=altencalsoftlabs.com; s=selector; t=1569170281; bh=eheTgax3u5kKV6C61bH76xA5Z41Fg7LmOiq2Sb7rT6o=; h=From:To:Date:Message-Id:MIME-Version; b=B9wNIDoO2Vm5PzpJcBSaJwJXA597yzOhpz831XjmZcOw07sSDJb8FXYKmP9xIFyvh /Kc3Yy7H+hUfySsNhetgt1xcuVoHI0M5wsX9GaRhL1S0FVl4jTjzpJq0++XFb/yRoI 45ZrQqrzLFZ1JDfjqg//S5IKJLpovTthcY7yO3m0= X-Virus-Scanned: amavisd-new at altencalsoftlabs.com Received: from mail.altencalsoftlabs.com ([127.0.0.1]) by localhost (mail.altencalsoftlabs.com [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id OcLpVeHtbfY0; Sun, 22 Sep 2019 22:08:01 +0530 (IST) Received: from ubuntu.domain.name (unknown [10.1.0.4]) by mail.altencalsoftlabs.com (Postfix) with ESMTPSA id 4EFE444200A9; Sun, 22 Sep 2019 22:08:00 +0530 (IST) To: ovs-dev@openvswitch.org, i.maximets@samsung.com Date: Sat, 21 Sep 2019 08:10:08 +0530 Message-Id: <20190921024008.11355-2-sriram.v@altencalsoftlabs.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190921024008.11355-1-sriram.v@altencalsoftlabs.com> References: <20190921024008.11355-1-sriram.v@altencalsoftlabs.com> MIME-Version: 1.0 X-Spam-Status: No, score=-0.7 required=5.0 tests=BAYES_00, DATE_IN_PAST_24_48, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, RCVD_IN_DNSWL_NONE autolearn=no version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v9 2/2] netdev-dpdk:Detailed packet drop statistics X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Sriram Vatala via dev From: "Li,Rongqing via dev" Reply-To: Sriram Vatala Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org OVS may be unable to transmit packets for multiple reasons and today there is a single counter to track packets dropped due to any of those reasons. The most common reason is that a VM is unable to read packets fast enough causing the vhostuser port transmit queue on the OVS side to become full. This manifests as a problem with VNFs not receiving all packets. Having a separate drop counter to track packets dropped because the transmit queue is full will clearly indicate that the problem is on the VM side and not in OVS. Similarly maintaining separate counters for all possible drops helps in indicating sensible cause for packet drops. This patch adds custom software stats counters to track packets dropped at port level and these counters are displayed along with other stats in "ovs-vsctl get interface statistics" command. The detailed stats will be available for both dpdk and vhostuser ports. Signed-off-by: Sriram Vatala Signed-off-by: Sriram Vatala Signed-off-by: Sriram Vatala Signed-off-by: Sriram Vatala Signed-off-by: Sriram Vatala Signed-off-by: Sriram Vatala --- Changes since v8: Addressed comments given by Ilya. Signed-off-by: Sriram Vatala --- Documentation/topics/dpdk/vhost-user.rst | 13 ++- lib/netdev-dpdk.c | 81 +++++++++++++++---- utilities/bugtool/automake.mk | 3 +- utilities/bugtool/ovs-bugtool-get-port-stats | 25 ++++++ .../plugins/network-status/openvswitch.xml | 1 + 5 files changed, 105 insertions(+), 18 deletions(-) create mode 100755 utilities/bugtool/ovs-bugtool-get-port-stats diff --git a/Documentation/topics/dpdk/vhost-user.rst b/Documentation/topics/dpdk/vhost-user.rst index 724aa62f6..89388a2bf 100644 --- a/Documentation/topics/dpdk/vhost-user.rst +++ b/Documentation/topics/dpdk/vhost-user.rst @@ -551,7 +551,18 @@ processing packets at the required rate. The amount of Tx retries on a vhost-user or vhost-user-client interface can be shown with:: - $ ovs-vsctl get Interface dpdkvhostclient0 statistics:tx_retries + $ ovs-vsctl get Interface dpdkvhostclient0 statistics:netdev_dpdk_tx_retries + +When the guest is not able to consume the packets fast enough, the transmit +queue of the port gets filled up i.e queue runs out of free descriptors. +This is the most likely reason why dpdk transmit API will fail to send packets +besides other reasons. + +The amount of tx failure drops on a dpdk vhost/physical interface can be +shown with:: + + $ ovs-vsctl get Interface dpdkvhostclient0 \ + statistics:netdev_dpdk_tx_failure_drops vhost-user Dequeue Zero Copy (experimental) ------------------------------------------- diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c index 652b57e3b..fd8f9102e 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -174,6 +174,20 @@ static const struct vhost_device_ops virtio_net_device_ops = .destroy_connection = destroy_connection, }; +/* Custom software stats for dpdk ports */ +struct netdev_dpdk_sw_stats { + /* No. of retries when unable to transmit. */ + uint64_t tx_retries; + /* Packet drops when unable to transmit; Probably Tx queue is full. */ + uint64_t tx_failure_drops; + /* Packet length greater than device MTU. */ + uint64_t tx_mtu_exceeded_drops; + /* Packet drops in egress policer processing. */ + uint64_t tx_qos_drops; + /* Packet drops in ingress policer processing. */ + uint64_t rx_qos_drops; +}; + enum { DPDK_RING_SIZE = 256 }; BUILD_ASSERT_DECL(IS_POW2(DPDK_RING_SIZE)); enum { DRAIN_TSC = 200000ULL }; @@ -413,11 +427,10 @@ struct netdev_dpdk { PADDED_MEMBERS(CACHE_LINE_SIZE, struct netdev_stats stats; - /* Custom stat for retries when unable to transmit. */ - uint64_t tx_retries; + struct netdev_dpdk_sw_stats *sw_stats; /* Protects stats */ rte_spinlock_t stats_lock; - /* 4 pad bytes here. */ + /* 36 pad bytes here. */ ); PADDED_MEMBERS(CACHE_LINE_SIZE, @@ -1173,7 +1186,9 @@ common_construct(struct netdev *netdev, dpdk_port_t port_no, dev->rte_xstats_ids = NULL; dev->rte_xstats_ids_size = 0; - dev->tx_retries = (dev->type == DPDK_DEV_VHOST) ? 0 : UINT64_MAX; + dev->sw_stats = (struct netdev_dpdk_sw_stats *) + xzalloc(sizeof *dev->sw_stats); + dev->sw_stats->tx_retries = (dev->type == DPDK_DEV_VHOST) ? 0 : UINT64_MAX; return 0; } @@ -1359,6 +1374,7 @@ common_destruct(struct netdev_dpdk *dev) ovs_list_remove(&dev->list_node); free(ovsrcu_get_protected(struct ingress_policer *, &dev->ingress_policer)); + free(dev->sw_stats); ovs_mutex_destroy(&dev->mutex); } @@ -2209,6 +2225,7 @@ netdev_dpdk_vhost_rxq_recv(struct netdev_rxq *rxq, rte_spinlock_lock(&dev->stats_lock); netdev_dpdk_vhost_update_rx_counters(&dev->stats, batch->packets, nb_rx, dropped); + dev->sw_stats->rx_qos_drops += dropped; rte_spinlock_unlock(&dev->stats_lock); batch->count = nb_rx; @@ -2258,6 +2275,7 @@ netdev_dpdk_rxq_recv(struct netdev_rxq *rxq, struct dp_packet_batch *batch, if (OVS_UNLIKELY(dropped)) { rte_spinlock_lock(&dev->stats_lock); dev->stats.rx_dropped += dropped; + dev->sw_stats->rx_qos_drops += dropped; rte_spinlock_unlock(&dev->stats_lock); } @@ -2341,6 +2359,10 @@ __netdev_dpdk_vhost_send(struct netdev *netdev, int qid, struct rte_mbuf **cur_pkts = (struct rte_mbuf **) pkts; unsigned int total_pkts = cnt; unsigned int dropped = 0; + unsigned int tx_failure; + unsigned int mtu_drops; + unsigned int qos_drops; + struct netdev_dpdk_sw_stats *sw_stats = dev->sw_stats; int i, retries = 0; int max_retries = VHOST_ENQ_RETRY_MIN; int vid = netdev_dpdk_get_vid(dev); @@ -2358,9 +2380,12 @@ __netdev_dpdk_vhost_send(struct netdev *netdev, int qid, rte_spinlock_lock(&dev->tx_q[qid].tx_lock); cnt = netdev_dpdk_filter_packet_len(dev, cur_pkts, cnt); + mtu_drops = total_pkts - cnt; + qos_drops = cnt; /* Check has QoS has been configured for the netdev */ cnt = netdev_dpdk_qos_run(dev, cur_pkts, cnt, true); - dropped = total_pkts - cnt; + qos_drops -= cnt; + dropped = qos_drops + mtu_drops; do { int vhost_qid = qid * VIRTIO_QNUM + VIRTIO_RXQ; @@ -2385,12 +2410,16 @@ __netdev_dpdk_vhost_send(struct netdev *netdev, int qid, } } while (cnt && (retries++ < max_retries)); + tx_failure = cnt; rte_spinlock_unlock(&dev->tx_q[qid].tx_lock); rte_spinlock_lock(&dev->stats_lock); netdev_dpdk_vhost_update_tx_counters(&dev->stats, pkts, total_pkts, cnt + dropped); - dev->tx_retries += MIN(retries, max_retries); + sw_stats->tx_retries += MIN(retries, max_retries); + sw_stats->tx_failure_drops += tx_failure; + sw_stats->tx_mtu_exceeded_drops += mtu_drops; + sw_stats->tx_qos_drops += qos_drops; rte_spinlock_unlock(&dev->stats_lock); out: @@ -2415,12 +2444,16 @@ dpdk_do_tx_copy(struct netdev *netdev, int qid, struct dp_packet_batch *batch) struct rte_mbuf *pkts[PKT_ARRAY_SIZE]; uint32_t cnt = batch_cnt; uint32_t dropped = 0; + uint32_t tx_failure = 0; + uint32_t mtu_drops = 0; + uint32_t qos_drops = 0; + struct netdev_dpdk_sw_stats *sw_stats = dev->sw_stats; if (dev->type != DPDK_DEV_VHOST) { /* Check if QoS has been configured for this netdev. */ cnt = netdev_dpdk_qos_run(dev, (struct rte_mbuf **) batch->packets, batch_cnt, false); - dropped += batch_cnt - cnt; + qos_drops = batch_cnt - cnt; } uint32_t txcnt = 0; @@ -2433,7 +2466,7 @@ dpdk_do_tx_copy(struct netdev *netdev, int qid, struct dp_packet_batch *batch) VLOG_WARN_RL(&rl, "Too big size %u max_packet_len %d", size, dev->max_packet_len); - dropped++; + mtu_drops++; continue; } @@ -2456,13 +2489,17 @@ dpdk_do_tx_copy(struct netdev *netdev, int qid, struct dp_packet_batch *batch) __netdev_dpdk_vhost_send(netdev, qid, (struct dp_packet **) pkts, txcnt); } else { - dropped += netdev_dpdk_eth_tx_burst(dev, qid, pkts, txcnt); + tx_failure = netdev_dpdk_eth_tx_burst(dev, qid, pkts, txcnt); } } + dropped += qos_drops + mtu_drops + tx_failure; if (OVS_UNLIKELY(dropped)) { rte_spinlock_lock(&dev->stats_lock); dev->stats.tx_dropped += dropped; + sw_stats->tx_failure_drops += tx_failure; + sw_stats->tx_mtu_exceeded_drops += mtu_drops; + sw_stats->tx_qos_drops += qos_drops; rte_spinlock_unlock(&dev->stats_lock); } } @@ -2503,19 +2540,27 @@ netdev_dpdk_send__(struct netdev_dpdk *dev, int qid, dpdk_do_tx_copy(netdev, qid, batch); dp_packet_delete_batch(batch, true); } else { + struct netdev_dpdk_sw_stats *sw_stats = dev->sw_stats; int tx_cnt, dropped; + int tx_failure, mtu_drops, qos_drops; int batch_cnt = dp_packet_batch_size(batch); struct rte_mbuf **pkts = (struct rte_mbuf **) batch->packets; tx_cnt = netdev_dpdk_filter_packet_len(dev, pkts, batch_cnt); + mtu_drops = batch_cnt - tx_cnt; + qos_drops = tx_cnt; tx_cnt = netdev_dpdk_qos_run(dev, pkts, tx_cnt, true); - dropped = batch_cnt - tx_cnt; + qos_drops -= tx_cnt; - dropped += netdev_dpdk_eth_tx_burst(dev, qid, pkts, tx_cnt); + tx_failure = netdev_dpdk_eth_tx_burst(dev, qid, pkts, tx_cnt); + dropped = tx_failure + mtu_drops + qos_drops; if (OVS_UNLIKELY(dropped)) { rte_spinlock_lock(&dev->stats_lock); dev->stats.tx_dropped += dropped; + sw_stats->tx_failure_drops += tx_failure; + sw_stats->tx_mtu_exceeded_drops += mtu_drops; + sw_stats->tx_qos_drops += qos_drops; rte_spinlock_unlock(&dev->stats_lock); } } @@ -2826,8 +2871,12 @@ netdev_dpdk_get_sw_custom_stats(const struct netdev *netdev, struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); int i, n; -#define SW_CSTATS \ - SW_CSTAT(tx_retries) +#define SW_CSTATS \ + SW_CSTAT(tx_retries) \ + SW_CSTAT(tx_failure_drops) \ + SW_CSTAT(tx_mtu_exceeded_drops) \ + SW_CSTAT(tx_qos_drops) \ + SW_CSTAT(rx_qos_drops) #define SW_CSTAT(NAME) + 1 custom_stats->size = SW_CSTATS; @@ -2840,7 +2889,7 @@ netdev_dpdk_get_sw_custom_stats(const struct netdev *netdev, rte_spinlock_lock(&dev->stats_lock); i = 0; #define SW_CSTAT(NAME) \ - custom_stats->counters[i++].value = dev->NAME; + custom_stats->counters[i++].value = dev->sw_stats->NAME; SW_CSTATS; #undef SW_CSTAT rte_spinlock_unlock(&dev->stats_lock); @@ -2851,8 +2900,8 @@ netdev_dpdk_get_sw_custom_stats(const struct netdev *netdev, n = 0; #define SW_CSTAT(NAME) \ if (custom_stats->counters[i].value != UINT64_MAX) { \ - ovs_strlcpy(custom_stats->counters[n].name, #NAME, \ - NETDEV_CUSTOM_STATS_NAME_SIZE); \ + ovs_strlcpy(custom_stats->counters[n].name, \ + "netdev_dpdk_"#NAME, NETDEV_CUSTOM_STATS_NAME_SIZE); \ custom_stats->counters[n].value = custom_stats->counters[i].value; \ n++; \ } \ diff --git a/utilities/bugtool/automake.mk b/utilities/bugtool/automake.mk index 40980b367..dda58e0a1 100644 --- a/utilities/bugtool/automake.mk +++ b/utilities/bugtool/automake.mk @@ -22,7 +22,8 @@ bugtool_scripts = \ utilities/bugtool/ovs-bugtool-ovs-bridge-datapath-type \ utilities/bugtool/ovs-bugtool-ovs-vswitchd-threads-affinity \ utilities/bugtool/ovs-bugtool-qos-configs \ - utilities/bugtool/ovs-bugtool-get-dpdk-nic-numa + utilities/bugtool/ovs-bugtool-get-dpdk-nic-numa \ + utilities/bugtool/ovs-bugtool-get-port-stats scripts_SCRIPTS += $(bugtool_scripts) diff --git a/utilities/bugtool/ovs-bugtool-get-port-stats b/utilities/bugtool/ovs-bugtool-get-port-stats new file mode 100755 index 000000000..0fe175e6b --- /dev/null +++ b/utilities/bugtool/ovs-bugtool-get-port-stats @@ -0,0 +1,25 @@ +#! /bin/bash + +# This library 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 library 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. +# +# Copyright (C) 2019 Ericsson AB + +for bridge in `ovs-vsctl -- --real list-br` +do + echo -e "\nBridge : ${bridge}\n" + for iface in `ovs-vsctl list-ifaces ${bridge}` + do + echo -e "iface : ${iface}" + ovs-vsctl get interface ${iface} statistics + echo -e "\n" + done + echo -e "iface : ${bridge}" + ovs-vsctl get interface ${bridge} statistics +done diff --git a/utilities/bugtool/plugins/network-status/openvswitch.xml b/utilities/bugtool/plugins/network-status/openvswitch.xml index d39867c6e..8c1ec643e 100644 --- a/utilities/bugtool/plugins/network-status/openvswitch.xml +++ b/utilities/bugtool/plugins/network-status/openvswitch.xml @@ -40,4 +40,5 @@ /usr/share/openvswitch/scripts/ovs-bugtool-ovs-ofctl-loop-over-bridges "dump-groups" /usr/share/openvswitch/scripts/ovs-bugtool-ovs-ofctl-loop-over-bridges "dump-group-stats" /usr/share/openvswitch/scripts/ovs-bugtool-get-dpdk-nic-numa + /usr/share/openvswitch/scripts/ovs-bugtool-get-port-stats