Unverified Commit d12310fd authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!6261 RDMA/hns: Some bugfixes and cleanups

Merge Pull Request from: @stinft 
 
Upload some bugfixes and cleanups from mainline linux.
 Chengchang Tang (5):
   RDMA/hns: Remove unused parameters and variables
   RDMA/hns: Fix deadlock on SRQ async events.
   RDMA/hns: Fix UAF for cq async event
   RDMA/hns: Fix GMV table pagesize
   RDMA/hns: Modify the print level of CQE error
 Yangyang Li (1):
   RDMA/hns: Use macro instead of magic number
 Zhengchao Shao (1):
 19   RDMA/hns: Fix return value in hns_roce_map_mr_sg
 wenglianfa (2):
   RDMA/hns: Fix mismatch exception rollback
   RDMA/hns: Add mutex_destroy()
https://gitee.com/openeuler/kernel/issues/I9GZX2
 
 
Link:https://gitee.com/openeuler/kernel/pulls/6261

 

Reviewed-by: default avatarChengchang Tang <tangchengchang@huawei.com>
Signed-off-by: default avatarXie XiuQi <xiexiuqi@huawei.com>
Acked-by: default avatarXie XiuQi <xiexiuqi@huawei.com>
parents a01bd327 e031d944
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -153,8 +153,7 @@ int hns_roce_get_kmem_bufs(struct hns_roce_dev *hr_dev, dma_addr_t *bufs,
	return total;
}

int hns_roce_get_umem_bufs(struct hns_roce_dev *hr_dev, dma_addr_t *bufs,
			   int buf_cnt, struct ib_umem *umem,
int hns_roce_get_umem_bufs(dma_addr_t *bufs, int buf_cnt, struct ib_umem *umem,
			   unsigned int page_shift)
{
	struct ib_block_iter biter;
+14 −10
Original line number Diff line number Diff line
@@ -149,7 +149,7 @@ static int alloc_cqc(struct hns_roce_dev *hr_dev, struct hns_roce_cq *hr_cq)
		return ret;
	}

	ret = xa_err(xa_store(&cq_table->array, hr_cq->cqn, hr_cq, GFP_KERNEL));
	ret = xa_err(xa_store_irq(&cq_table->array, hr_cq->cqn, hr_cq, GFP_KERNEL));
	if (ret) {
		ibdev_err(ibdev, "failed to xa_store CQ, ret = %d.\n", ret);
		goto err_put;
@@ -163,7 +163,7 @@ static int alloc_cqc(struct hns_roce_dev *hr_dev, struct hns_roce_cq *hr_cq)
	return 0;

err_xa:
	xa_erase(&cq_table->array, hr_cq->cqn);
	xa_erase_irq(&cq_table->array, hr_cq->cqn);
err_put:
	hns_roce_table_put(hr_dev, &cq_table->table, hr_cq->cqn);

@@ -186,6 +186,7 @@ static void free_cqc(struct hns_roce_dev *hr_dev, struct hns_roce_cq *hr_cq)
		hr_cq->delayed_destroy_flag = true;

	xa_erase(&cq_table->array, hr_cq->cqn);
	xa_erase_irq(&cq_table->array, hr_cq->cqn);

	/* Waiting interrupt process procedure carried out */
	synchronize_irq(hr_dev->eq_table.eq[hr_cq->vector].irq);
@@ -497,13 +498,6 @@ void hns_roce_cq_event(struct hns_roce_dev *hr_dev, u32 cqn, int event_type)
	struct ib_event event;
	struct ib_cq *ibcq;

	hr_cq = xa_load(&hr_dev->cq_table.array,
			cqn & (hr_dev->caps.num_cqs - 1));
	if (!hr_cq) {
		dev_warn(dev, "async event for bogus CQ 0x%06x\n", cqn);
		return;
	}

	if (event_type != HNS_ROCE_EVENT_TYPE_CQ_ID_INVALID &&
	    event_type != HNS_ROCE_EVENT_TYPE_CQ_ACCESS_ERROR &&
	    event_type != HNS_ROCE_EVENT_TYPE_CQ_OVERFLOW) {
@@ -512,7 +506,16 @@ void hns_roce_cq_event(struct hns_roce_dev *hr_dev, u32 cqn, int event_type)
		return;
	}

	xa_lock(&hr_dev->cq_table.array);
	hr_cq = xa_load(&hr_dev->cq_table.array,
			cqn & (hr_dev->caps.num_cqs - 1));
	if (hr_cq)
		refcount_inc(&hr_cq->refcount);
	xa_unlock(&hr_dev->cq_table.array);
	if (!hr_cq) {
		dev_warn(dev, "async event for bogus CQ 0x%06x\n", cqn);
		return;
	}

	ibcq = &hr_cq->ib_cq;
	if (ibcq->event_handler) {
@@ -555,4 +558,5 @@ void hns_roce_cleanup_cq_table(struct hns_roce_dev *hr_dev)

	for (i = 0; i < HNS_ROCE_CQ_BANK_NUM; i++)
		ida_destroy(&hr_dev->cq_table.bank[i].ida);
	mutex_destroy(&hr_dev->cq_table.bank_mutex);
}
+2 −3
Original line number Diff line number Diff line
@@ -1021,8 +1021,7 @@ struct hns_roce_hw {
	int (*rereg_write_mtpt)(struct hns_roce_dev *hr_dev,
				struct hns_roce_mr *mr, int flags,
				void *mb_buf);
	int (*frmr_write_mtpt)(struct hns_roce_dev *hr_dev, void *mb_buf,
			       struct hns_roce_mr *mr);
	int (*frmr_write_mtpt)(void *mb_buf, struct hns_roce_mr *mr);
	int (*mw_write_mtpt)(void *mb_buf, struct hns_roce_mw *mw);
	void (*write_cqc)(struct hns_roce_dev *hr_dev,
			  struct hns_roce_cq *hr_cq, void *mb_buf, u64 *mtts,
@@ -1389,7 +1388,7 @@ struct hns_roce_buf *hns_roce_buf_alloc(struct hns_roce_dev *hr_dev, u32 size,
int hns_roce_get_kmem_bufs(struct hns_roce_dev *hr_dev, dma_addr_t *bufs,
			   int buf_cnt, struct hns_roce_buf *buf,
			   unsigned int page_shift);
int hns_roce_get_umem_bufs(struct hns_roce_dev *hr_dev, dma_addr_t *bufs,
int hns_roce_get_umem_bufs(dma_addr_t *bufs,
			   int buf_cnt, struct ib_umem *umem,
			   unsigned int page_shift);

+8 −9
Original line number Diff line number Diff line
@@ -281,7 +281,7 @@ static struct hns_roce_hem *hns_roce_alloc_hem(struct hns_roce_dev *hr_dev,
	return hem;

fail:
	hns_roce_free_hem(hr_dev, hem);
	kfree(hem);
	return NULL;
}

@@ -878,6 +878,7 @@ void hns_roce_cleanup_hem_table(struct hns_roce_dev *hr_dev,

	if (hns_roce_check_whether_mhop(hr_dev, table->type)) {
		hns_roce_cleanup_mhop_hem_table(hr_dev, table);
		mutex_destroy(&table->mutex);
		return;
	}

@@ -892,6 +893,7 @@ void hns_roce_cleanup_hem_table(struct hns_roce_dev *hr_dev,
			hns_roce_free_hem(hr_dev, table->hem[i]);
		}

	mutex_destroy(&table->mutex);
	kfree(table->hem);
}

@@ -987,15 +989,13 @@ static void hem_list_free_all(struct hns_roce_dev *hr_dev,
	}
}

static void hem_list_link_bt(struct hns_roce_dev *hr_dev, void *base_addr,
			     u64 table_addr)
static void hem_list_link_bt(void *base_addr, u64 table_addr)
{
	*(u64 *)(base_addr) = table_addr;
}

/* assign L0 table address to hem from root bt */
static void hem_list_assign_bt(struct hns_roce_dev *hr_dev,
			       struct hns_roce_hem_item *hem, void *cpu_addr,
static void hem_list_assign_bt(struct hns_roce_hem_item *hem, void *cpu_addr,
			       u64 phy_addr)
{
	hem->addr = cpu_addr;
@@ -1164,8 +1164,7 @@ static int hem_list_alloc_mid_bt(struct hns_roce_dev *hr_dev,
		if (level > 1) {
			pre = hem_ptrs[level - 1];
			step = (cur->start - pre->start) / step * BA_BYTE_LEN;
			hem_list_link_bt(hr_dev, pre->addr + step,
					 cur->dma_addr);
			hem_list_link_bt(pre->addr + step, cur->dma_addr);
		}
	}

@@ -1223,7 +1222,7 @@ static int alloc_fake_root_bt(struct hns_roce_dev *hr_dev, void *cpu_base,
	if (!hem)
		return -ENOMEM;

	hem_list_assign_bt(hr_dev, hem, cpu_base, phy_base);
	hem_list_assign_bt(hem, cpu_base, phy_base);
	list_add(&hem->list, branch_head);
	list_add(&hem->sibling, leaf_head);

@@ -1246,7 +1245,7 @@ static int setup_middle_bt(struct hns_roce_dev *hr_dev, void *cpu_base,
	/* if exist mid bt, link L1 to L0 */
	list_for_each_entry_safe(hem, temp_hem, branch_head, list) {
		offset = (hem->start - r->offset) / step * BA_BYTE_LEN;
		hem_list_link_bt(hr_dev, cpu_base + offset, hem->dma_addr);
		hem_list_link_bt(cpu_base + offset, hem->dma_addr);
		total++;
	}

+35 −32
Original line number Diff line number Diff line
@@ -2260,7 +2260,7 @@ static void apply_func_caps(struct hns_roce_dev *hr_dev)
					 caps->gmv_bt_num *
					 (HNS_HW_PAGE_SIZE / caps->gmv_entry_sz));

		caps->gmv_entry_num = caps->gmv_bt_num * (PAGE_SIZE /
		caps->gmv_entry_num = caps->gmv_bt_num * (HNS_HW_PAGE_SIZE /
							  caps->gmv_entry_sz);
	} else {
		u32 func_num = max_t(u32, 1, hr_dev->func_num);
@@ -2856,6 +2856,8 @@ static void free_mr_exit(struct hns_roce_dev *hr_dev)
		kfree(free_mr->rsv_pd);
		free_mr->rsv_pd = NULL;
	}

	mutex_destroy(&free_mr->mutex);
}

static int free_mr_alloc_res(struct hns_roce_dev *hr_dev)
@@ -3006,8 +3008,10 @@ static int free_mr_init(struct hns_roce_dev *hr_dev)
	mutex_init(&free_mr->mutex);

	ret = free_mr_alloc_res(hr_dev);
	if (ret)
	if (ret) {
		mutex_destroy(&free_mr->mutex);
		return ret;
	}

	ret = free_mr_modify_qp(hr_dev);
	if (ret)
@@ -3433,13 +3437,14 @@ static int set_mtpt_pbl(struct hns_roce_dev *hr_dev,

	/* Aligned to the hardware address access unit */
	for (i = 0; i < ARRAY_SIZE(pages); i++)
		pages[i] >>= 6;
		pages[i] >>= MPT_PBL_BUF_ADDR_S;

	pbl_ba = hns_roce_get_mtr_ba(&mr->pbl_mtr);

	mpt_entry->pbl_size = cpu_to_le32(mr->npages);
	mpt_entry->pbl_ba_l = cpu_to_le32(pbl_ba >> 3);
	hr_reg_write(mpt_entry, MPT_PBL_BA_H, upper_32_bits(pbl_ba >> 3));
	mpt_entry->pbl_ba_l = cpu_to_le32(pbl_ba >> MPT_PBL_BA_ADDR_S);
	hr_reg_write(mpt_entry, MPT_PBL_BA_H,
		     upper_32_bits(pbl_ba >> MPT_PBL_BA_ADDR_S));

	mpt_entry->pa0_l = cpu_to_le32(lower_32_bits(pages[0]));
	hr_reg_write(mpt_entry, MPT_PA0_H, upper_32_bits(pages[0]));
@@ -3532,8 +3537,7 @@ static int hns_roce_v2_rereg_write_mtpt(struct hns_roce_dev *hr_dev,
	return ret;
}

static int hns_roce_v2_frmr_write_mtpt(struct hns_roce_dev *hr_dev,
				       void *mb_buf, struct hns_roce_mr *mr)
static int hns_roce_v2_frmr_write_mtpt(void *mb_buf, struct hns_roce_mr *mr)
{
	dma_addr_t pbl_ba = hns_roce_get_mtr_ba(&mr->pbl_mtr);
	struct hns_roce_v2_mpt_entry *mpt_entry;
@@ -3560,8 +3564,10 @@ static int hns_roce_v2_frmr_write_mtpt(struct hns_roce_dev *hr_dev,

	mpt_entry->pbl_size = cpu_to_le32(mr->npages);

	mpt_entry->pbl_ba_l = cpu_to_le32(lower_32_bits(pbl_ba >> 3));
	hr_reg_write(mpt_entry, MPT_PBL_BA_H, upper_32_bits(pbl_ba >> 3));
	mpt_entry->pbl_ba_l = cpu_to_le32(lower_32_bits(pbl_ba >>
							MPT_PBL_BA_ADDR_S));
	hr_reg_write(mpt_entry, MPT_PBL_BA_H,
		     upper_32_bits(pbl_ba >> MPT_PBL_BA_ADDR_S));

	return 0;
}
@@ -3808,14 +3814,14 @@ static void hns_roce_v2_write_cqc(struct hns_roce_dev *hr_dev,
		     to_hr_hw_page_shift(hr_cq->mtr.hem_cfg.ba_pg_shift));
	hr_reg_write(cq_context, CQC_CQE_BUF_PG_SZ,
		     to_hr_hw_page_shift(hr_cq->mtr.hem_cfg.buf_pg_shift));
	hr_reg_write(cq_context, CQC_CQE_BA_L, dma_handle >> 3);
	hr_reg_write(cq_context, CQC_CQE_BA_H, (dma_handle >> (32 + 3)));
	hr_reg_write(cq_context, CQC_CQE_BA_L, dma_handle >> CQC_CQE_BA_L_S);
	hr_reg_write(cq_context, CQC_CQE_BA_H, dma_handle >> CQC_CQE_BA_H_S);
	hr_reg_write_bool(cq_context, CQC_DB_RECORD_EN,
			  hr_cq->flags & HNS_ROCE_CQ_FLAG_RECORD_DB);
	hr_reg_write(cq_context, CQC_CQE_DB_RECORD_ADDR_L,
		     ((u32)hr_cq->db.dma) >> 1);
	hr_reg_write(cq_context, CQC_CQE_DB_RECORD_ADDR_H,
		     hr_cq->db.dma >> 32);
		     hr_cq->db.dma >> CQC_CQE_DB_RECORD_ADDR_H_S);
	hr_reg_write(cq_context, CQC_CQ_MAX_CNT,
		     HNS_ROCE_V2_CQ_DEFAULT_BURST_NUM);
	hr_reg_write(cq_context, CQC_CQ_PERIOD,
@@ -3937,8 +3943,9 @@ static void get_cqe_status(struct hns_roce_dev *hr_dev, struct hns_roce_qp *qp,
		   wc->status == IB_WC_WR_FLUSH_ERR))
		return;

	ibdev_err(&hr_dev->ib_dev, "error cqe status 0x%x:\n", cqe_status);
	print_hex_dump(KERN_ERR, "", DUMP_PREFIX_NONE, 16, 4, cqe,
	ibdev_err_ratelimited(&hr_dev->ib_dev, "error cqe status 0x%x:\n",
			      cqe_status);
	print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_NONE, 16, 4, cqe,
		       cq->cqe_size, false);
	wc->vendor_err = hr_reg_read(cqe, CQE_SUB_STATUS);

@@ -4447,8 +4454,7 @@ static void set_access_flags(struct hns_roce_qp *hr_qp,
}

static void set_qpc_wqe_cnt(struct hns_roce_qp *hr_qp,
			    struct hns_roce_v2_qp_context *context,
			    struct hns_roce_v2_qp_context *qpc_mask)
			    struct hns_roce_v2_qp_context *context)
{
	hr_reg_write(context, QPC_SGE_SHIFT,
		     to_hr_hem_entries_shift(hr_qp->sge.sge_cnt,
@@ -4470,7 +4476,6 @@ static inline int get_pdn(struct ib_pd *ib_pd)
}

static void modify_qp_reset_to_init(struct ib_qp *ibqp,
				    const struct ib_qp_attr *attr,
				    struct hns_roce_v2_qp_context *context,
				    struct hns_roce_v2_qp_context *qpc_mask)
{
@@ -4489,7 +4494,7 @@ static void modify_qp_reset_to_init(struct ib_qp *ibqp,

	hr_reg_write(context, QPC_RQWS, ilog2(hr_qp->rq.max_gs));

	set_qpc_wqe_cnt(hr_qp, context, qpc_mask);
	set_qpc_wqe_cnt(hr_qp, context);

	/* No VLAN need to set 0xFFF */
	hr_reg_write(context, QPC_VLAN_ID, 0xfff);
@@ -4530,7 +4535,6 @@ static void modify_qp_reset_to_init(struct ib_qp *ibqp,
}

static void modify_qp_init_to_init(struct ib_qp *ibqp,
				   const struct ib_qp_attr *attr,
				   struct hns_roce_v2_qp_context *context,
				   struct hns_roce_v2_qp_context *qpc_mask)
{
@@ -4755,11 +4759,11 @@ static int modify_qp_init_to_rtr(struct ib_qp *ibqp,
		return -EINVAL;
	}

	hr_reg_write(context, QPC_TRRL_BA_L, trrl_ba >> 4);
	hr_reg_write(context, QPC_TRRL_BA_L, trrl_ba >> QPC_TRRL_BA_L_S);
	hr_reg_clear(qpc_mask, QPC_TRRL_BA_L);
	context->trrl_ba = cpu_to_le32(trrl_ba >> (16 + 4));
	context->trrl_ba = cpu_to_le32(trrl_ba >> QPC_TRRL_BA_M_S);
	qpc_mask->trrl_ba = 0;
	hr_reg_write(context, QPC_TRRL_BA_H, trrl_ba >> (32 + 16 + 4));
	hr_reg_write(context, QPC_TRRL_BA_H, trrl_ba >> QPC_TRRL_BA_H_S);
	hr_reg_clear(qpc_mask, QPC_TRRL_BA_H);

	if (hr_dev->pci_dev->revision >= PCI_REVISION_ID_HIP09) {
@@ -4772,9 +4776,9 @@ static int modify_qp_init_to_rtr(struct ib_qp *ibqp,
		hr_reg_clear(qpc_mask, QPC_V2_IRRL_HEAD);
	}

	context->irrl_ba = cpu_to_le32(irrl_ba >> 6);
	context->irrl_ba = cpu_to_le32(irrl_ba >> QPC_IRRL_BA_L_S);
	qpc_mask->irrl_ba = 0;
	hr_reg_write(context, QPC_IRRL_BA_H, irrl_ba >> (32 + 6));
	hr_reg_write(context, QPC_IRRL_BA_H, irrl_ba >> QPC_IRRL_BA_H_S);
	hr_reg_clear(qpc_mask, QPC_IRRL_BA_H);

	hr_reg_enable(context, QPC_RMT_E2E);
@@ -4836,8 +4840,9 @@ static int modify_qp_init_to_rtr(struct ib_qp *ibqp,
	hr_reg_clear(qpc_mask, QPC_TRRL_HEAD_MAX);
	hr_reg_clear(qpc_mask, QPC_TRRL_TAIL_MAX);

#define MAX_LP_SGEN 3
	/* rocee send 2^lp_sgen_ini segs every time */
	hr_reg_write(context, QPC_LP_SGEN_INI, 3);
	hr_reg_write(context, QPC_LP_SGEN_INI, MAX_LP_SGEN);
	hr_reg_clear(qpc_mask, QPC_LP_SGEN_INI);

	if (udata && ibqp->qp_type == IB_QPT_RC &&
@@ -4863,8 +4868,7 @@ static int modify_qp_init_to_rtr(struct ib_qp *ibqp,
	return 0;
}

static int modify_qp_rtr_to_rts(struct ib_qp *ibqp,
				const struct ib_qp_attr *attr, int attr_mask,
static int modify_qp_rtr_to_rts(struct ib_qp *ibqp, int attr_mask,
				struct hns_roce_v2_qp_context *context,
				struct hns_roce_v2_qp_context *qpc_mask)
{
@@ -4929,7 +4933,7 @@ static int get_dip_ctx_idx(struct ib_qp *ibqp, const struct ib_qp_attr *attr,
	*tail = (*tail == hr_dev->caps.num_qps - 1) ? 0 : (*tail + 1);

	list_for_each_entry(hr_dip, &hr_dev->dip_list, node) {
		if (!memcmp(grh->dgid.raw, hr_dip->dgid, 16)) {
		if (!memcmp(grh->dgid.raw, hr_dip->dgid, GID_LEN_V2)) {
			*dip_idx = hr_dip->dip_idx;
			goto out;
		}
@@ -5267,15 +5271,14 @@ static int hns_roce_v2_set_abs_fields(struct ib_qp *ibqp,

	if (cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT) {
		memset(qpc_mask, 0, hr_dev->caps.qpc_sz);
		modify_qp_reset_to_init(ibqp, attr, context, qpc_mask);
		modify_qp_reset_to_init(ibqp, context, qpc_mask);
	} else if (cur_state == IB_QPS_INIT && new_state == IB_QPS_INIT) {
		modify_qp_init_to_init(ibqp, attr, context, qpc_mask);
		modify_qp_init_to_init(ibqp, context, qpc_mask);
	} else if (cur_state == IB_QPS_INIT && new_state == IB_QPS_RTR) {
		ret = modify_qp_init_to_rtr(ibqp, attr, attr_mask, context,
					    qpc_mask, udata);
	} else if (cur_state == IB_QPS_RTR && new_state == IB_QPS_RTS) {
		ret = modify_qp_rtr_to_rts(ibqp, attr, attr_mask, context,
					   qpc_mask);
		ret = modify_qp_rtr_to_rts(ibqp, attr_mask, context, qpc_mask);
	}

	return ret;
Loading