diff --git a/drivers/infiniband/hw/hns/hns_roce_cq.c b/drivers/infiniband/hw/hns/hns_roce_cq.c index 1858b0726c9f1b00102ac49913bf51724ea68d4e..cd058acfa10fd9c41b3f900fd4452bd044ce8b8b 100644 --- a/drivers/infiniband/hw/hns/hns_roce_cq.c +++ b/drivers/infiniband/hw/hns/hns_roce_cq.c @@ -464,12 +464,10 @@ int hns_roce_create_cq(struct ib_cq *ib_cq, const struct ib_cq_init_attr *attr, struct hns_roce_cq *hr_cq = to_hr_cq(ib_cq); struct ib_device *ibdev = &hr_dev->ib_dev; struct hns_roce_ib_create_cq ucmd = {}; - int ret; + int ret = -EOPNOTSUPP; - if (attr->flags) { - ret = -EOPNOTSUPP; + if (attr->flags) goto err_out; - } ret = verify_cq_create_attr(hr_dev, attr); if (ret) diff --git a/drivers/infiniband/hw/hns/hns_roce_debugfs.c b/drivers/infiniband/hw/hns/hns_roce_debugfs.c index 023b111997be5ee9a2e4b0934cbb7c1b3f988da2..d39e666d9a9785bfbb50059806f523ec69189c50 100644 --- a/drivers/infiniband/hw/hns/hns_roce_debugfs.c +++ b/drivers/infiniband/hw/hns/hns_roce_debugfs.c @@ -46,8 +46,6 @@ static void init_debugfs_seqfile(struct hns_debugfs_seqfile *seq, entry = debugfs_create_file(name, 0400, parent, seq, &hns_debugfs_seqfile_fops); - if (IS_ERR(entry)) - return; seq->read = read_fn; seq->data = data; @@ -85,11 +83,17 @@ struct hns_poe_debugfs { struct dentry *root; /* dev debugfs entry */ }; +struct hns_sw_stat_debugfs { + struct dentry *root; + struct hns_debugfs_seqfile sw_stat; +}; + /* Debugfs for device */ struct hns_roce_dev_debugfs { struct dentry *root; struct hns_dca_debugfs *dca_root; struct hns_poe_debugfs *poe_root; + struct hns_sw_stat_debugfs *sw_stat_root; }; struct dca_mem_stats { @@ -444,13 +448,8 @@ static void init_dca_ctx_debugfs(struct hns_dca_ctx_debugfs *dbgfs, { char name[DCA_CTX_PID_LEN]; - if (IS_ERR_OR_NULL(parent)) - return; - dca_setup_pool_name(uctx ? uctx->pid : 0, !uctx, name, sizeof(name)); dbgfs->root = debugfs_create_dir(name, parent); - if (IS_ERR_OR_NULL(dbgfs->root)) - return; if (uctx) { init_debugfs_seqfile(&dbgfs->mem, "mstats", dbgfs->root, @@ -477,18 +476,11 @@ create_dca_debugfs(struct hns_roce_dev *hr_dev, struct dentry *parent) { struct hns_dca_debugfs *dbgfs; - if (IS_ERR(parent)) - return NULL; - dbgfs = kzalloc(sizeof(*dbgfs), GFP_KERNEL); if (!dbgfs) return NULL; dbgfs->root = debugfs_create_dir("dca", parent); - if (IS_ERR_OR_NULL(dbgfs->root)) { - kfree(dbgfs); - return NULL; - } init_debugfs_seqfile(&dbgfs->pool, "pool", dbgfs->root, dca_debugfs_pool_show, hr_dev); @@ -634,24 +626,75 @@ void hns_roce_unregister_uctx_debugfs(struct hns_roce_dev *hr_dev, } } +static const char * const sw_stat_info[] = { + [HNS_ROCE_DFX_AEQE_CNT] = "aeqe", + [HNS_ROCE_DFX_CEQE_CNT] = "ceqe", + [HNS_ROCE_DFX_CMDS_CNT] = "cmds", + [HNS_ROCE_DFX_CMDS_ERR_CNT] = "cmds_err", + [HNS_ROCE_DFX_MBX_POSTED_CNT] = "posted_mbx", + [HNS_ROCE_DFX_MBX_POLLED_CNT] = "polled_mbx", + [HNS_ROCE_DFX_MBX_EVENT_CNT] = "mbx_event", + [HNS_ROCE_DFX_QP_CREATE_ERR_CNT] = "qp_create_err", + [HNS_ROCE_DFX_QP_MODIFY_ERR_CNT] = "qp_modify_err", + [HNS_ROCE_DFX_CQ_CREATE_ERR_CNT] = "cq_create_err", + [HNS_ROCE_DFX_CQ_MODIFY_ERR_CNT] = "cq_modify_err", + [HNS_ROCE_DFX_SRQ_CREATE_ERR_CNT] = "srq_create_err", + [HNS_ROCE_DFX_SRQ_MODIFY_ERR_CNT] = "srq_modify_err", + [HNS_ROCE_DFX_XRCD_ALLOC_ERR_CNT] = "xrcd_alloc_err", + [HNS_ROCE_DFX_MR_REG_ERR_CNT] = "mr_reg_err", + [HNS_ROCE_DFX_MR_REREG_ERR_CNT] = "mr_rereg_err", + [HNS_ROCE_DFX_AH_CREATE_ERR_CNT] = "ah_create_err", + [HNS_ROCE_DFX_MMAP_ERR_CNT] = "mmap_err", + [HNS_ROCE_DFX_UCTX_ALLOC_ERR_CNT] = "uctx_alloc_err", +}; + +static int sw_stat_debugfs_show(struct seq_file *file, void *offset) +{ + struct hns_roce_dev *hr_dev = file->private; + int i; + + for (i = 0; i < HNS_ROCE_DFX_CNT_TOTAL; i++) + seq_printf(file, "%-20s --- %lld\n", sw_stat_info[i], + atomic64_read(&hr_dev->dfx_cnt[i])); + + return 0; +} + +static struct hns_sw_stat_debugfs + *create_sw_stat_debugfs(struct hns_roce_dev *hr_dev, + struct dentry *parent) +{ + struct hns_sw_stat_debugfs *dbgfs; + + dbgfs = kvzalloc(sizeof(*dbgfs), GFP_KERNEL); + if (!dbgfs) + return NULL; + + dbgfs->root = debugfs_create_dir("sw_stat", parent); + + init_debugfs_seqfile(&dbgfs->sw_stat, "sw_stat", dbgfs->root, + sw_stat_debugfs_show, hr_dev); + return dbgfs; +} + +static void destroy_sw_stat_debugfs(struct hns_sw_stat_debugfs *sw_stat_dbgfs) +{ + cleanup_debugfs_seqfile(&sw_stat_dbgfs->sw_stat); + debugfs_remove_recursive(sw_stat_dbgfs->root); + kvfree(sw_stat_dbgfs); +} + /* debugfs for device */ void hns_roce_register_debugfs(struct hns_roce_dev *hr_dev) { struct hns_roce_dev_debugfs *dbgfs; - if (IS_ERR_OR_NULL(hns_roce_dbgfs_root)) - return; - dbgfs = kzalloc(sizeof(*dbgfs), GFP_KERNEL); if (!dbgfs) return; dbgfs->root = debugfs_create_dir(dev_name(&hr_dev->ib_dev.dev), hns_roce_dbgfs_root); - if (IS_ERR(dbgfs->root)) { - kfree(dbgfs); - return; - } if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_DCA_MODE) dbgfs->dca_root = create_dca_debugfs(hr_dev, dbgfs->root); @@ -659,6 +702,8 @@ void hns_roce_register_debugfs(struct hns_roce_dev *hr_dev) if (poe_is_supported(hr_dev)) dbgfs->poe_root = create_poe_debugfs(hr_dev, dbgfs->root); + dbgfs->sw_stat_root = create_sw_stat_debugfs(hr_dev, dbgfs->root); + hr_dev->dbgfs = dbgfs; } @@ -666,9 +711,6 @@ void hns_roce_unregister_debugfs(struct hns_roce_dev *hr_dev) { struct hns_roce_dev_debugfs *dbgfs; - if (IS_ERR_OR_NULL(hns_roce_dbgfs_root)) - return; - dbgfs = hr_dev->dbgfs; if (!dbgfs) return; @@ -683,6 +725,11 @@ void hns_roce_unregister_debugfs(struct hns_roce_dev *hr_dev) dbgfs->poe_root = NULL; } + if (dbgfs->sw_stat_root) { + destroy_sw_stat_debugfs(dbgfs->sw_stat_root); + dbgfs->sw_stat_root = NULL; + } + debugfs_remove_recursive(dbgfs->root); hr_dev->dbgfs = NULL; kfree(dbgfs); diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h index 146eafaec5bf305b0c733e765c31a48a49582aa3..ae9067e36bb2cbd5bf896ad68cc65c67bf235e46 100644 --- a/drivers/infiniband/hw/hns/hns_roce_device.h +++ b/drivers/infiniband/hw/hns/hns_roce_device.h @@ -994,7 +994,7 @@ enum hns_roce_hw_pkt_stat_index { HNS_ROCE_HW_CNT_TOTAL, }; -enum hns_roce_hw_dfx_stat_index { +enum hns_roce_sw_dfx_stat_index { HNS_ROCE_DFX_AEQE_CNT, HNS_ROCE_DFX_CEQE_CNT, HNS_ROCE_DFX_CMDS_CNT, @@ -1005,7 +1005,9 @@ enum hns_roce_hw_dfx_stat_index { HNS_ROCE_DFX_QP_CREATE_ERR_CNT, HNS_ROCE_DFX_QP_MODIFY_ERR_CNT, HNS_ROCE_DFX_CQ_CREATE_ERR_CNT, + HNS_ROCE_DFX_CQ_MODIFY_ERR_CNT, HNS_ROCE_DFX_SRQ_CREATE_ERR_CNT, + HNS_ROCE_DFX_SRQ_MODIFY_ERR_CNT, HNS_ROCE_DFX_XRCD_ALLOC_ERR_CNT, HNS_ROCE_DFX_MR_REG_ERR_CNT, HNS_ROCE_DFX_MR_REREG_ERR_CNT, diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c index 3702d866bc02d85885ab6b610de09c0ece036fb5..9064729b5d918769c72ccb99058eacc4e2e79615 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c @@ -6186,19 +6186,23 @@ static int hns_roce_v2_modify_srq(struct ib_srq *ibsrq, struct hns_roce_srq_context *srq_context; struct hns_roce_srq_context *srqc_mask; struct hns_roce_cmd_mailbox *mailbox; - int ret; + int ret = -EOPNOTSUPP; /* Resizing SRQs is not supported yet */ if (srq_attr_mask & IB_SRQ_MAX_WR) - return -EINVAL; + goto out; if (srq_attr_mask & IB_SRQ_LIMIT) { - if (srq_attr->srq_limit > srq->wqe_cnt) - return -EINVAL; + if (srq_attr->srq_limit > srq->wqe_cnt) { + ret = -EINVAL; + goto out; + } mailbox = hns_roce_alloc_cmd_mailbox(hr_dev); - if (IS_ERR(mailbox)) - return PTR_ERR(mailbox); + if (IS_ERR(mailbox)) { + ret = PTR_ERR(mailbox); + goto out; + } srq_context = mailbox->buf; srqc_mask = (struct hns_roce_srq_context *)mailbox->buf + 1; @@ -6211,15 +6215,17 @@ static int hns_roce_v2_modify_srq(struct ib_srq *ibsrq, ret = hns_roce_cmd_mbox(hr_dev, mailbox->dma, 0, HNS_ROCE_CMD_MODIFY_SRQC, srq->srqn); hns_roce_free_cmd_mailbox(hr_dev, mailbox); - if (ret) { + if (ret) ibdev_err(&hr_dev->ib_dev, "failed to handle cmd of modifying SRQ, ret = %d.\n", ret); - return ret; - } } - return 0; +out: + if (ret) + atomic64_inc(&hr_dev->dfx_cnt[HNS_ROCE_DFX_SRQ_MODIFY_ERR_CNT]); + + return ret; } static int hns_roce_v2_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr) @@ -6263,8 +6269,9 @@ static int hns_roce_v2_modify_cq(struct ib_cq *cq, u16 cq_count, u16 cq_period) int ret; mailbox = hns_roce_alloc_cmd_mailbox(hr_dev); - if (IS_ERR(mailbox)) - return PTR_ERR(mailbox); + ret = PTR_ERR_OR_ZERO(mailbox); + if (ret) + goto err_out; cq_context = mailbox->buf; cqc_mask = (struct hns_roce_v2_cq_context *)mailbox->buf + 1; @@ -6294,6 +6301,10 @@ static int hns_roce_v2_modify_cq(struct ib_cq *cq, u16 cq_count, u16 cq_period) "failed to process cmd when modifying CQ, ret = %d.\n", ret); +err_out: + if (ret) + atomic64_inc(&hr_dev->dfx_cnt[HNS_ROCE_DFX_CQ_MODIFY_ERR_CNT]); + return ret; } diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c b/drivers/infiniband/hw/hns/hns_roce_main.c index 239e08abd166a20016afdb96b0c6c5fdfd73d198..8641cb38cd07b07100c92a51a068208443bc6e55 100644 --- a/drivers/infiniband/hw/hns/hns_roce_main.c +++ b/drivers/infiniband/hw/hns/hns_roce_main.c @@ -786,30 +786,10 @@ static void hns_roce_get_fw_ver(struct ib_device *device, char *str) sub_minor); } -#define HNS_ROCE_DFX_STATS(ename, cname) \ - [HNS_ROCE_DFX_##ename##_CNT] = cname - #define HNS_ROCE_HW_CNT(ename, cname) \ - [HNS_ROCE_DFX_CNT_TOTAL + HNS_ROCE_HW_##ename##_CNT] = cname + [HNS_ROCE_HW_##ename##_CNT] = cname static const char *const hns_roce_port_stats_descs[] = { - HNS_ROCE_DFX_STATS(AEQE, "aeqe"), - HNS_ROCE_DFX_STATS(CEQE, "ceqe"), - HNS_ROCE_DFX_STATS(CMDS, "cmds"), - HNS_ROCE_DFX_STATS(CMDS_ERR, "cmds_err"), - HNS_ROCE_DFX_STATS(MBX_POSTED, "posted_mbx"), - HNS_ROCE_DFX_STATS(MBX_POLLED, "polled_mbx"), - HNS_ROCE_DFX_STATS(MBX_EVENT, "mbx_event"), - HNS_ROCE_DFX_STATS(QP_CREATE_ERR, "qp_create_err"), - HNS_ROCE_DFX_STATS(QP_MODIFY_ERR, "qp_modify_err"), - HNS_ROCE_DFX_STATS(CQ_CREATE_ERR, "cq_create_err"), - HNS_ROCE_DFX_STATS(SRQ_CREATE_ERR, "srq_create_err"), - HNS_ROCE_DFX_STATS(XRCD_ALLOC_ERR, "xrcd_alloc_err"), - HNS_ROCE_DFX_STATS(MR_REG_ERR, "mr_reg_err"), - HNS_ROCE_DFX_STATS(MR_REREG_ERR, "mr_rereg_err"), - HNS_ROCE_DFX_STATS(AH_CREATE_ERR, "ah_create_err"), - HNS_ROCE_DFX_STATS(MMAP_ERR, "mmap_err"), - HNS_ROCE_DFX_STATS(UCTX_ALLOC_ERR, "uctx_alloc_err"), HNS_ROCE_HW_CNT(RX_RC_PKT, "rx_rc_pkt"), HNS_ROCE_HW_CNT(RX_UC_PKT, "rx_uc_pkt"), HNS_ROCE_HW_CNT(RX_UD_PKT, "rx_ud_pkt"), @@ -838,21 +818,14 @@ static struct rdma_hw_stats *hns_roce_alloc_hw_port_stats(struct ib_device *devi u8 port_num) { struct hns_roce_dev *hr_dev = to_hr_dev(device); - int num_counters; if (port_num > hr_dev->caps.num_ports) { ibdev_err(device, "invalid port num.\n"); return NULL; } - if (hr_dev->pci_dev->revision >= PCI_REVISION_ID_HIP09 && - !hr_dev->is_vf) - num_counters = ARRAY_SIZE(hns_roce_port_stats_descs); - else - num_counters = HNS_ROCE_DFX_CNT_TOTAL; - return rdma_alloc_hw_stats_struct(hns_roce_port_stats_descs, - num_counters, + ARRAY_SIZE(hns_roce_port_stats_descs), RDMA_HW_STATS_DEFAULT_LIFESPAN); } @@ -861,9 +834,8 @@ static int hns_roce_get_hw_stats(struct ib_device *device, u8 port, int index) { struct hns_roce_dev *hr_dev = to_hr_dev(device); - int hw_counters = HNS_ROCE_HW_CNT_TOTAL; + int num_counters = HNS_ROCE_HW_CNT_TOTAL; int ret; - int i; if (port == 0) return 0; @@ -871,24 +843,15 @@ static int hns_roce_get_hw_stats(struct ib_device *device, if (port > hr_dev->caps.num_ports) return -EINVAL; - for (i = 0; i < HNS_ROCE_DFX_CNT_TOTAL; i++) - stats->value[i] = atomic64_read(&hr_dev->dfx_cnt[i]); - - if (hr_dev->pci_dev->revision <= PCI_REVISION_ID_HIP08 || - hr_dev->is_vf) - return HNS_ROCE_DFX_CNT_TOTAL; - - hw_counters = HNS_ROCE_HW_CNT_TOTAL; - ret = hr_dev->hw->query_hw_counter(hr_dev, - &stats->value[HNS_ROCE_DFX_CNT_TOTAL], - port, &hw_counters); + ret = hr_dev->hw->query_hw_counter(hr_dev, stats->value, port, + &num_counters); if (ret) { ibdev_err(device, "failed to query hw counter, ret = %d.\n", ret); return ret; } - return hw_counters + HNS_ROCE_DFX_CNT_TOTAL; + return num_counters; } static void hns_roce_unregister_device(struct hns_roce_dev *hr_dev, @@ -970,8 +933,6 @@ static const struct ib_device_ops hns_roce_dev_ops = { .query_pkey = hns_roce_query_pkey, .query_port = hns_roce_query_port, .reg_user_mr = hns_roce_reg_user_mr, - .alloc_hw_stats = hns_roce_alloc_hw_port_stats, - .get_hw_stats = hns_roce_get_hw_stats, .init_port = hns_roce_create_port_files, INIT_RDMA_OBJ_SIZE(ib_ah, hns_roce_ah, ibah), @@ -980,6 +941,11 @@ static const struct ib_device_ops hns_roce_dev_ops = { INIT_RDMA_OBJ_SIZE(ib_ucontext, hns_roce_ucontext, ibucontext), }; +static const struct ib_device_ops hns_roce_dev_hw_stats_ops = { + .alloc_hw_stats = hns_roce_alloc_hw_port_stats, + .get_hw_stats = hns_roce_get_hw_stats, +}; + static const struct ib_device_ops hns_roce_dev_mr_ops = { .rereg_user_mr = hns_roce_rereg_user_mr, }; @@ -1102,6 +1068,10 @@ static int hns_roce_register_device(struct hns_roce_dev *hr_dev) ib_set_device_ops(ib_dev, &hns_roce_dev_xrcd_ops); } + if (hr_dev->pci_dev->revision >= PCI_REVISION_ID_HIP09 && + !hr_dev->is_vf) + ib_set_device_ops(ib_dev, &hns_roce_dev_hw_stats_ops); + ib_set_device_ops(ib_dev, hr_dev->hw->hns_roce_dev_ops); ib_set_device_ops(ib_dev, &hns_roce_dev_ops); ib_set_device_ops(ib_dev, &hns_roce_dev_restrack_ops); @@ -1459,8 +1429,8 @@ static void hns_roce_unregister_poe_ch(struct hns_roce_dev *hr_dev) static int hns_roce_alloc_dfx_cnt(struct hns_roce_dev *hr_dev) { - hr_dev->dfx_cnt = kcalloc(HNS_ROCE_DFX_CNT_TOTAL, sizeof(atomic64_t), - GFP_KERNEL); + hr_dev->dfx_cnt = kvcalloc(HNS_ROCE_DFX_CNT_TOTAL, sizeof(atomic64_t), + GFP_KERNEL); if (!hr_dev->dfx_cnt) return -ENOMEM; @@ -1469,7 +1439,7 @@ static int hns_roce_alloc_dfx_cnt(struct hns_roce_dev *hr_dev) static void hns_roce_dealloc_dfx_cnt(struct hns_roce_dev *hr_dev) { - kfree(hr_dev->dfx_cnt); + kvfree(hr_dev->dfx_cnt); } int hns_roce_init(struct hns_roce_dev *hr_dev) @@ -1480,8 +1450,10 @@ int hns_roce_init(struct hns_roce_dev *hr_dev) hr_dev->is_reset = false; ret = hns_roce_alloc_dfx_cnt(hr_dev); - if (ret) + if (ret) { + dev_err(dev, "Alloc dfx_cnt failed!\n"); return ret; + } if (hr_dev->hw->cmq_init) { ret = hr_dev->hw->cmq_init(hr_dev); diff --git a/drivers/infiniband/hw/hns/hns_roce_pd.c b/drivers/infiniband/hw/hns/hns_roce_pd.c index 6c69e095aa01151f8ee57f8411687783d40b5396..4b95f16afeca7a0b097346f44b2353915140d4f9 100644 --- a/drivers/infiniband/hw/hns/hns_roce_pd.c +++ b/drivers/infiniband/hw/hns/hns_roce_pd.c @@ -146,7 +146,7 @@ int hns_roce_alloc_xrcd(struct ib_xrcd *ib_xrcd, struct ib_udata *udata) { struct hns_roce_dev *hr_dev = to_hr_dev(ib_xrcd->device); struct hns_roce_xrcd *xrcd = to_hr_xrcd(ib_xrcd); - int ret = -EINVAL; + int ret = -EOPNOTSUPP; if (!(hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_XRC)) goto err_out;