This patch realizes the debugfs for hip08. Up to now, only query cqc and qpc are supported in this patch as examples. More functions will be supported later. the usage should be: $ cat cq_index $ echo N >cq_index $ cat cqc Signed-off-by: Tao Tian <tiantao6@xxxxxxxxxx> --- drivers/infiniband/hw/hns/Makefile | 4 +- drivers/infiniband/hw/hns/hns_roce_cmd.h | 1 + drivers/infiniband/hw/hns/hns_roce_debugfs.c | 120 +++++++++++++++++++++++++ drivers/infiniband/hw/hns/hns_roce_device.h | 17 ++++ drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 12 ++- drivers/infiniband/hw/hns/hns_roce_hw_v2.h | 11 +++ drivers/infiniband/hw/hns/hns_roce_hw_v2_dfx.c | 114 +++++++++++++++++++++++ drivers/infiniband/hw/hns/hns_roce_main.c | 2 + 8 files changed, 277 insertions(+), 4 deletions(-) create mode 100644 drivers/infiniband/hw/hns/hns_roce_debugfs.c create mode 100644 drivers/infiniband/hw/hns/hns_roce_hw_v2_dfx.c diff --git a/drivers/infiniband/hw/hns/Makefile b/drivers/infiniband/hw/hns/Makefile index cf03404..0cfb059 100644 --- a/drivers/infiniband/hw/hns/Makefile +++ b/drivers/infiniband/hw/hns/Makefile @@ -7,8 +7,8 @@ ccflags-y := -Idrivers/net/ethernet/hisilicon/hns3 obj-$(CONFIG_INFINIBAND_HNS) += hns-roce.o hns-roce-objs := hns_roce_main.o hns_roce_cmd.o hns_roce_pd.o \ hns_roce_ah.o hns_roce_hem.o hns_roce_mr.o hns_roce_qp.o \ - hns_roce_cq.o hns_roce_alloc.o hns_roce_db.o + hns_roce_cq.o hns_roce_alloc.o hns_roce_db.o hns_roce_debugfs.o obj-$(CONFIG_INFINIBAND_HNS_HIP06) += hns-roce-hw-v1.o hns-roce-hw-v1-objs := hns_roce_hw_v1.o obj-$(CONFIG_INFINIBAND_HNS_HIP08) += hns-roce-hw-v2.o -hns-roce-hw-v2-objs := hns_roce_hw_v2.o +hns-roce-hw-v2-objs := hns_roce_hw_v2.o hns_roce_hw_v2_dfx.o diff --git a/drivers/infiniband/hw/hns/hns_roce_cmd.h b/drivers/infiniband/hw/hns/hns_roce_cmd.h index 9549ae5..e93b6fb 100644 --- a/drivers/infiniband/hw/hns/hns_roce_cmd.h +++ b/drivers/infiniband/hw/hns/hns_roce_cmd.h @@ -53,6 +53,7 @@ enum { HNS_ROCE_CMD_QUERY_QPC = 0x42, HNS_ROCE_CMD_MODIFY_CQC = 0x52, + HNS_ROCE_CMD_QUERY_CQC = 0x53, /* CQC BT commands */ HNS_ROCE_CMD_WRITE_CQC_BT0 = 0x10, HNS_ROCE_CMD_WRITE_CQC_BT1 = 0x11, diff --git a/drivers/infiniband/hw/hns/hns_roce_debugfs.c b/drivers/infiniband/hw/hns/hns_roce_debugfs.c new file mode 100644 index 0000000..1d50216 --- /dev/null +++ b/drivers/infiniband/hw/hns/hns_roce_debugfs.c @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2018 Hisilicon Limited. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include <linux/debugfs.h> + +#include <linux/fs.h> +#include <linux/kernel.h> +#include <linux/seq_file.h> + +#include "hns_roce_device.h" +#include "hns_roce_hw_v2.h" + +static struct dentry *hns_roce_dbgfs_root; + +#define HNS_ROCE_FILE_DEFINE(name) \ +static int hns_roce_##name##_show(struct seq_file *s, void *v) \ +{ \ + struct hns_roce_dev *hdev = s->private; \ + int ret; \ + if (hdev->dfx->query_##name##_info) { \ + ret = hdev->dfx->query_##name##_info(hdev, s); \ + if (ret) \ + return ret; \ + } \ + return 0; \ +} \ +static int open_##name(struct inode *inode, struct file *file) \ +{ \ + return single_open(file, hns_roce_##name##_show, inode->i_private); \ +} \ +static const struct file_operations fops_##name = { \ + .open = open_##name, \ + .read = seq_read, \ + .llseek = seq_lseek, \ + .release = single_release, \ +} + +HNS_ROCE_FILE_DEFINE(cqc); +HNS_ROCE_FILE_DEFINE(qpc); + +void hns_roce_dbg_init(struct hns_roce_dev *hdev) +{ + struct dentry *pfile; + + hdev->hns_roce_dbgfs = debugfs_create_dir(dev_name(hdev->dev), + hns_roce_dbgfs_root); + if (!hdev->hns_roce_dbgfs) + return; + + pfile = debugfs_create_u32("cq_index", 0660, hdev->hns_roce_dbgfs, + &hdev->hr_stat.cqn); + if (!pfile) + goto create_failed; + + pfile = debugfs_create_file("cqc", 0600, hdev->hns_roce_dbgfs, hdev, + &fops_cqc); + if (!pfile) + goto create_failed; + + pfile = debugfs_create_u32("qp_index", 0660, hdev->hns_roce_dbgfs, + &hdev->hr_stat.qpn); + if (!pfile) + goto create_failed; + + pfile = debugfs_create_file("qpc", 0600, hdev->hns_roce_dbgfs, hdev, + &fops_qpc); + if (!pfile) + goto create_failed; + + return; + +create_failed: + dev_err(hdev->dev, "create file for %s fail\n", dev_name(hdev->dev)); + debugfs_remove_recursive(hdev->hns_roce_dbgfs); +} + +void hns_roce_register_debugfs(void) +{ + hns_roce_dbgfs_root = debugfs_create_dir("hns_roce", NULL); + if (!hns_roce_dbgfs_root) + return; + +} +EXPORT_SYMBOL(hns_roce_register_debugfs); + +void hns_roce_unregister_debugfs(void) +{ + debugfs_remove_recursive(hns_roce_dbgfs_root); +} +EXPORT_SYMBOL(hns_roce_unregister_debugfs); + diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h index d39bdfd..6ae3335 100644 --- a/drivers/infiniband/hw/hns/hns_roce_device.h +++ b/drivers/infiniband/hw/hns/hns_roce_device.h @@ -756,6 +756,16 @@ struct hns_roce_work { int sub_type; }; +struct hns_roce_stat { + u32 cqn; + u32 qpn; +}; + +struct hns_roce_dfx_hw { + int (*query_cqc_info)(struct hns_roce_dev *hr_dev, struct seq_file *s); + int (*query_qpc_info)(struct hns_roce_dev *hr_dev, struct seq_file *s); +}; + struct hns_roce_hw { int (*reset)(struct hns_roce_dev *hr_dev, bool enable); int (*cmq_init)(struct hns_roce_dev *hr_dev); @@ -851,6 +861,9 @@ struct hns_roce_dev { const struct hns_roce_hw *hw; void *priv; struct workqueue_struct *irq_workq; + struct hns_roce_stat hr_stat; + struct dentry *hns_roce_dbgfs; + const struct hns_roce_dfx_hw *dfx; }; static inline struct hns_roce_dev *to_hr_dev(struct ib_device *ib_dev) @@ -1056,4 +1069,8 @@ int hns_get_gid_index(struct hns_roce_dev *hr_dev, u8 port, int gid_index); int hns_roce_init(struct hns_roce_dev *hr_dev); void hns_roce_exit(struct hns_roce_dev *hr_dev); +void hns_roce_dbg_init(struct hns_roce_dev *hr_dev); +void hns_roce_register_debugfs(void); +void hns_roce_unregister_debugfs(void); + #endif /* _HNS_ROCE_DEVICE_H */ diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c index a4c62ae..7d6b13c 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c @@ -846,7 +846,7 @@ static void hns_roce_v2_cmq_exit(struct hns_roce_dev *hr_dev) hns_roce_free_cmq_desc(hr_dev, &priv->cmq.crq); } -static void hns_roce_cmq_setup_basic_desc(struct hns_roce_cmq_desc *desc, +void hns_roce_cmq_setup_basic_desc(struct hns_roce_cmq_desc *desc, enum hns_roce_opcode_type opcode, bool is_read) { @@ -892,7 +892,7 @@ static int hns_roce_cmq_csq_clean(struct hns_roce_dev *hr_dev) return clean; } -static int hns_roce_cmq_send(struct hns_roce_dev *hr_dev, +int hns_roce_cmq_send(struct hns_roce_dev *hr_dev, struct hns_roce_cmq_desc *desc, int num) { struct hns_roce_v2_priv *priv = (struct hns_roce_v2_priv *)hr_dev->priv; @@ -5340,6 +5340,11 @@ static void hns_roce_v2_cleanup_eq_table(struct hns_roce_dev *hr_dev) destroy_workqueue(hr_dev->irq_workq); } +static const struct hns_roce_dfx_hw hns_roce_dfx_hw_v2 = { + .query_cqc_info = hns_roce_v2_query_cqc_info, + .query_qpc_info = hns_roce_v2_query_qpc_info, +}; + static const struct hns_roce_hw hns_roce_hw_v2 = { .cmq_init = hns_roce_v2_cmq_init, .cmq_exit = hns_roce_v2_cmq_exit, @@ -5394,6 +5399,7 @@ static int hns_roce_hw_v2_get_cfg(struct hns_roce_dev *hr_dev, } hr_dev->hw = &hns_roce_hw_v2; + hr_dev->dfx = &hns_roce_dfx_hw_v2; hr_dev->sdb_offset = ROCEE_DB_SQ_L_0_REG; hr_dev->odb_offset = hr_dev->sdb_offset; @@ -5555,12 +5561,14 @@ static struct hnae3_client hns_roce_hw_v2_client = { static int __init hns_roce_hw_v2_init(void) { + hns_roce_register_debugfs(); return hnae3_register_client(&hns_roce_hw_v2_client); } static void __exit hns_roce_hw_v2_exit(void) { hnae3_unregister_client(&hns_roce_hw_v2_client); + hns_roce_unregister_debugfs(); } module_init(hns_roce_hw_v2_init); diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h index 8bc8206..b5ac81c 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h @@ -1612,4 +1612,15 @@ struct hns_roce_wqe_atomic_seg { __le64 cmp_data; }; +int hns_roce_v2_query_qpc_info(struct hns_roce_dev *hr_dev, + struct seq_file *s); +int hns_roce_v2_query_cqc_info(struct hns_roce_dev *hr_dev, + struct seq_file *s); + +void hns_roce_cmq_setup_basic_desc(struct hns_roce_cmq_desc *desc, + enum hns_roce_opcode_type opcode, + bool is_read); +int hns_roce_cmq_send(struct hns_roce_dev *hr_dev, + struct hns_roce_cmq_desc *desc, int num); + #endif diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2_dfx.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2_dfx.c new file mode 100644 index 0000000..d5760ee --- /dev/null +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2_dfx.c @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2018 Hisilicon Limited. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "hns_roce_device.h" +#include "hns_roce_cmd.h" +#include "hns_roce_hw_v2.h" + +static void hns_roce_print_obj_info(struct seq_file *s, int *obj, int len) +{ + int i; + + for (i = 0; i < len; i += 8) { + seq_printf(s, + "%08x %08x %08x %08x %08x %08x %08x %08x\n", + *obj, *(obj + 1), *(obj + 2), + *(obj + 3), *(obj + 4), *(obj + 5), + *(obj + 6), *(obj + 7)); + if (seq_has_overflowed(s)) + break; + obj += 8; + } +} + +int hns_roce_v2_query_qpc_info(struct hns_roce_dev *hr_dev, + struct seq_file *s) +{ + struct hns_roce_v2_qp_context *qp_context; + struct hns_roce_cmd_mailbox *mailbox; + int qpc_len; + int ret; + + mailbox = hns_roce_alloc_cmd_mailbox(hr_dev); + if (IS_ERR(mailbox)) + return PTR_ERR(mailbox); + + qp_context = mailbox->buf; + ret = hns_roce_cmd_mbox(hr_dev, 0, mailbox->dma, + hr_dev->hr_stat.qpn, 0, + HNS_ROCE_CMD_QUERY_QPC, + HNS_ROCE_CMD_TIMEOUT_MSECS); + if (ret) { + dev_err(hr_dev->dev, "QUERY qpc cmd process error\n"); + goto err_mailbox; + } + + qpc_len = sizeof(*qp_context) >> 2; + hns_roce_print_obj_info(s, (int *)qp_context, qpc_len); + +err_mailbox: + hns_roce_free_cmd_mailbox(hr_dev, mailbox); + + return ret; +} + +int hns_roce_v2_query_cqc_info(struct hns_roce_dev *hr_dev, + struct seq_file *s) +{ + struct hns_roce_v2_cq_context *cq_context; + struct hns_roce_cmd_mailbox *mailbox; + int cqc_len; + int ret; + + mailbox = hns_roce_alloc_cmd_mailbox(hr_dev); + if (IS_ERR(mailbox)) + return PTR_ERR(mailbox); + + cq_context = mailbox->buf; + ret = hns_roce_cmd_mbox(hr_dev, 0, mailbox->dma, + hr_dev->hr_stat.cqn, 0, + HNS_ROCE_CMD_QUERY_CQC, + HNS_ROCE_CMD_TIMEOUT_MSECS); + if (ret) { + dev_err(hr_dev->dev, "QUERY cqc cmd process error\n"); + goto err_mailbox; + } + + cqc_len = sizeof(*cq_context) >> 2; + hns_roce_print_obj_info(s, (int *)cq_context, cqc_len); + +err_mailbox: + hns_roce_free_cmd_mailbox(hr_dev, mailbox); + + return ret; +} + diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c b/drivers/infiniband/hw/hns/hns_roce_main.c index 1b3ee51..4129a8d 100644 --- a/drivers/infiniband/hw/hns/hns_roce_main.c +++ b/drivers/infiniband/hw/hns/hns_roce_main.c @@ -818,6 +818,8 @@ int hns_roce_init(struct hns_roce_dev *hr_dev) if (ret) goto error_failed_register_device; + hns_roce_dbg_init(hr_dev); + return 0; error_failed_register_device: -- 2.7.4