octeontx2-af: Dump current resource provisioning status
authorChristina Jacob <cjacob@marvell.com>
Thu, 14 Nov 2019 05:26:16 +0000 (10:56 +0530)
committerDavid S. Miller <davem@davemloft.net>
Fri, 15 Nov 2019 02:09:15 +0000 (18:09 -0800)
Added support to dump current resource provisioning status
of all resource virtualization unit (RVU) block's
(i.e NPA, NIX, SSO, SSOW, CPT, TIM) local functions attached
to a PF_FUNC into a debugfs file.

'cat /sys/kernel/debug/octeontx2/rsrc_alloc'
will show the current block LF's allocation status.

Signed-off-by: Christina Jacob <cjacob@marvell.com>
Signed-off-by: Prakash Brahmajyosyula <bprakash@marvell.com>
Signed-off-by: Sunil Goutham <sgoutham@marvell.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/marvell/octeontx2/af/Makefile
drivers/net/ethernet/marvell/octeontx2/af/rvu.c
drivers/net/ethernet/marvell/octeontx2/af/rvu.h
drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c [new file with mode: 0644]

index 06329acf9c2c9794679f9a183ac062510cf699bc..1b25948c662b7d3faa8ffd5b97b66745616a7d3c 100644 (file)
@@ -8,4 +8,4 @@ obj-$(CONFIG_OCTEONTX2_AF) += octeontx2_af.o
 
 octeontx2_mbox-y := mbox.o
 octeontx2_af-y := cgx.o rvu.o rvu_cgx.o rvu_npa.o rvu_nix.o \
-                 rvu_reg.o rvu_npc.o
+                 rvu_reg.o rvu_npc.o rvu_debugfs.o
index e581091c09c4e328ffca2a4d10b99af391d62c42..8ed54989dd68e1e620116b62cb42dc5511069328 100644 (file)
@@ -2456,6 +2456,9 @@ static int rvu_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        if (err)
                goto err_irq;
 
+       /* Initialize debugfs */
+       rvu_dbg_init(rvu);
+
        return 0;
 err_irq:
        rvu_unregister_interrupts(rvu);
@@ -2482,6 +2485,7 @@ static void rvu_remove(struct pci_dev *pdev)
 {
        struct rvu *rvu = pci_get_drvdata(pdev);
 
+       rvu_dbg_exit(rvu);
        rvu_unregister_interrupts(rvu);
        rvu_flr_wq_destroy(rvu);
        rvu_cgx_exit(rvu);
index c9d60b0554c0ff5f0e5a9c0087a9b487679ee1b9..9e8ef1f36700fcf8b7bc6ca35f61fa112e802e06 100644 (file)
 #define RVU_PFVF_FUNC_SHIFT    0
 #define RVU_PFVF_FUNC_MASK     0x3FF
 
+#ifdef CONFIG_DEBUG_FS
+struct rvu_debugfs {
+       struct dentry *root;
+};
+#endif
+
 struct rvu_work {
        struct  work_struct work;
        struct  rvu *rvu;
@@ -263,6 +269,10 @@ struct rvu {
        struct list_head        cgx_evq_head; /* cgx event queue head */
 
        char mkex_pfl_name[MKEX_NAME_LEN]; /* Configured MKEX profile name */
+
+#ifdef CONFIG_DEBUG_FS
+       struct rvu_debugfs      rvu_dbg;
+#endif
 };
 
 static inline void rvu_write64(struct rvu *rvu, u64 block, u64 offset, u64 val)
@@ -501,4 +511,12 @@ int rvu_mbox_handler_npc_mcam_alloc_and_write_entry(struct rvu *rvu,
                          struct npc_mcam_alloc_and_write_entry_rsp *rsp);
 int rvu_mbox_handler_npc_get_kex_cfg(struct rvu *rvu, struct msg_req *req,
                                     struct npc_get_kex_cfg_rsp *rsp);
+
+#ifdef CONFIG_DEBUG_FS
+void rvu_dbg_init(struct rvu *rvu);
+void rvu_dbg_exit(struct rvu *rvu);
+#else
+static inline void rvu_dbg_init(struct rvu *rvu) {}
+static inline void rvu_dbg_exit(struct rvu *rvu) {}
+#endif
 #endif /* RVU_H */
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c
new file mode 100644 (file)
index 0000000..ede6cdb
--- /dev/null
@@ -0,0 +1,146 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Marvell OcteonTx2 RVU Admin Function driver
+ *
+ * Copyright (C) 2019 Marvell International Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifdef CONFIG_DEBUG_FS
+
+#include <linux/fs.h>
+#include <linux/debugfs.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+
+#include "rvu_struct.h"
+#include "rvu_reg.h"
+#include "rvu.h"
+
+#define DEBUGFS_DIR_NAME "octeontx2"
+
+#define rvu_dbg_NULL NULL
+
+#define RVU_DEBUG_FOPS(name, read_op, write_op) \
+static const struct file_operations rvu_dbg_##name##_fops = { \
+       .owner = THIS_MODULE, \
+       .open = simple_open, \
+       .read = rvu_dbg_##read_op, \
+       .write = rvu_dbg_##write_op \
+}
+
+/* Dumps current provisioning status of all RVU block LFs */
+static ssize_t rvu_dbg_rsrc_attach_status(struct file *filp,
+                                         char __user *buffer,
+                                         size_t count, loff_t *ppos)
+{
+       int index, off = 0, flag = 0, go_back = 0, off_prev;
+       struct rvu *rvu = filp->private_data;
+       int lf, pf, vf, pcifunc;
+       struct rvu_block block;
+       int bytes_not_copied;
+       int buf_size = 2048;
+       char *buf;
+
+       /* don't allow partial reads */
+       if (*ppos != 0)
+               return 0;
+
+       buf = kzalloc(buf_size, GFP_KERNEL);
+       if (!buf)
+               return -ENOSPC;
+       off +=  scnprintf(&buf[off], buf_size - 1 - off, "\npcifunc\t\t");
+       for (index = 0; index < BLK_COUNT; index++)
+               if (strlen(rvu->hw->block[index].name))
+                       off +=  scnprintf(&buf[off], buf_size - 1 - off,
+                                         "%*s\t", (index - 1) * 2,
+                                         rvu->hw->block[index].name);
+       off += scnprintf(&buf[off], buf_size - 1 - off, "\n");
+       for (pf = 0; pf < rvu->hw->total_pfs; pf++) {
+               for (vf = 0; vf <= rvu->hw->total_vfs; vf++) {
+                       pcifunc = pf << 10 | vf;
+                       if (!pcifunc)
+                               continue;
+
+                       if (vf) {
+                               go_back = scnprintf(&buf[off],
+                                                   buf_size - 1 - off,
+                                                   "PF%d:VF%d\t\t", pf,
+                                                   vf - 1);
+                       } else {
+                               go_back = scnprintf(&buf[off],
+                                                   buf_size - 1 - off,
+                                                   "PF%d\t\t", pf);
+                       }
+
+                       off += go_back;
+                       for (index = 0; index < BLKTYPE_MAX; index++) {
+                               block = rvu->hw->block[index];
+                               if (!strlen(block.name))
+                                       continue;
+                               off_prev = off;
+                               for (lf = 0; lf < block.lf.max; lf++) {
+                                       if (block.fn_map[lf] != pcifunc)
+                                               continue;
+                                       flag = 1;
+                                       off += scnprintf(&buf[off], buf_size - 1
+                                                       - off, "%3d,", lf);
+                               }
+                               if (flag && off_prev != off)
+                                       off--;
+                               else
+                                       go_back++;
+                               off += scnprintf(&buf[off], buf_size - 1 - off,
+                                               "\t");
+                       }
+                       if (!flag)
+                               off -= go_back;
+                       else
+                               flag = 0;
+                       off--;
+                       off +=  scnprintf(&buf[off], buf_size - 1 - off, "\n");
+               }
+       }
+
+       bytes_not_copied = copy_to_user(buffer, buf, off);
+       kfree(buf);
+
+       if (bytes_not_copied)
+               return -EFAULT;
+
+       *ppos = off;
+       return off;
+}
+
+RVU_DEBUG_FOPS(rsrc_status, rsrc_attach_status, NULL);
+
+void rvu_dbg_init(struct rvu *rvu)
+{
+       struct device *dev = &rvu->pdev->dev;
+       struct dentry *pfile;
+
+       rvu->rvu_dbg.root = debugfs_create_dir(DEBUGFS_DIR_NAME, NULL);
+       if (!rvu->rvu_dbg.root) {
+               dev_err(rvu->dev, "%s failed\n", __func__);
+               return;
+       }
+       pfile = debugfs_create_file("rsrc_alloc", 0444, rvu->rvu_dbg.root, rvu,
+                                   &rvu_dbg_rsrc_status_fops);
+       if (!pfile)
+               goto create_failed;
+
+       return;
+
+create_failed:
+       dev_err(dev, "Failed to create debugfs dir\n");
+       debugfs_remove_recursive(rvu->rvu_dbg.root);
+}
+
+void rvu_dbg_exit(struct rvu *rvu)
+{
+       debugfs_remove_recursive(rvu->rvu_dbg.root);
+}
+
+#endif /* CONFIG_DEBUG_FS */