diff --git a/drivers/infiniband/hw/hns/hns_roce_cq.c b/drivers/infiniband/hw/hns/hns_roce_cq.c index 48c25b30a395105fef0a9fd32bb12801da74e108..e26926622f236da6e72c71ca9fcb110751f17dc7 100644 --- a/drivers/infiniband/hw/hns/hns_roce_cq.c +++ b/drivers/infiniband/hw/hns/hns_roce_cq.c @@ -179,8 +179,9 @@ static void free_cqc(struct hns_roce_dev *hr_dev, struct hns_roce_cq *hr_cq) ret = hns_roce_destroy_hw_ctx(hr_dev, HNS_ROCE_CMD_DESTROY_CQC, hr_cq->cqn); if (ret) - dev_err(dev, "DESTROY_CQ failed (%d) for CQN %06lx\n", ret, - hr_cq->cqn); + dev_err_ratelimited(dev, + "DESTROY_CQ failed (%d) for CQN %06lx\n", + ret, hr_cq->cqn); if (ret == -EBUSY) hr_cq->delayed_destroy_flag = true; @@ -223,6 +224,7 @@ static int alloc_cq_buf(struct hns_roce_dev *hr_dev, struct hns_roce_cq *hr_cq, if (ret) { ibdev_err(ibdev, "Failed to alloc CQ mtr, ret = %d\n", ret); kvfree(hr_cq->mtr_node); + hr_cq->mtr_node = NULL; } return ret; @@ -235,6 +237,7 @@ static void free_cq_buf(struct hns_roce_dev *hr_dev, struct hns_roce_cq *hr_cq) } else { hns_roce_mtr_destroy(hr_dev, &hr_cq->mtr); kvfree(hr_cq->mtr_node); + hr_cq->mtr_node = NULL; } } diff --git a/drivers/infiniband/hw/hns/hns_roce_dca.c b/drivers/infiniband/hw/hns/hns_roce_dca.c index e88603c96ae40d1730b011f8d35d9670d8a77958..ddc21f10b923373c8c6ed1e48bed278326425e3c 100644 --- a/drivers/infiniband/hw/hns/hns_roce_dca.c +++ b/drivers/infiniband/hw/hns/hns_roce_dca.c @@ -1529,6 +1529,11 @@ static int UVERBS_HANDLER(HNS_IB_METHOD_DCA_MEM_REG)( if (ret) return ret; + if (!init_attr.size) + return -EINVAL; + + init_attr.size = hr_hw_page_align(init_attr.size); + mem = alloc_dca_mem(to_hr_dca_ctx(hr_dev, uctx)); if (!mem) return -ENOMEM; diff --git a/drivers/infiniband/hw/hns/hns_roce_debugfs.c b/drivers/infiniband/hw/hns/hns_roce_debugfs.c index c8294a836ee3d72883931ca56cdb24a2f2db1fa6..85fa88e8a6572be7892f1e3188208b27351696cf 100644 --- a/drivers/infiniband/hw/hns/hns_roce_debugfs.c +++ b/drivers/infiniband/hw/hns/hns_roce_debugfs.c @@ -353,19 +353,19 @@ static void dca_stats_dev_qp_in_seqfile(struct hns_roce_dev *hr_dev, seq_printf(file, "%-10s %-10s %-10s %s\n", "QPN", "Size(kB)", "PID", "State"); - xa_lock(&hr_dev->qp_table_xa); + xa_lock_irq(&hr_dev->qp_table_xa); xa_for_each(&hr_dev->qp_table_xa, id, hr_qp) { stats.total_size = 0; dca_setup_qp_stats(hr_qp, &stats); if (!stats.total_size) continue; - xa_unlock(&hr_dev->qp_table_xa); + xa_unlock_irq(&hr_dev->qp_table_xa); seq_printf(file, "%-10u %-10u %-10s %-s\n", stats.qpn, stats.total_size / KB, stats.name, stats.state); - xa_lock(&hr_dev->qp_table_xa); + xa_lock_irq(&hr_dev->qp_table_xa); } - xa_unlock(&hr_dev->qp_table_xa); + xa_unlock_irq(&hr_dev->qp_table_xa); } static void dca_stats_ctx_qp_in_seqfile(struct hns_roce_dev *hr_dev, @@ -391,11 +391,11 @@ static void dca_stats_ctx_qp_in_seqfile(struct hns_roce_dev *hr_dev, dca_ctx_stats_qp(ctx, bitmap, nbits); for_each_set_bit(qpn, bitmap, nbits) { stats.total_size = 0; - xa_lock(&hr_dev->qp_table_xa); + xa_lock_irq(&hr_dev->qp_table_xa); hr_qp = __hns_roce_qp_lookup(hr_dev, qpn); if (hr_qp) dca_setup_qp_stats(hr_qp, &stats); - xa_unlock(&hr_dev->qp_table_xa); + xa_unlock_irq(&hr_dev->qp_table_xa); if (!stats.total_size) continue; diff --git a/drivers/infiniband/hw/hns/hns_roce_hem.c b/drivers/infiniband/hw/hns/hns_roce_hem.c index 709a446465a4ce58d8df70dbd667b5c504ee0d73..f6e4ecbcb1d38cab6bac3491390a44ab2a843881 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hem.c +++ b/drivers/infiniband/hw/hns/hns_roce_hem.c @@ -321,6 +321,7 @@ void hns_roce_free_hem(struct hns_roce_dev *hr_dev, struct hns_roce_hem *hem) return; list_for_each_entry_safe(chunk, tmp, &hem->chunk_list, list) { + list_del(&chunk->list); for (i = 0; i < chunk->npages; ++i) dma_free_coherent(hr_dev->dev, sg_dma_len(&chunk->mem[i]), @@ -712,8 +713,9 @@ void hns_roce_table_put(struct hns_roce_dev *hr_dev, ret = hr_dev->hw->clear_hem(hr_dev, table, obj, HEM_HOP_STEP_DIRECT); if (ret) - dev_warn(dev, "failed to clear HEM base address, ret = %d.\n", - ret); + dev_warn_ratelimited(dev, + "failed to clear HEM base address, ret = %d.\n", + ret); hns_roce_free_hem(hr_dev, table->hem[i]); table->hem[i] = NULL; diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c index 570675a3b541b4df58d7f88dbc62d7171d8b41dc..045fe899d953c8c465a53180e3a9ef8b094e95d7 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include @@ -452,20 +451,22 @@ static int check_send_valid(struct hns_roce_dev *hr_dev, if (unlikely(hr_qp->state == IB_QPS_RESET || hr_qp->state == IB_QPS_INIT || hr_qp->state == IB_QPS_RTR)) { - ibdev_err(ibdev, "failed to post WQE, QP state %u!\n", - hr_qp->state); + ibdev_err_ratelimited(ibdev, + "failed to post WQE, QP state %u!\n", + hr_qp->state); return -EINVAL; } else if (unlikely(hr_dev->state >= HNS_ROCE_DEVICE_STATE_RST_DOWN)) { - ibdev_err(ibdev, "failed to post WQE, dev state %d!\n", - hr_dev->state); + ibdev_err_ratelimited(ibdev, + "failed to post WQE, dev state %d!\n", + hr_dev->state); return -EIO; } if (check_dca_attach_enable(hr_qp)) { ret = dca_attach_qp_buf(hr_dev, hr_qp); if (unlikely(ret)) { - ibdev_err(ibdev, - "failed to attach DCA for QP-%ld send!\n", + ibdev_err_ratelimited(ibdev, + "failed to attach DCA for QP-%lu send!\n", hr_qp->qpn); return ret; } @@ -1146,14 +1147,9 @@ static u32 hns_roce_v2_cmd_hw_resetting(struct hns_roce_dev *hr_dev, unsigned long instance_stage, unsigned long reset_stage) { -#define HW_RESET_TIMEOUT_US 1000000 -#define HW_RESET_DELAY_US 1 - struct hns_roce_v2_priv *priv = hr_dev->priv; struct hnae3_handle *handle = priv->handle; const struct hnae3_ae_ops *ops = handle->ae_algo->ops; - unsigned long val; - int ret; /* When hardware reset is detected, we should stop sending mailbox&cmq& * doorbell to hardware. If now in .init_instance() function, we should @@ -1166,10 +1162,7 @@ static u32 hns_roce_v2_cmd_hw_resetting(struct hns_roce_dev *hr_dev, */ hr_dev->dis_db = true; - ret = read_poll_timeout_atomic(ops->ae_dev_reset_cnt, val, - val > hr_dev->reset_cnt, HW_RESET_DELAY_US, - HW_RESET_TIMEOUT_US, false, handle); - if (!ret) + if (!ops->get_hw_reset_stat(handle)) hr_dev->is_reset = true; if (!hr_dev->is_reset || reset_stage == HNS_ROCE_STATE_RST_INIT || @@ -3822,8 +3815,9 @@ static int free_mr_post_send_lp_wqe(struct hns_roce_qp *hr_qp) ret = hns_roce_v2_post_send(&hr_qp->ibqp, send_wr, &bad_wr); if (ret) { - ibdev_err(ibdev, "failed to post wqe for free mr, ret = %d.\n", - ret); + ibdev_err_ratelimited(ibdev, + "failed to post wqe for free mr, ret = %d.\n", + ret); return ret; } @@ -3862,7 +3856,7 @@ static void free_mr_send_cmd_to_hw(struct hns_roce_dev *hr_dev) ret = free_mr_post_send_lp_wqe(hr_qp); if (ret) { - ibdev_err(ibdev, + ibdev_err_ratelimited(ibdev, "failed to send wqe (qp:0x%lx) for free mr, ret = %d.\n", hr_qp->qpn, ret); break; @@ -3875,14 +3869,14 @@ static void free_mr_send_cmd_to_hw(struct hns_roce_dev *hr_dev) while (cqe_cnt) { npolled = hns_roce_v2_poll_cq(&free_mr->rsv_cq->ib_cq, cqe_cnt, wc); if (npolled < 0) { - ibdev_err(ibdev, + ibdev_err_ratelimited(ibdev, "failed to poll cqe for free mr, remain %d cqe.\n", cqe_cnt); goto out; } if (time_after(jiffies, end)) { - ibdev_err(ibdev, + ibdev_err_ratelimited(ibdev, "failed to poll cqe for free mr and timeout, remain %d cqe.\n", cqe_cnt); goto out; @@ -5544,7 +5538,8 @@ static int hns_roce_v2_set_abs_fields(struct ib_qp *ibqp, int ret = 0; if (!check_qp_state(cur_state, new_state)) { - ibdev_err(&hr_dev->ib_dev, "Illegal state for QP!\n"); + ibdev_err_ratelimited(&hr_dev->ib_dev, + "Illegal state for QP!\n"); return -EINVAL; } @@ -5804,7 +5799,7 @@ static int hns_roce_v2_modify_qp(struct ib_qp *ibqp, /* SW pass context to HW */ ret = hns_roce_v2_qp_modify(hr_dev, context, qpc_mask, hr_qp); if (ret) { - ibdev_err(ibdev, "failed to modify QP, ret = %d.\n", ret); + ibdev_err_ratelimited(ibdev, "failed to modify QP, ret = %d.\n", ret); goto out; } @@ -5989,7 +5984,9 @@ static int hns_roce_v2_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr, ret = hns_roce_v2_query_qpc(hr_dev, hr_qp->qpn, &context); if (ret) { - ibdev_err(ibdev, "failed to query QPC, ret = %d.\n", ret); + ibdev_err_ratelimited(ibdev, + "failed to query QPC, ret = %d.\n", + ret); ret = -EINVAL; goto out; } @@ -5997,7 +5994,7 @@ static int hns_roce_v2_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr, state = hr_reg_read(&context, QPC_QP_ST); tmp_qp_state = to_ib_qp_st((enum hns_roce_v2_qp_state)state); if (tmp_qp_state == -1) { - ibdev_err(ibdev, "Illegal ib_qp_state\n"); + ibdev_err_ratelimited(ibdev, "Illegal ib_qp_state\n"); ret = -EINVAL; goto out; } @@ -6079,7 +6076,9 @@ static bool hns_roce_v2_chk_dca_buf_inactive(struct hns_roce_dev *hr_dev, ret = hns_roce_v2_query_qpc(hr_dev, hr_qp->qpn, &context); if (ret) { - ibdev_err(ibdev, "failed to query DCA QPC, ret = %d.\n", ret); + ibdev_err_ratelimited(ibdev, + "failed to query DCA QPC, ret = %d.\n", + ret); return false; } @@ -6123,7 +6122,7 @@ int hns_roce_v2_destroy_qp_common(struct hns_roce_dev *hr_dev, ret = hns_roce_v2_modify_qp(&hr_qp->ibqp, NULL, 0, hr_qp->state, IB_QPS_RESET, udata); if (ret) - ibdev_err(ibdev, + ibdev_err_ratelimited(ibdev, "failed to modify QP to RST, ret = %d.\n", ret); } @@ -6161,7 +6160,7 @@ int hns_roce_v2_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata) ret = hns_roce_v2_destroy_qp_common(hr_dev, hr_qp, udata); if (ret) - ibdev_err(&hr_dev->ib_dev, + ibdev_err_ratelimited(&hr_dev->ib_dev, "failed to destroy QP, QPN = 0x%06lx, ret = %d.\n", hr_qp->qpn, ret); @@ -6460,7 +6459,7 @@ static int hns_roce_v2_modify_cq(struct ib_cq *cq, u16 cq_count, u16 cq_period) HNS_ROCE_CMD_MODIFY_CQC, hr_cq->cqn); hns_roce_free_cmd_mailbox(hr_dev, mailbox); if (ret) - ibdev_err(&hr_dev->ib_dev, + ibdev_err_ratelimited(&hr_dev->ib_dev, "failed to process cmd when modifying CQ, ret = %d.\n", ret); @@ -6486,9 +6485,9 @@ static int hns_roce_v2_query_cqc(struct hns_roce_dev *hr_dev, u32 cqn, ret = hns_roce_cmd_mbox(hr_dev, 0, mailbox->dma, HNS_ROCE_CMD_QUERY_CQC, cqn); if (ret) { - ibdev_err(&hr_dev->ib_dev, - "failed to process cmd when querying CQ, ret = %d.\n", - ret); + ibdev_err_ratelimited(&hr_dev->ib_dev, + "failed to process cmd when querying CQ, ret = %d.\n", + ret); goto err_mailbox; } @@ -7383,6 +7382,9 @@ static int hns_roce_v2_query_scc_param(struct hns_roce_dev *hr_dev, struct hns_roce_port *pdata; int ret; + if (hr_dev->pci_dev->revision <= PCI_REVISION_ID_HIP08 || hr_dev->is_vf) + return -EOPNOTSUPP; + if (port_num > hr_dev->caps.num_ports) { ibdev_err_ratelimited(&hr_dev->ib_dev, "invalid port num %u.\n", port_num); diff --git a/drivers/infiniband/hw/hns/hns_roce_mr.c b/drivers/infiniband/hw/hns/hns_roce_mr.c index 68049467a721d3302040540fd538b189e81f8978..3c36836dcf4972e68ce8213c433122d740dfb9e2 100644 --- a/drivers/infiniband/hw/hns/hns_roce_mr.c +++ b/drivers/infiniband/hw/hns/hns_roce_mr.c @@ -122,6 +122,7 @@ static int alloc_mr_pbl(struct hns_roce_dev *hr_dev, struct hns_roce_mr *mr, if (err) { ibdev_err(ibdev, "failed to alloc pbl mtr, ret = %d.\n", err); kvfree(mr->mtr_node); + mr->mtr_node = NULL; return err; } @@ -138,6 +139,7 @@ static void free_mr_pbl(struct hns_roce_dev *hr_dev, struct hns_roce_mr *mr) } else { hns_roce_mtr_destroy(hr_dev, &mr->pbl_mtr); kvfree(mr->mtr_node); + mr->mtr_node = NULL; } } @@ -151,7 +153,7 @@ static void hns_roce_mr_free(struct hns_roce_dev *hr_dev, struct hns_roce_mr *mr key_to_hw_index(mr->key) & (hr_dev->caps.num_mtpts - 1)); if (ret) - ibdev_warn(ibdev, "failed to destroy mpt, ret = %d.\n", + ibdev_warn_ratelimited(ibdev, "failed to destroy mpt, ret = %d.\n", ret); if (ret == -EBUSY) mr->delayed_destroy_flag = true; diff --git a/drivers/infiniband/hw/hns/hns_roce_qp.c b/drivers/infiniband/hw/hns/hns_roce_qp.c index 4989828b5badb93bf8d92ab1ec62af191037c4da..bb0460e7db950f1e68c50eeb71eaee2d2e75f8cf 100644 --- a/drivers/infiniband/hw/hns/hns_roce_qp.c +++ b/drivers/infiniband/hw/hns/hns_roce_qp.c @@ -798,6 +798,7 @@ static int alloc_wqe_buf(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp, ibdev_err(ibdev, "failed to enable DCA, ret = %d.\n", ret); kvfree(hr_qp->mtr_node); + hr_qp->mtr_node = NULL; return ret; } @@ -822,6 +823,7 @@ static int alloc_wqe_buf(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp, if (dca_en) hns_roce_disable_dca(hr_dev, hr_qp, udata); kvfree(hr_qp->mtr_node); + hr_qp->mtr_node = NULL; } return ret; @@ -835,6 +837,7 @@ static void free_wqe_buf(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp, } else { hns_roce_mtr_destroy(hr_dev, &hr_qp->mtr); kvfree(hr_qp->mtr_node); + hr_qp->mtr_node = NULL; } if (hr_qp->en_flags & HNS_ROCE_QP_CAP_DYNAMIC_CTX_ATTACH) diff --git a/drivers/infiniband/hw/hns/hns_roce_srq.c b/drivers/infiniband/hw/hns/hns_roce_srq.c index 4779232ee3184a55aa112959576601fa54f6b9ec..cf7b0d51683a0719fb42d67a23745342f3feec29 100644 --- a/drivers/infiniband/hw/hns/hns_roce_srq.c +++ b/drivers/infiniband/hw/hns/hns_roce_srq.c @@ -162,8 +162,9 @@ static void free_srqc(struct hns_roce_dev *hr_dev, struct hns_roce_srq *srq) ret = hns_roce_destroy_hw_ctx(hr_dev, HNS_ROCE_CMD_DESTROY_SRQ, srq->srqn); if (ret) - dev_err(hr_dev->dev, "DESTROY_SRQ failed (%d) for SRQN %06lx\n", - ret, srq->srqn); + dev_err_ratelimited(hr_dev->dev, + "DESTROY_SRQ failed (%d) for SRQN %06lx\n", + ret, srq->srqn); if (ret == -EBUSY) srq->delayed_destroy_flag = true; @@ -221,6 +222,7 @@ static int alloc_srq_idx(struct hns_roce_dev *hr_dev, struct hns_roce_srq *srq, hns_roce_mtr_destroy(hr_dev, &idx_que->mtr); err_kvmalloc: kvfree(idx_que->mtr_node); + idx_que->mtr_node = NULL; return ret; } @@ -236,6 +238,7 @@ static void free_srq_idx(struct hns_roce_dev *hr_dev, struct hns_roce_srq *srq) } else { hns_roce_mtr_destroy(hr_dev, &idx_que->mtr); kvfree(idx_que->mtr_node); + idx_que->mtr_node = NULL; } } @@ -268,6 +271,7 @@ static int alloc_srq_wqe_buf(struct hns_roce_dev *hr_dev, ibdev_err(ibdev, "failed to alloc SRQ buf mtr, ret = %d.\n", ret); kvfree(srq->mtr_node); + srq->mtr_node = NULL; } return ret; @@ -281,6 +285,7 @@ static void free_srq_wqe_buf(struct hns_roce_dev *hr_dev, } else { hns_roce_mtr_destroy(hr_dev, &srq->buf_mtr); kvfree(srq->mtr_node); + srq->mtr_node = NULL; } } diff --git a/drivers/infiniband/hw/hns/hns_roce_sysfs.c b/drivers/infiniband/hw/hns/hns_roce_sysfs.c index a51423b94dc1729e2a1b0a4eb3ce0af24e1be9a9..0262ec6716f16017e8457be09b4580446c7e0113 100644 --- a/drivers/infiniband/hw/hns/hns_roce_sysfs.c +++ b/drivers/infiniband/hw/hns/hns_roce_sysfs.c @@ -26,6 +26,22 @@ static void scc_param_config_work(struct work_struct *work) scc_param->algo_type); } +static void get_default_scc_param(struct hns_roce_dev *hr_dev, + struct hns_roce_port *pdata) +{ + int ret; + int i; + + for (i = 0; i < HNS_ROCE_SCC_ALGO_TOTAL; i++) { + pdata->scc_param[i].timestamp = jiffies; + ret = hr_dev->hw->query_scc_param(hr_dev, pdata->port_num, i); + if (ret && ret != -EOPNOTSUPP) + ibdev_warn_ratelimited(&hr_dev->ib_dev, + "failed to get default parameters of scc algo %d, ret = %d.\n", + i, ret); + } +} + static int alloc_scc_param(struct hns_roce_dev *hr_dev, struct hns_roce_port *pdata) { @@ -39,7 +55,6 @@ static int alloc_scc_param(struct hns_roce_dev *hr_dev, for (i = 0; i < HNS_ROCE_SCC_ALGO_TOTAL; i++) { scc_param[i].algo_type = i; - scc_param[i].timestamp = jiffies; scc_param[i].hr_dev = hr_dev; scc_param[i].port_num = pdata->port_num; INIT_DELAYED_WORK(&scc_param[i].scc_cfg_dwork, @@ -47,6 +62,9 @@ static int alloc_scc_param(struct hns_roce_dev *hr_dev, } pdata->scc_param = scc_param; + + get_default_scc_param(hr_dev, pdata); + return 0; } @@ -75,7 +93,6 @@ static ssize_t scc_attr_show(struct hns_roce_port *pdata, struct hns_port_cc_attr *scc_attr = container_of(attr, struct hns_port_cc_attr, port_attr); struct hns_roce_scc_param *scc_param; - unsigned long exp_time; __le32 val = 0; int ret; @@ -85,18 +102,6 @@ static ssize_t scc_attr_show(struct hns_roce_port *pdata, scc_param = &pdata->scc_param[scc_attr->algo_type]; - /* Only HW param need be queried */ - if (scc_attr->offset < offsetof(typeof(*scc_param), lifespan)) { - exp_time = scc_param->timestamp + - msecs_to_jiffies(scc_param->lifespan); - - if (time_is_before_eq_jiffies(exp_time)) { - scc_param->timestamp = jiffies; - pdata->hr_dev->hw->query_scc_param(pdata->hr_dev, - pdata->port_num, scc_attr->algo_type); - } - } - memcpy(&val, (void *)scc_param + scc_attr->offset, scc_attr->size); return sysfs_emit(buf, "%u\n", le32_to_cpu(val));