]> git.baikalelectronics.ru Git - kernel.git/commitdiff
hinic: add support to query rq info
authorLuo bin <luobin9@huawei.com>
Fri, 28 Aug 2020 03:37:47 +0000 (11:37 +0800)
committerDavid S. Miller <davem@davemloft.net>
Mon, 31 Aug 2020 19:21:27 +0000 (12:21 -0700)
add debugfs node for querying rq info, for example:
cat /sys/kernel/debug/hinic/0000:15:00.0/RQs/0x0/rq_hw_pi

Signed-off-by: Luo bin <luobin9@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/huawei/hinic/hinic_debugfs.c
drivers/net/ethernet/huawei/hinic/hinic_debugfs.h
drivers/net/ethernet/huawei/hinic/hinic_dev.h
drivers/net/ethernet/huawei/hinic/hinic_hw_io.c
drivers/net/ethernet/huawei/hinic/hinic_hw_qp.h
drivers/net/ethernet/huawei/hinic/hinic_main.c

index 2a1050cb400ef08d52074013493e2808df051d6b..d10d0a6d9f134d206e246360aaaff3b531870558 100644 (file)
@@ -40,6 +40,36 @@ static u64 hinic_dbg_get_sq_info(struct hinic_dev *nic_dev, struct hinic_sq *sq,
        return 0;
 }
 
+enum rq_dbg_info {
+       GLB_RQ_ID,
+       RQ_HW_PI,
+       RQ_SW_CI,
+       RQ_SW_PI,
+       RQ_MSIX_ENTRY,
+};
+
+static char *rq_fields[] = {"glb_rq_id", "rq_hw_pi", "rq_sw_ci", "rq_sw_pi", "rq_msix_entry"};
+
+static u64 hinic_dbg_get_rq_info(struct hinic_dev *nic_dev, struct hinic_rq *rq, int idx)
+{
+       struct hinic_wq *wq = rq->wq;
+
+       switch (idx) {
+       case GLB_RQ_ID:
+               return nic_dev->hwdev->func_to_io.global_qpn + rq->qid;
+       case RQ_HW_PI:
+               return be16_to_cpu(*(__be16 *)(rq->pi_virt_addr)) & wq->mask;
+       case RQ_SW_CI:
+               return atomic_read(&wq->cons_idx) & wq->mask;
+       case RQ_SW_PI:
+               return atomic_read(&wq->prod_idx) & wq->mask;
+       case RQ_MSIX_ENTRY:
+               return rq->msix_entry;
+       }
+
+       return 0;
+}
+
 static ssize_t hinic_dbg_cmd_read(struct file *filp, char __user *buffer, size_t count,
                                  loff_t *ppos)
 {
@@ -57,6 +87,10 @@ static ssize_t hinic_dbg_cmd_read(struct file *filp, char __user *buffer, size_t
                out = hinic_dbg_get_sq_info(dbg->dev, dbg->object, *desc);
                break;
 
+       case HINIC_DBG_RQ_INFO:
+               out = hinic_dbg_get_rq_info(dbg->dev, dbg->object, *desc);
+               break;
+
        default:
                netif_warn(dbg->dev, drv, dbg->dev->netdev, "Invalid hinic debug cmd: %d\n",
                           dbg->type);
@@ -128,6 +162,28 @@ void hinic_sq_debug_rem(struct hinic_sq *sq)
                rem_dbg_files(sq->dbg);
 }
 
+int hinic_rq_debug_add(struct hinic_dev *dev, u16 rq_id)
+{
+       struct hinic_rq *rq;
+       struct dentry *root;
+       char sub_dir[16];
+
+       rq = dev->rxqs[rq_id].rq;
+
+       sprintf(sub_dir, "0x%x", rq_id);
+
+       root = debugfs_create_dir(sub_dir, dev->rq_dbgfs);
+
+       return create_dbg_files(dev, HINIC_DBG_RQ_INFO, rq, root, &rq->dbg, rq_fields,
+                               ARRAY_SIZE(rq_fields));
+}
+
+void hinic_rq_debug_rem(struct hinic_rq *rq)
+{
+       if (rq->dbg)
+               rem_dbg_files(rq->dbg);
+}
+
 void hinic_sq_dbgfs_init(struct hinic_dev *nic_dev)
 {
        nic_dev->sq_dbgfs = debugfs_create_dir("SQs", nic_dev->dbgfs_root);
@@ -138,6 +194,16 @@ void hinic_sq_dbgfs_uninit(struct hinic_dev *nic_dev)
        debugfs_remove_recursive(nic_dev->sq_dbgfs);
 }
 
+void hinic_rq_dbgfs_init(struct hinic_dev *nic_dev)
+{
+       nic_dev->rq_dbgfs = debugfs_create_dir("RQs", nic_dev->dbgfs_root);
+}
+
+void hinic_rq_dbgfs_uninit(struct hinic_dev *nic_dev)
+{
+       debugfs_remove_recursive(nic_dev->rq_dbgfs);
+}
+
 void hinic_dbg_init(struct hinic_dev *nic_dev)
 {
        nic_dev->dbgfs_root = debugfs_create_dir(pci_name(nic_dev->hwdev->hwif->pdev),
index 45fb3b40f48792210d9e098ead2f77aedc9a0245..186ca4a26919d665911913e2f947ef4c2e6d799c 100644 (file)
@@ -12,10 +12,18 @@ int hinic_sq_debug_add(struct hinic_dev *dev, u16 sq_id);
 
 void hinic_sq_debug_rem(struct hinic_sq *sq);
 
+int hinic_rq_debug_add(struct hinic_dev *dev, u16 rq_id);
+
+void hinic_rq_debug_rem(struct hinic_rq *rq);
+
 void hinic_sq_dbgfs_init(struct hinic_dev *nic_dev);
 
 void hinic_sq_dbgfs_uninit(struct hinic_dev *nic_dev);
 
+void hinic_rq_dbgfs_init(struct hinic_dev *nic_dev);
+
+void hinic_rq_dbgfs_uninit(struct hinic_dev *nic_dev);
+
 void hinic_dbg_init(struct hinic_dev *nic_dev);
 
 void hinic_dbg_uninit(struct hinic_dev *nic_dev);
index 95d9548014ac10b02263abd45f10f7ffc8b54d9e..0876a699d2057063b8417987bf142615e348dc52 100644 (file)
@@ -60,6 +60,7 @@ struct hinic_intr_coal_info {
 
 enum hinic_dbg_type {
        HINIC_DBG_SQ_INFO,
+       HINIC_DBG_RQ_INFO,
 };
 
 struct hinic_debug_priv {
@@ -112,6 +113,7 @@ struct hinic_dev {
 
        struct dentry                   *dbgfs_root;
        struct dentry                   *sq_dbgfs;
+       struct dentry                   *rq_dbgfs;
        struct devlink                  *devlink;
        bool                            cable_unplugged;
        bool                            module_unrecognized;
index 39a38edb89d6606e8b28266aaf71263155200d74..6772d897872246d90c6877f03c8607af9052d7a3 100644 (file)
@@ -315,6 +315,7 @@ static int init_qp(struct hinic_func_to_io *func_to_io,
                goto err_sq_init;
        }
 
+       qp->rq.qid = q_id;
        err = hinic_init_rq(&qp->rq, hwif, &func_to_io->rq_wq[q_id],
                            rq_msix_entry);
        if (err) {
index 936605cec4ab86707a5398a3a5230499b199aef2..0dfa51ad5855de5b86acd3884d7bbd96c5e38862 100644 (file)
@@ -100,6 +100,8 @@ struct hinic_rq {
 
        struct hinic_wq         *wq;
 
+       u16                     qid;
+
        struct cpumask          affinity_mask;
        u32                     irq;
        u16                     msix_entry;
@@ -113,6 +115,7 @@ struct hinic_rq {
 
        u16                     *pi_virt_addr;
        dma_addr_t              pi_dma_addr;
+       struct hinic_debug_priv *dbg;
 };
 
 struct hinic_qp {
index aad1e5e1bfbe3588e389c598bbdffda882c06382..27ae780d581ae588ec9d59a34811f2b6fdb7b61e 100644 (file)
@@ -234,6 +234,8 @@ static int create_rxqs(struct hinic_dev *nic_dev)
        if (!nic_dev->rxqs)
                return -ENOMEM;
 
+       hinic_rq_dbgfs_init(nic_dev);
+
        for (i = 0; i < num_rxqs; i++) {
                struct hinic_rq *rq = hinic_hwdev_get_rq(nic_dev->hwdev, i);
 
@@ -243,13 +245,26 @@ static int create_rxqs(struct hinic_dev *nic_dev)
                                  "Failed to init rxq\n");
                        goto err_init_rxq;
                }
+
+               err = hinic_rq_debug_add(nic_dev, i);
+               if (err) {
+                       netif_err(nic_dev, drv, netdev,
+                                 "Failed to add RQ%d debug\n", i);
+                       goto err_add_rq_dbg;
+               }
        }
 
        return 0;
 
+err_add_rq_dbg:
+       hinic_clean_rxq(&nic_dev->rxqs[i]);
 err_init_rxq:
-       for (j = 0; j < i; j++)
+       for (j = 0; j < i; j++) {
+               hinic_rq_debug_rem(nic_dev->rxqs[j].rq);
                hinic_clean_rxq(&nic_dev->rxqs[j]);
+       }
+
+       hinic_rq_dbgfs_uninit(nic_dev);
 
        devm_kfree(&netdev->dev, nic_dev->rxqs);
        return err;
@@ -267,8 +282,12 @@ static void free_rxqs(struct hinic_dev *nic_dev)
        if (!nic_dev->rxqs)
                return;
 
-       for (i = 0; i < num_rxqs; i++)
+       for (i = 0; i < num_rxqs; i++) {
+               hinic_rq_debug_rem(nic_dev->rxqs[i].rq);
                hinic_clean_rxq(&nic_dev->rxqs[i]);
+       }
+
+       hinic_rq_dbgfs_uninit(nic_dev);
 
        devm_kfree(&netdev->dev, nic_dev->rxqs);
        nic_dev->rxqs = NULL;