net: hns3: dump more information when tx timeout happens
authorJian Shen <shenjian15@huawei.com>
Fri, 19 Apr 2019 03:05:42 +0000 (11:05 +0800)
committerDavid S. Miller <davem@davemloft.net>
Sat, 20 Apr 2019 01:43:16 +0000 (18:43 -0700)
Currently we just print few information when tx timeout happens.
In order to find out the cause of timeout, this patch prints more
information about the packet statistics, tqp registers and
napi state.

Signed-off-by: Jian Shen <shenjian15@huawei.com>
Signed-off-by: Peng Li <lipeng321@huawei.com>
Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/hisilicon/hns3/hnae3.h
drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c

index 681c1752c1e3cedb4f53953f7adffb96ec037421..8fe2c8fa7115302cea531ad8badd9d022194ad71 100644 (file)
@@ -392,7 +392,8 @@ struct hnae3_ae_ops {
        void (*update_stats)(struct hnae3_handle *handle,
                             struct net_device_stats *net_stats);
        void (*get_stats)(struct hnae3_handle *handle, u64 *data);
-
+       void (*get_mac_pause_stats)(struct hnae3_handle *handle, u64 *tx_cnt,
+                                   u64 *rx_cnt);
        void (*get_strings)(struct hnae3_handle *handle,
                            u32 stringset, u8 *data);
        int (*get_sset_count)(struct hnae3_handle *handle, int stringset);
index 652b19d16834ebf8706948fcb451845bebb5819f..4c96f94d4502dfa7cb506e695059c2663728414a 100644 (file)
@@ -1628,9 +1628,15 @@ static int hns3_nic_change_mtu(struct net_device *netdev, int new_mtu)
 static bool hns3_get_tx_timeo_queue_info(struct net_device *ndev)
 {
        struct hns3_nic_priv *priv = netdev_priv(ndev);
+       struct hnae3_handle *h = hns3_get_handle(ndev);
        struct hns3_enet_ring *tx_ring = NULL;
+       struct napi_struct *napi;
        int timeout_queue = 0;
        int hw_head, hw_tail;
+       int fbd_num, fbd_oft;
+       int ebd_num, ebd_oft;
+       int bd_num, bd_err;
+       int ring_en, tc;
        int i;
 
        /* Find the stopped queue the same way the stack does */
@@ -1658,20 +1664,63 @@ static bool hns3_get_tx_timeo_queue_info(struct net_device *ndev)
        priv->tx_timeout_count++;
 
        tx_ring = priv->ring_data[timeout_queue].ring;
+       napi = &tx_ring->tqp_vector->napi;
+
+       netdev_info(ndev,
+                   "tx_timeout count: %llu, queue id: %d, SW_NTU: 0x%x, SW_NTC: 0x%x, napi state: %lu\n",
+                   priv->tx_timeout_count, timeout_queue, tx_ring->next_to_use,
+                   tx_ring->next_to_clean, napi->state);
+
+       netdev_info(ndev,
+                   "tx_pkts: %llu, tx_bytes: %llu, io_err_cnt: %llu, sw_err_cnt: %llu\n",
+                   tx_ring->stats.tx_pkts, tx_ring->stats.tx_bytes,
+                   tx_ring->stats.io_err_cnt, tx_ring->stats.sw_err_cnt);
+
+       netdev_info(ndev,
+                   "seg_pkt_cnt: %llu, tx_err_cnt: %llu, restart_queue: %llu, tx_busy: %llu\n",
+                   tx_ring->stats.seg_pkt_cnt, tx_ring->stats.tx_err_cnt,
+                   tx_ring->stats.restart_queue, tx_ring->stats.tx_busy);
+
+       /* When mac received many pause frames continuous, it's unable to send
+        * packets, which may cause tx timeout
+        */
+       if (h->ae_algo->ops->update_stats &&
+           h->ae_algo->ops->get_mac_pause_stats) {
+               u64 tx_pause_cnt, rx_pause_cnt;
+
+               h->ae_algo->ops->update_stats(h, &ndev->stats);
+               h->ae_algo->ops->get_mac_pause_stats(h, &tx_pause_cnt,
+                                                    &rx_pause_cnt);
+               netdev_info(ndev, "tx_pause_cnt: %llu, rx_pause_cnt: %llu\n",
+                           tx_pause_cnt, rx_pause_cnt);
+       }
 
        hw_head = readl_relaxed(tx_ring->tqp->io_base +
                                HNS3_RING_TX_RING_HEAD_REG);
        hw_tail = readl_relaxed(tx_ring->tqp->io_base +
                                HNS3_RING_TX_RING_TAIL_REG);
+       fbd_num = readl_relaxed(tx_ring->tqp->io_base +
+                               HNS3_RING_TX_RING_FBDNUM_REG);
+       fbd_oft = readl_relaxed(tx_ring->tqp->io_base +
+                               HNS3_RING_TX_RING_OFFSET_REG);
+       ebd_num = readl_relaxed(tx_ring->tqp->io_base +
+                               HNS3_RING_TX_RING_EBDNUM_REG);
+       ebd_oft = readl_relaxed(tx_ring->tqp->io_base +
+                               HNS3_RING_TX_RING_EBD_OFFSET_REG);
+       bd_num = readl_relaxed(tx_ring->tqp->io_base +
+                              HNS3_RING_TX_RING_BD_NUM_REG);
+       bd_err = readl_relaxed(tx_ring->tqp->io_base +
+                              HNS3_RING_TX_RING_BD_ERR_REG);
+       ring_en = readl_relaxed(tx_ring->tqp->io_base + HNS3_RING_EN_REG);
+       tc = readl_relaxed(tx_ring->tqp->io_base + HNS3_RING_TX_RING_TC_REG);
+
        netdev_info(ndev,
-                   "tx_timeout count: %llu, queue id: %d, SW_NTU: 0x%x, SW_NTC: 0x%x, HW_HEAD: 0x%x, HW_TAIL: 0x%x, INT: 0x%x\n",
-                   priv->tx_timeout_count,
-                   timeout_queue,
-                   tx_ring->next_to_use,
-                   tx_ring->next_to_clean,
-                   hw_head,
-                   hw_tail,
+                   "BD_NUM: 0x%x HW_HEAD: 0x%x, HW_TAIL: 0x%x, BD_ERR: 0x%x, INT: 0x%x\n",
+                   bd_num, hw_head, hw_tail, bd_err,
                    readl(tx_ring->tqp_vector->mask_addr));
+       netdev_info(ndev,
+                   "RING_EN: 0x%x, TC: 0x%x, FBD_NUM: 0x%x FBD_OFT: 0x%x, EBD_NUM: 0x%x, EBD_OFT: 0x%x\n",
+                   ring_en, tc, fbd_num, fbd_oft, ebd_num, ebd_oft);
 
        return true;
 }
index 025d0f7f860dbd261692fdaacf38c57c90c95a56..f433c6d19b59db89d4f599feef88d2ff9e7a8edf 100644 (file)
@@ -42,8 +42,10 @@ enum hns3_nic_state {
 #define HNS3_RING_TX_RING_HEAD_REG             0x0005C
 #define HNS3_RING_TX_RING_FBDNUM_REG           0x00060
 #define HNS3_RING_TX_RING_OFFSET_REG           0x00064
+#define HNS3_RING_TX_RING_EBDNUM_REG           0x00068
 #define HNS3_RING_TX_RING_PKTNUM_RECORD_REG    0x0006C
-
+#define HNS3_RING_TX_RING_EBD_OFFSET_REG       0x00070
+#define HNS3_RING_TX_RING_BD_ERR_REG           0x00074
 #define HNS3_RING_PREFETCH_EN_REG              0x0007C
 #define HNS3_RING_CFG_VF_NUM_REG               0x00080
 #define HNS3_RING_ASID_REG                     0x0008C
index 9b7bc2268113dc2ffd2657f6b0eeaae1e37c8be1..7ac760215bfa4e2c1a77e350b717fa7ea49a5b1b 100644 (file)
@@ -699,6 +699,16 @@ static void hclge_get_stats(struct hnae3_handle *handle, u64 *data)
        p = hclge_tqps_get_stats(handle, p);
 }
 
+static void hclge_get_mac_pause_stat(struct hnae3_handle *handle, u64 *tx_cnt,
+                                    u64 *rx_cnt)
+{
+       struct hclge_vport *vport = hclge_get_vport(handle);
+       struct hclge_dev *hdev = vport->back;
+
+       *tx_cnt = hdev->hw_stats.mac_stats.mac_tx_mac_pause_num;
+       *rx_cnt = hdev->hw_stats.mac_stats.mac_rx_mac_pause_num;
+}
+
 static int hclge_parse_func_status(struct hclge_dev *hdev,
                                   struct hclge_func_status_cmd *status)
 {
@@ -8522,6 +8532,7 @@ static const struct hnae3_ae_ops hclge_ops = {
        .set_mtu = hclge_set_mtu,
        .reset_queue = hclge_reset_tqp,
        .get_stats = hclge_get_stats,
+       .get_mac_pause_stats = hclge_get_mac_pause_stat,
        .update_stats = hclge_update_stats,
        .get_strings = hclge_get_strings,
        .get_sset_count = hclge_get_sset_count,