Received: by 2002:ac0:de83:0:0:0:0:0 with SMTP id b3csp1415904imk; Mon, 4 Jul 2022 02:37:17 -0700 (PDT) X-Google-Smtp-Source: AGRyM1uKex8+/fBzst+d58kQn97dO3FMx3ou+iyqevnDU9/hXWNtdXFX9pvNjO8dnaoTvOiJYAON X-Received: by 2002:a17:902:e881:b0:16a:39e4:c5ef with SMTP id w1-20020a170902e88100b0016a39e4c5efmr34734488plg.114.1656927437407; Mon, 04 Jul 2022 02:37:17 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1656927437; cv=none; d=google.com; s=arc-20160816; b=KjtEufFO8+mbvuTu/BsRIj8xs135bXVLJBmruxXNw7SZRWy4Ek8Qks3CYD8ePGupXO 20wwNLr7mHP+6X5F6UVxdZkjp6iw7eXcjw7dBBUu21m7yD1AHk7LS6YpmEKt6f6m6lSi JjPKEKgUZKYIL++zkzX882ZE4n9jhg6ySe2VCbhZVF8ADwSVG+YP20kO6x1wF6AFTvQq fN18hEdSQVBpEkr7PAh8edKe22vCD27VstgkpGL1J++7RetqbiLjhMsaBiZNs3DcAoL5 LFZkXLpdXJcKr/YI7rVN6pecBBbA9DhjPLeqtusAI6qdjjbmuyAqmmzz+aqXhgL6w+uf PIzw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:references:in-reply-to:references:in-reply-to :message-id:date:subject:cc:to:from; bh=3P4oDmy5RMWfUBn0Lr4CB/JOVHaSIfCKBRvm7pmnxZI=; b=CYfi4TxWJev18szW9wo3n4D3ryTKpvL++VPkbmfq39PGCXZyKn/42s79alzpMcjZIV i24qbZzyh2gs70ngF6bFFfE0dZWPEvFxmuQm1W0l0iEzl/ThC4U4mjSG6fbZ3E6tyeJC e7O22Z0QoSVxcSGXkK5hT1cdnK7RgZm7se1FMF1XCgEs8VWzNfEGTxzz9eQnCtsdbPKs oV419AMveUWxTVC4DXd0r+Y9gHkUKgaBQoU6iTK8/j2Z6f3aM6izezpd8opKqPfLUpLs RMXUCZgp/YVuZBzZjkzYa79dprXxJ/2/56Uen7kDpVCqzqreaG71zB2CpPtg+uziHvIC lQ0Q== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=alibaba.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id u10-20020a65670a000000b00408d622b82dsi39023351pgf.136.2022.07.04.02.37.03; Mon, 04 Jul 2022 02:37:17 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=alibaba.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233285AbiGDI6J (ORCPT + 99 others); Mon, 4 Jul 2022 04:58:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57110 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233237AbiGDI6F (ORCPT ); Mon, 4 Jul 2022 04:58:05 -0400 Received: from out30-130.freemail.mail.aliyun.com (out30-130.freemail.mail.aliyun.com [115.124.30.130]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 04CF1BCAE; Mon, 4 Jul 2022 01:58:03 -0700 (PDT) X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R171e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=ay29a033018046050;MF=mqaio@linux.alibaba.com;NM=1;PH=DS;RN=11;SR=0;TI=SMTPD_---0VIJ4YGN_1656925078; Received: from localhost(mailfrom:mqaio@linux.alibaba.com fp:SMTPD_---0VIJ4YGN_1656925078) by smtp.aliyun-inc.com; Mon, 04 Jul 2022 16:57:59 +0800 From: Qiao Ma To: davem@davemloft.net, edumazet@google.com, pabeni@redhat.com, kuba@kernel.org, gustavoars@kernel.org, cai.huoqing@linux.dev, aviad.krawczyk@huawei.com, zhaochen6@huawei.com Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH net-next v2 1/3] net: hinic: fix bug that ethtool get wrong stats Date: Mon, 4 Jul 2022 16:57:44 +0800 Message-Id: <7e3115e81cd5cab71a4a79b8061062e9d25eb5af.1656921519.git.mqaio@linux.alibaba.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: References: In-Reply-To: References: X-Spam-Status: No, score=-9.9 required=5.0 tests=BAYES_00, ENV_AND_HDR_SPF_MATCH,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE,UNPARSEABLE_RELAY,USER_IN_DEF_SPF_WL autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Function hinic_get_stats64() will do two operations: 1. reads stats from every hinic_rxq/txq and accumulates them 2. calls hinic_rxq/txq_clean_stats() to clean every rxq/txq's stats For hinic_get_stats64(), it could get right data, because it sums all data to nic_dev->rx_stats/tx_stats. But it is wrong for get_drv_queue_stats(), this function will read hinic_rxq's stats, which have been cleared to zero by hinic_get_stats64(). I have observed hinic's cleanup operation by using such command: > watch -n 1 "cat ethtool -S eth4 | tail -40" Result before: ... rxq7_pkts: 1 rxq7_bytes: 90 rxq7_errors: 0 rxq7_csum_errors: 0 rxq7_other_errors: 0 ... rxq9_pkts: 11 rxq9_bytes: 726 rxq9_errors: 0 rxq9_csum_errors: 0 rxq9_other_errors: 0 ... rxq11_pkts: 0 rxq11_bytes: 0 rxq11_errors: 0 rxq11_csum_errors: 0 rxq11_other_errors: 0 Result after a few seconds: ... rxq7_pkts: 0 rxq7_bytes: 0 rxq7_errors: 0 rxq7_csum_errors: 0 rxq7_other_errors: 0 ... rxq9_pkts: 2 rxq9_bytes: 132 rxq9_errors: 0 rxq9_csum_errors: 0 rxq9_other_errors: 0 ... rxq11_pkts: 1 rxq11_bytes: 170 rxq11_errors: 0 rxq11_csum_errors: 0 rxq11_other_errors: 0 To solve this problem, we just keep every queue's total stats in their own queue (aka hinic_{rxq|txq}), and simply sum all per-queue stats every time calling hinic_get_stats64(). With that solution, there is no need to clean per-queue stats now, and there is no need to maintain global hinic_dev.{tx|rx}_stats, too. Fixes: edd384f682cc ("net-next/hinic: Add ethtool and stats") Signed-off-by: Qiao Ma --- drivers/net/ethernet/huawei/hinic/hinic_dev.h | 3 -- drivers/net/ethernet/huawei/hinic/hinic_main.c | 54 +++++++++----------------- 2 files changed, 18 insertions(+), 39 deletions(-) diff --git a/drivers/net/ethernet/huawei/hinic/hinic_dev.h b/drivers/net/ethernet/huawei/hinic/hinic_dev.h index fb3e89141a0d..a4fbf44f944c 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_dev.h +++ b/drivers/net/ethernet/huawei/hinic/hinic_dev.h @@ -95,9 +95,6 @@ struct hinic_dev { u16 sq_depth; u16 rq_depth; - struct hinic_txq_stats tx_stats; - struct hinic_rxq_stats rx_stats; - u8 rss_tmpl_idx; u8 rss_hash_engine; u16 num_rss; diff --git a/drivers/net/ethernet/huawei/hinic/hinic_main.c b/drivers/net/ethernet/huawei/hinic/hinic_main.c index 56a89793f47d..84d957692442 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_main.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_main.c @@ -80,56 +80,48 @@ static int set_features(struct hinic_dev *nic_dev, netdev_features_t pre_features, netdev_features_t features, bool force_change); -static void update_rx_stats(struct hinic_dev *nic_dev, struct hinic_rxq *rxq) +static void gather_rx_stats(struct hinic_rxq_stats *nic_rx_stats, struct hinic_rxq *rxq) { - struct hinic_rxq_stats *nic_rx_stats = &nic_dev->rx_stats; struct hinic_rxq_stats rx_stats; u64_stats_init(&rx_stats.syncp); hinic_rxq_get_stats(rxq, &rx_stats); - u64_stats_update_begin(&nic_rx_stats->syncp); nic_rx_stats->bytes += rx_stats.bytes; nic_rx_stats->pkts += rx_stats.pkts; nic_rx_stats->errors += rx_stats.errors; nic_rx_stats->csum_errors += rx_stats.csum_errors; nic_rx_stats->other_errors += rx_stats.other_errors; - u64_stats_update_end(&nic_rx_stats->syncp); - - hinic_rxq_clean_stats(rxq); } -static void update_tx_stats(struct hinic_dev *nic_dev, struct hinic_txq *txq) +static void gather_tx_stats(struct hinic_txq_stats *nic_tx_stats, struct hinic_txq *txq) { - struct hinic_txq_stats *nic_tx_stats = &nic_dev->tx_stats; struct hinic_txq_stats tx_stats; u64_stats_init(&tx_stats.syncp); hinic_txq_get_stats(txq, &tx_stats); - u64_stats_update_begin(&nic_tx_stats->syncp); nic_tx_stats->bytes += tx_stats.bytes; nic_tx_stats->pkts += tx_stats.pkts; nic_tx_stats->tx_busy += tx_stats.tx_busy; nic_tx_stats->tx_wake += tx_stats.tx_wake; nic_tx_stats->tx_dropped += tx_stats.tx_dropped; nic_tx_stats->big_frags_pkts += tx_stats.big_frags_pkts; - u64_stats_update_end(&nic_tx_stats->syncp); - - hinic_txq_clean_stats(txq); } -static void update_nic_stats(struct hinic_dev *nic_dev) +static void gather_nic_stats(struct hinic_dev *nic_dev, + struct hinic_rxq_stats *nic_rx_stats, + struct hinic_txq_stats *nic_tx_stats) { int i, num_qps = hinic_hwdev_num_qps(nic_dev->hwdev); for (i = 0; i < num_qps; i++) - update_rx_stats(nic_dev, &nic_dev->rxqs[i]); + gather_rx_stats(nic_rx_stats, &nic_dev->rxqs[i]); for (i = 0; i < num_qps; i++) - update_tx_stats(nic_dev, &nic_dev->txqs[i]); + gather_tx_stats(nic_tx_stats, &nic_dev->txqs[i]); } /** @@ -558,8 +550,6 @@ int hinic_close(struct net_device *netdev) netif_carrier_off(netdev); netif_tx_disable(netdev); - update_nic_stats(nic_dev); - up(&nic_dev->mgmt_lock); if (!HINIC_IS_VF(nic_dev->hwdev->hwif)) @@ -853,26 +843,24 @@ static void hinic_get_stats64(struct net_device *netdev, struct rtnl_link_stats64 *stats) { struct hinic_dev *nic_dev = netdev_priv(netdev); - struct hinic_rxq_stats *nic_rx_stats; - struct hinic_txq_stats *nic_tx_stats; + struct hinic_rxq_stats nic_rx_stats = {}; + struct hinic_txq_stats nic_tx_stats = {}; - nic_rx_stats = &nic_dev->rx_stats; - nic_tx_stats = &nic_dev->tx_stats; + u64_stats_init(&nic_rx_stats.syncp); + u64_stats_init(&nic_tx_stats.syncp); down(&nic_dev->mgmt_lock); - if (nic_dev->flags & HINIC_INTF_UP) - update_nic_stats(nic_dev); - + gather_nic_stats(nic_dev, &nic_rx_stats, &nic_tx_stats); up(&nic_dev->mgmt_lock); - stats->rx_bytes = nic_rx_stats->bytes; - stats->rx_packets = nic_rx_stats->pkts; - stats->rx_errors = nic_rx_stats->errors; + stats->rx_bytes = nic_rx_stats.bytes; + stats->rx_packets = nic_rx_stats.pkts; + stats->rx_errors = nic_rx_stats.errors; - stats->tx_bytes = nic_tx_stats->bytes; - stats->tx_packets = nic_tx_stats->pkts; - stats->tx_errors = nic_tx_stats->tx_dropped; + stats->tx_bytes = nic_tx_stats.bytes; + stats->tx_packets = nic_tx_stats.pkts; + stats->tx_errors = nic_tx_stats.tx_dropped; } static int hinic_set_features(struct net_device *netdev, @@ -1234,12 +1222,6 @@ static int nic_dev_init(struct pci_dev *pdev) sema_init(&nic_dev->mgmt_lock, 1); - tx_stats = &nic_dev->tx_stats; - rx_stats = &nic_dev->rx_stats; - - u64_stats_init(&tx_stats->syncp); - u64_stats_init(&rx_stats->syncp); - nic_dev->vlan_bitmap = devm_bitmap_zalloc(&pdev->dev, VLAN_N_VID, GFP_KERNEL); if (!nic_dev->vlan_bitmap) { -- 1.8.3.1