Re: [PATCH for-next 1/2] RDMA/hns: Add alloc mw support for hip08

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

 



On Thu, Sep 06, 2018 at 04:49:40PM +0800, Yixian Liu wrote:
> This patch adds memory window (mw) allocation support in
> the kernel space.
>
> Signed-off-by: Yixian Liu <liuyixian@xxxxxxxxxx>
> ---
>  drivers/infiniband/hw/hns/hns_roce_device.h |  21 +++++
>  drivers/infiniband/hw/hns/hns_roce_hw_v2.c  |  48 +++++++++++
>  drivers/infiniband/hw/hns/hns_roce_hw_v2.h  |  10 +++
>  drivers/infiniband/hw/hns/hns_roce_main.c   |   6 ++
>  drivers/infiniband/hw/hns/hns_roce_mr.c     | 120 ++++++++++++++++++++++++++++
>  5 files changed, 205 insertions(+)
>
> diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h
> index cfb88a4..4fe4a3b 100644
> --- a/drivers/infiniband/hw/hns/hns_roce_device.h
> +++ b/drivers/infiniband/hw/hns/hns_roce_device.h
> @@ -193,6 +193,7 @@ enum {
>  	HNS_ROCE_CAP_FLAG_RQ_INLINE		= BIT(2),
>  	HNS_ROCE_CAP_FLAG_RECORD_DB		= BIT(3),
>  	HNS_ROCE_CAP_FLAG_SQ_RECORD_DB		= BIT(4),
> +	HNS_ROCE_CAP_FLAG_MW			= BIT(7),
>  };
>
>  enum hns_roce_mtt_type {
> @@ -293,6 +294,16 @@ struct hns_roce_mtt {
>  	enum hns_roce_mtt_type	mtt_type;
>  };
>
> +struct hns_roce_mw {
> +	struct ib_mw		ibmw;
> +	u32			pdn;
> +	u32			rkey;
> +	int			enabled; /* MW's active status */
> +	u32			pbl_hop_num;
> +	u32			pbl_ba_pg_sz;
> +	u32			pbl_buf_pg_sz;
> +};
> +
>  /* Only support 4K page size for mr register */
>  #define MR_SIZE_4K 0
>
> @@ -765,6 +776,8 @@ struct hns_roce_hw {
>  				struct hns_roce_mr *mr, int flags, u32 pdn,
>  				int mr_access_flags, u64 iova, u64 size,
>  				void *mb_buf);
> +	int (*mw_write_mtpt)(void *mb_buf, struct hns_roce_mw *mw,
> +			     unsigned long mtpt_idx);
>  	void (*write_cqc)(struct hns_roce_dev *hr_dev,
>  			  struct hns_roce_cq *hr_cq, void *mb_buf, u64 *mtts,
>  			  dma_addr_t dma_handle, int nent, u32 vector);
> @@ -864,6 +877,11 @@ static inline struct hns_roce_mr *to_hr_mr(struct ib_mr *ibmr)
>  	return container_of(ibmr, struct hns_roce_mr, ibmr);
>  }
>
> +static inline struct hns_roce_mw *to_hr_mw(struct ib_mw *ibmw)
> +{
> +	return container_of(ibmw, struct hns_roce_mw, ibmw);
> +}
> +
>  static inline struct hns_roce_qp *to_hr_qp(struct ib_qp *ibqp)
>  {
>  	return container_of(ibqp, struct hns_roce_qp, ibqp);
> @@ -975,6 +993,9 @@ int hns_roce_hw2sw_mpt(struct hns_roce_dev *hr_dev,
>  		       unsigned long mpt_index);
>  unsigned long key_to_hw_index(u32 key);
>
> +struct ib_mw *hns_roce_alloc_mw(struct ib_pd *pd, enum ib_mw_type,
> +				struct ib_udata *udata);
> +
>  void hns_roce_buf_free(struct hns_roce_dev *hr_dev, u32 size,
>  		       struct hns_roce_buf *buf);
>  int hns_roce_buf_alloc(struct hns_roce_dev *hr_dev, u32 size, u32 max_direct,
> diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
> index b16ad95..5b65f2b 100644
> --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
> +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
> @@ -1255,6 +1255,10 @@ static int hns_roce_v2_profile(struct hns_roce_dev *hr_dev)
>  				  HNS_ROCE_CAP_FLAG_RQ_INLINE |
>  				  HNS_ROCE_CAP_FLAG_RECORD_DB |
>  				  HNS_ROCE_CAP_FLAG_SQ_RECORD_DB;
> +
> +	if (hr_dev->pci_dev->revision == 0x21)
> +		caps->flags	|= HNS_ROCE_CAP_FLAG_MW;
> +
>  	caps->pkey_table_len[0] = 1;
>  	caps->gid_table_len[0] = HNS_ROCE_V2_GID_INDEX_NUM;
>  	caps->ceqe_depth	= HNS_ROCE_V2_COMP_EQE_NUM;
> @@ -1817,6 +1821,49 @@ static int hns_roce_v2_rereg_write_mtpt(struct hns_roce_dev *hr_dev,
>  	return 0;
>  }
>
> +static int hns_roce_v2_mw_write_mtpt(void *mb_buf, struct hns_roce_mw *mw,
> +				     unsigned long mtpt_idx)
> +{
> +	struct hns_roce_v2_mpt_entry *mpt_entry;
> +
> +	mpt_entry = mb_buf;
> +	memset(mpt_entry, 0, sizeof(*mpt_entry));
> +
> +	roce_set_field(mpt_entry->byte_4_pd_hop_st, V2_MPT_BYTE_4_MPT_ST_M,
> +		       V2_MPT_BYTE_4_MPT_ST_S, V2_MPT_ST_FREE);
> +	roce_set_field(mpt_entry->byte_4_pd_hop_st, V2_MPT_BYTE_4_PD_M,
> +		       V2_MPT_BYTE_4_PD_S, mw->pdn);
> +	roce_set_field(mpt_entry->byte_4_pd_hop_st, V2_MPT_BYTE_4_PBL_HOP_NUM_M,
> +		       V2_MPT_BYTE_4_PBL_HOP_NUM_S, mw->pbl_hop_num ==
> +		       HNS_ROCE_HOP_NUM_0 ? 0 : mw->pbl_hop_num);
> +	roce_set_field(mpt_entry->byte_4_pd_hop_st,
> +		       V2_MPT_BYTE_4_PBL_BA_PG_SZ_M,
> +		       V2_MPT_BYTE_4_PBL_BA_PG_SZ_S,
> +		       mw->pbl_ba_pg_sz + PG_SHIFT_OFFSET);
> +	mpt_entry->byte_4_pd_hop_st = cpu_to_le32(mpt_entry->byte_4_pd_hop_st);
> +
> +	roce_set_bit(mpt_entry->byte_8_mw_cnt_en, V2_MPT_BYTE_8_R_INV_EN_S, 1);
> +	roce_set_bit(mpt_entry->byte_8_mw_cnt_en, V2_MPT_BYTE_8_L_INV_EN_S, 1);
> +	mpt_entry->byte_8_mw_cnt_en = cpu_to_le32(mpt_entry->byte_8_mw_cnt_en);
> +
> +	roce_set_bit(mpt_entry->byte_12_mw_pa, V2_MPT_BYTE_12_PA_S, 0);
> +	roce_set_bit(mpt_entry->byte_12_mw_pa, V2_MPT_BYTE_12_MR_MW_S, 1);
> +	roce_set_bit(mpt_entry->byte_12_mw_pa, V2_MPT_BYTE_12_BPD_S, 1);
> +	roce_set_bit(mpt_entry->byte_12_mw_pa, V2_MPT_BYTE_12_BQP_S,
> +		     mw->ibmw.type == IB_MW_TYPE_1 ? 0 : 1);
> +	mpt_entry->byte_12_mw_pa = cpu_to_le32(mpt_entry->byte_12_mw_pa);
> +
> +	roce_set_field(mpt_entry->byte_64_buf_pa1,
> +		       V2_MPT_BYTE_64_PBL_BUF_PG_SZ_M,
> +		       V2_MPT_BYTE_64_PBL_BUF_PG_SZ_S,
> +		       mw->pbl_buf_pg_sz + PG_SHIFT_OFFSET);
> +	mpt_entry->byte_64_buf_pa1 = cpu_to_le32(mpt_entry->byte_64_buf_pa1);
> +
> +	mpt_entry->lkey = cpu_to_le32(mw->rkey);
> +
> +	return 0;
> +}
> +
>  static void *get_cqe_v2(struct hns_roce_cq *hr_cq, int n)
>  {
>  	return hns_roce_buf_offset(&hr_cq->hr_buf.hr_buf,
> @@ -5159,6 +5206,7 @@ static const struct hns_roce_hw hns_roce_hw_v2 = {
>  	.set_mac = hns_roce_v2_set_mac,
>  	.write_mtpt = hns_roce_v2_write_mtpt,
>  	.rereg_write_mtpt = hns_roce_v2_rereg_write_mtpt,
> +	.mw_write_mtpt = hns_roce_v2_mw_write_mtpt,
>  	.write_cqc = hns_roce_v2_write_cqc,
>  	.set_hem = hns_roce_v2_set_hem,
>  	.clear_hem = hns_roce_v2_clear_hem,
> diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
> index 14aa308..746fe80 100644
> --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
> +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
> @@ -324,6 +324,7 @@ struct hns_roce_v2_cq_context {
>
>  enum{
>  	V2_MPT_ST_VALID = 0x1,
> +	V2_MPT_ST_FREE	= 0x2,
>  };
>
>  enum hns_roce_v2_qp_state {
> @@ -878,8 +879,17 @@ struct hns_roce_v2_mpt_entry {
>
>  #define V2_MPT_BYTE_8_LW_EN_S 7
>
> +#define V2_MPT_BYTE_8_MW_CNT_S 8
> +#define V2_MPT_BYTE_8_MW_CNT_M GENMASK(31, 8)
> +
>  #define V2_MPT_BYTE_12_PA_S 1
>
> +#define V2_MPT_BYTE_12_MR_MW_S 4
> +
> +#define V2_MPT_BYTE_12_BPD_S 5
> +
> +#define V2_MPT_BYTE_12_BQP_S 6
> +
>  #define V2_MPT_BYTE_12_INNER_PA_VLD_S 7
>
>  #define V2_MPT_BYTE_12_MW_BIND_QPN_S 8
> diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c b/drivers/infiniband/hw/hns/hns_roce_main.c
> index c5cae9a..ff71d91 100644
> --- a/drivers/infiniband/hw/hns/hns_roce_main.c
> +++ b/drivers/infiniband/hw/hns/hns_roce_main.c
> @@ -584,6 +584,12 @@ static int hns_roce_register_device(struct hns_roce_dev *hr_dev)
>  		ib_dev->uverbs_cmd_mask |= (1ULL << IB_USER_VERBS_CMD_REREG_MR);
>  	}
>
> +	/* MW */
> +	if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_MW) {
> +		ib_dev->alloc_mw	= hns_roce_alloc_mw;
> +		ib_dev->uverbs_cmd_mask |= (1ULL << IB_USER_VERBS_CMD_ALLOC_MW);
> +	}
> +
>  	/* OTHERS */
>  	ib_dev->get_port_immutable	= hns_roce_port_immutable;
>  	ib_dev->disassociate_ucontext	= hns_roce_disassociate_ucontext;
> diff --git a/drivers/infiniband/hw/hns/hns_roce_mr.c b/drivers/infiniband/hw/hns/hns_roce_mr.c
> index eb26a5f..84779dd 100644
> --- a/drivers/infiniband/hw/hns/hns_roce_mr.c
> +++ b/drivers/infiniband/hw/hns/hns_roce_mr.c
> @@ -1201,3 +1201,123 @@ int hns_roce_dereg_mr(struct ib_mr *ibmr)
>
>  	return ret;
>  }
> +
> +static int hns_roce_mw_free(struct hns_roce_dev *hr_dev,
> +			     struct hns_roce_mw *mw)
> +{
> +	struct device *dev = hr_dev->dev;
> +	int ret = 0;
> +
> +	if (mw->enabled) {
> +		ret = hns_roce_hw2sw_mpt(hr_dev, NULL, key_to_hw_index(mw->rkey)
> +					 & (hr_dev->caps.num_mtpts - 1));
> +		if (ret) {
> +			dev_warn(dev, "MW HW2SW_MPT failed (%d)\n", ret);
> +			return ret;
> +		}
> +	}
> +
> +	if (mw->enabled)

I see two "if (mw->enabled)", one after another.
It should be combined.

> +		hns_roce_table_put(hr_dev, &hr_dev->mr_table.mtpt_table,
> +				   key_to_hw_index(mw->rkey));
> +
> +	hns_roce_bitmap_free(&hr_dev->mr_table.mtpt_bitmap,
> +			     key_to_hw_index(mw->rkey), BITMAP_NO_RR);
> +
> +	return ret;
> +}

Attachment: signature.asc
Description: PGP signature


[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