Re: [PATCH for-next 4/4] RDMA/bnxt_re: Add debugfs hook in the driver

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




On 2024/10/22 18:11, Selvin Xavier wrote:
> From: Kalesh AP <kalesh-anakkur.purayil@xxxxxxxxxxxx>
> 
> Adding support for a per device debugfs folder for exporting
> some of the device specific debug information.
> Added support to get QP info for now. The same folder can be
> used to export other debug features in future.
> 
> Signed-off-by: Saravanan Vajravel <saravanan.vajravel@xxxxxxxxxxxx>
> Signed-off-by: Kalesh AP <kalesh-anakkur.purayil@xxxxxxxxxxxx>
> Signed-off-by: Selvin Xavier <selvin.xavier@xxxxxxxxxxxx>
> ---
>  drivers/infiniband/hw/bnxt_re/Makefile   |   3 +-
>  drivers/infiniband/hw/bnxt_re/bnxt_re.h  |   2 +
>  drivers/infiniband/hw/bnxt_re/debugfs.c  | 141 +++++++++++++++++++++++++++++++
>  drivers/infiniband/hw/bnxt_re/debugfs.h  |  21 +++++
>  drivers/infiniband/hw/bnxt_re/ib_verbs.c |   4 +
>  drivers/infiniband/hw/bnxt_re/ib_verbs.h |   1 +
>  drivers/infiniband/hw/bnxt_re/main.c     |  13 ++-
>  7 files changed, 183 insertions(+), 2 deletions(-)
>  create mode 100644 drivers/infiniband/hw/bnxt_re/debugfs.c
>  create mode 100644 drivers/infiniband/hw/bnxt_re/debugfs.h
> 
> diff --git a/drivers/infiniband/hw/bnxt_re/Makefile b/drivers/infiniband/hw/bnxt_re/Makefile
> index ee9bb1b..f63417d 100644
> --- a/drivers/infiniband/hw/bnxt_re/Makefile
> +++ b/drivers/infiniband/hw/bnxt_re/Makefile
> @@ -4,4 +4,5 @@ ccflags-y := -I $(srctree)/drivers/net/ethernet/broadcom/bnxt
>  obj-$(CONFIG_INFINIBAND_BNXT_RE) += bnxt_re.o
>  bnxt_re-y := main.o ib_verbs.o \
>  	     qplib_res.o qplib_rcfw.o	\
> -	     qplib_sp.o qplib_fp.o  hw_counters.o
> +	     qplib_sp.o qplib_fp.o  hw_counters.o	\
> +	     debugfs.o
> diff --git a/drivers/infiniband/hw/bnxt_re/bnxt_re.h b/drivers/infiniband/hw/bnxt_re/bnxt_re.h
> index 311bb7c..7f931c7 100644
> --- a/drivers/infiniband/hw/bnxt_re/bnxt_re.h
> +++ b/drivers/infiniband/hw/bnxt_re/bnxt_re.h
> @@ -213,6 +213,8 @@ struct bnxt_re_dev {
>  	struct delayed_work dbq_pacing_work;
>  	DECLARE_HASHTABLE(cq_hash, MAX_CQ_HASH_BITS);
>  	DECLARE_HASHTABLE(srq_hash, MAX_SRQ_HASH_BITS);
> +	struct dentry			*dbg_root;
> +	struct dentry			*qp_debugfs;
>  };
>  
>  #define to_bnxt_re_dev(ptr, member)	\
> diff --git a/drivers/infiniband/hw/bnxt_re/debugfs.c b/drivers/infiniband/hw/bnxt_re/debugfs.c
> new file mode 100644
> index 0000000..dd38dd6c
> --- /dev/null
> +++ b/drivers/infiniband/hw/bnxt_re/debugfs.c
> @@ -0,0 +1,141 @@
> +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
> +/*
> + * Copyright (c) 2024, Broadcom. All rights reserved.  The term
> + * Broadcom refers to Broadcom Limited and/or its subsidiaries.
> + *
> + * Description: Debugfs component of the bnxt_re driver
> + */
> +
> +#include <linux/debugfs.h>
> +#include <linux/pci.h>
> +#include <rdma/ib_addr.h>
> +
> +#include "bnxt_ulp.h"
> +#include "roce_hsi.h"
> +#include "qplib_res.h"
> +#include "qplib_sp.h"
> +#include "qplib_fp.h"
> +#include "qplib_rcfw.h"
> +#include "bnxt_re.h"
> +#include "ib_verbs.h"
> +#include "debugfs.h"
> +
> +static struct dentry *bnxt_re_debugfs_root;
> +
> +static inline const char *bnxt_re_qp_state_str(u8 state)
> +{
> +	switch (state) {
> +	case CMDQ_MODIFY_QP_NEW_STATE_RESET:
> +		return "RST";
> +	case CMDQ_MODIFY_QP_NEW_STATE_INIT:
> +		return "INIT";
> +	case CMDQ_MODIFY_QP_NEW_STATE_RTR:
> +		return "RTR";
> +	case CMDQ_MODIFY_QP_NEW_STATE_RTS:
> +		return "RTS";
> +	case CMDQ_MODIFY_QP_NEW_STATE_SQE:
> +		return "SQER";
> +	case CMDQ_MODIFY_QP_NEW_STATE_SQD:
> +		return "SQD";
> +	case CMDQ_MODIFY_QP_NEW_STATE_ERR:
> +		return "ERR";
> +	default:
> +		return "Invalid QP state";
> +	}
> +}
> +
> +static inline const char *bnxt_re_qp_type_str(u8 type)
> +{
> +	switch (type) {
> +	case CMDQ_CREATE_QP1_TYPE_GSI: return "QP1";
> +	case CMDQ_CREATE_QP_TYPE_GSI: return "QP1";
> +	case CMDQ_CREATE_QP_TYPE_RC: return "RC";
> +	case CMDQ_CREATE_QP_TYPE_UD: return "UD";
> +	case CMDQ_CREATE_QP_TYPE_RAW_ETHERTYPE: return "RAW_ETHERTYPE";
> +	default: return "Invalid transport type";
> +	}
> +}
> +

Would it be better to use table-driven approach for these two functions?

> +static ssize_t qp_info_read(struct file *filep,
> +			    char __user *buffer,
> +			    size_t count, loff_t *ppos)
> +{
> +	struct bnxt_re_qp *qp = filep->private_data;
> +	char *buf;
> +	int len;
> +
> +	if (*ppos)
> +		return 0;
> +
> +	buf = kasprintf(GFP_KERNEL,
> +			"QPN\t\t: %d\n"
> +			"transport\t: %s\n"
> +			"state\t\t: %s\n"
> +			"mtu\t\t: %d\n"
> +			"timeout\t\t: %d\n"
> +			"remote QPN\t: %d\n",
> +			qp->qplib_qp.id,
> +			bnxt_re_qp_type_str(qp->qplib_qp.type),
> +			bnxt_re_qp_state_str(qp->qplib_qp.state),
> +			qp->qplib_qp.mtu,
> +			qp->qplib_qp.timeout,
> +			qp->qplib_qp.dest_qpn);
> +	if (!buf)
> +		return -ENOMEM;
> +	if (count < strlen(buf)) {
> +		kfree(buf);
> +		return -ENOSPC;
> +	}
> +	len = simple_read_from_buffer(buffer, count, ppos, buf, strlen(buf));
> +	kfree(buf);
> +	return len;
> +}
> +
> +static const struct file_operations debugfs_qp_fops = {
> +	.owner = THIS_MODULE,
> +	.open = simple_open,
> +	.read = qp_info_read,
> +};
> +
> +void bnxt_re_debug_add_qpinfo(struct bnxt_re_dev *rdev, struct bnxt_re_qp *qp)
> +{
> +	char resn[32];
> +
> +	sprintf(resn, "0x%x", qp->qplib_qp.id);
> +	qp->dentry = debugfs_create_file(resn, 0400, rdev->qp_debugfs, qp, &debugfs_qp_fops);
> +}
> +
> +void bnxt_re_debug_rem_qpinfo(struct bnxt_re_dev *rdev, struct bnxt_re_qp *qp)
> +{
> +	if (!bnxt_re_debugfs_root || !rdev->qp_debugfs)
> +		return;

debugfs functions can handle cases where the input dentry is an error,
so this checking is unnecessary.

Junxian

> +
> +	debugfs_remove(qp->dentry);> +}
> +
> +void bnxt_re_debugfs_add_pdev(struct bnxt_re_dev *rdev)
> +{
> +	struct pci_dev *pdev = rdev->en_dev->pdev;
> +
> +	rdev->dbg_root = debugfs_create_dir(dev_name(&pdev->dev), bnxt_re_debugfs_root);
> +
> +	rdev->qp_debugfs = debugfs_create_dir("QPs", rdev->dbg_root);
> +}
> +
> +void bnxt_re_debugfs_rem_pdev(struct bnxt_re_dev *rdev)
> +{
> +	debugfs_remove_recursive(rdev->qp_debugfs);
> +
> +	debugfs_remove_recursive(rdev->dbg_root);
> +	rdev->dbg_root = NULL;
> +}
> +
> +void bnxt_re_register_debugfs(void)
> +{
> +	bnxt_re_debugfs_root = debugfs_create_dir("bnxt_re", NULL);
> +}
> +
> +void bnxt_re_unregister_debugfs(void)
> +{
> +	debugfs_remove(bnxt_re_debugfs_root);
> +}
> diff --git a/drivers/infiniband/hw/bnxt_re/debugfs.h b/drivers/infiniband/hw/bnxt_re/debugfs.h
> new file mode 100644
> index 0000000..cd3be0a9
> --- /dev/null
> +++ b/drivers/infiniband/hw/bnxt_re/debugfs.h
> @@ -0,0 +1,21 @@
> +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
> +/*
> + * Copyright (c) 2024, Broadcom. All rights reserved.  The term
> + * Broadcom refers to Broadcom Limited and/or its subsidiaries.
> + *
> + * Description: Debugfs header
> + */
> +
> +#ifndef __BNXT_RE_DEBUGFS__
> +#define __BNXT_RE_DEBUGFS__
> +
> +void bnxt_re_debug_add_qpinfo(struct bnxt_re_dev *rdev, struct bnxt_re_qp *qp);
> +void bnxt_re_debug_rem_qpinfo(struct bnxt_re_dev *rdev, struct bnxt_re_qp *qp);
> +
> +void bnxt_re_debugfs_add_pdev(struct bnxt_re_dev *rdev);
> +void bnxt_re_debugfs_rem_pdev(struct bnxt_re_dev *rdev);
> +
> +void bnxt_re_register_debugfs(void);
> +void bnxt_re_unregister_debugfs(void);
> +
> +#endif
> diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
> index e66ae9f..10e96f1 100644
> --- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
> +++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
> @@ -62,6 +62,7 @@
>  
>  #include "bnxt_re.h"
>  #include "ib_verbs.h"
> +#include "debugfs.h"
>  
>  #include <rdma/uverbs_types.h>
>  #include <rdma/uverbs_std_types.h>
> @@ -939,6 +940,8 @@ int bnxt_re_destroy_qp(struct ib_qp *ib_qp, struct ib_udata *udata)
>  	else if (qp->qplib_qp.type == CMDQ_CREATE_QP_TYPE_UD)
>  		atomic_dec(&rdev->stats.res.ud_qp_count);
>  
> +	bnxt_re_debug_rem_qpinfo(rdev, qp);
> +
>  	ib_umem_release(qp->rumem);
>  	ib_umem_release(qp->sumem);
>  
> @@ -1622,6 +1625,7 @@ int bnxt_re_create_qp(struct ib_qp *ib_qp, struct ib_qp_init_attr *qp_init_attr,
>  		if (active_qps > rdev->stats.res.ud_qp_watermark)
>  			rdev->stats.res.ud_qp_watermark = active_qps;
>  	}
> +	bnxt_re_debug_add_qpinfo(rdev, qp);
>  
>  	return 0;
>  qp_destroy:
> diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.h b/drivers/infiniband/hw/bnxt_re/ib_verbs.h
> index b789e47..e02a5e7 100644
> --- a/drivers/infiniband/hw/bnxt_re/ib_verbs.h
> +++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.h
> @@ -95,6 +95,7 @@ struct bnxt_re_qp {
>  	struct ib_ud_header	qp1_hdr;
>  	struct bnxt_re_cq	*scq;
>  	struct bnxt_re_cq	*rcq;
> +	struct dentry		*dentry;
>  };
>  
>  struct bnxt_re_cq {
> diff --git a/drivers/infiniband/hw/bnxt_re/main.c b/drivers/infiniband/hw/bnxt_re/main.c
> index 0a18d24..04fa81e 100644
> --- a/drivers/infiniband/hw/bnxt_re/main.c
> +++ b/drivers/infiniband/hw/bnxt_re/main.c
> @@ -67,6 +67,7 @@
>  #include <rdma/bnxt_re-abi.h>
>  #include "bnxt.h"
>  #include "hw_counters.h"
> +#include "debugfs.h"
>  
>  static char version[] =
>  		BNXT_RE_DESC "\n";
> @@ -1870,6 +1871,8 @@ static void bnxt_re_dev_uninit(struct bnxt_re_dev *rdev, u8 op_type)
>  	u8 type;
>  	int rc;
>  
> +	bnxt_re_debugfs_rem_pdev(rdev);
> +
>  	if (test_and_clear_bit(BNXT_RE_FLAG_QOS_WORK_REG, &rdev->flags))
>  		cancel_delayed_work_sync(&rdev->worker);
>  
> @@ -2070,6 +2073,8 @@ static int bnxt_re_dev_init(struct bnxt_re_dev *rdev, u8 op_type)
>  	if (rdev->chip_ctx->modes.toggle_bits & BNXT_QPLIB_SRQ_TOGGLE_BIT)
>  		hash_init(rdev->srq_hash);
>  
> +	bnxt_re_debugfs_add_pdev(rdev);
> +
>  	return 0;
>  free_sctx:
>  	bnxt_re_net_stats_ctx_free(rdev, rdev->qplib_ctx.stats.fw_id);
> @@ -2389,18 +2394,24 @@ static int __init bnxt_re_mod_init(void)
>  	int rc;
>  
>  	pr_info("%s: %s", ROCE_DRV_MODULE_NAME, version);
> +	bnxt_re_register_debugfs();
> +
>  	rc = auxiliary_driver_register(&bnxt_re_driver);
>  	if (rc) {
>  		pr_err("%s: Failed to register auxiliary driver\n",
>  			ROCE_DRV_MODULE_NAME);
> -		return rc;
> +		goto err_debug;
>  	}
>  	return 0;
> +err_debug:
> +	bnxt_re_unregister_debugfs();
> +	return rc;
>  }
>  
>  static void __exit bnxt_re_mod_exit(void)
>  {
>  	auxiliary_driver_unregister(&bnxt_re_driver);
> +	bnxt_re_unregister_debugfs();
>  }
>  
>  module_init(bnxt_re_mod_init);




[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Photo]     [Yosemite News]     [Yosemite Photos]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux