Re: [PATCH 4/5] rdma/cxgb4: Add t4_srq support functions & structs

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

 



On Mon, Mar 12, 2018 at 11:13:02PM +0530, Raju Rangoju wrote:
> This patch adds kernel mode t4_srq structures and support functions
> - Also add srq resp structures
>
> Signed-off-by: Raju Rangoju <rajur@xxxxxxxxxxx>
> Reviewed-by: Steve Wise <swise@xxxxxxxxxxxxxxxxxxxxx>
> ---
>  drivers/infiniband/hw/cxgb4/iw_cxgb4.h    |  38 +++++++++
>  drivers/infiniband/hw/cxgb4/t4.h          | 134 ++++++++++++++++++++++++++++++
>  drivers/infiniband/hw/cxgb4/t4fw_ri_api.h |  19 +++++
>  include/uapi/rdma/cxgb4-abi.h             |  15 ++++
>  4 files changed, 206 insertions(+)
>
> diff --git a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
> index cc929002c05e..757a7177ce3e 100644
> --- a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
> +++ b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
> @@ -96,6 +96,7 @@ struct c4iw_resource {
>  	struct c4iw_id_table tpt_table;
>  	struct c4iw_id_table qid_table;
>  	struct c4iw_id_table pdid_table;
> +	struct c4iw_id_table srq_table;
>  };
>
>  struct c4iw_qid_list {
> @@ -129,6 +130,8 @@ struct c4iw_stats {
>  	struct c4iw_stat stag;
>  	struct c4iw_stat pbl;
>  	struct c4iw_stat rqt;
> +	struct c4iw_stat srqt;
> +	struct c4iw_stat srq;
>  	struct c4iw_stat ocqp;
>  	u64  db_full;
>  	u64  db_empty;
> @@ -544,6 +547,7 @@ struct c4iw_qp {
>  	struct kref kref;
>  	wait_queue_head_t wait;
>  	int sq_sig_all;
> +	struct c4iw_srq *srq;
>  	struct work_struct free_work;
>  	struct c4iw_ucontext *ucontext;
>  	struct c4iw_wr_wait *wr_waitp;
> @@ -554,6 +558,26 @@ static inline struct c4iw_qp *to_c4iw_qp(struct ib_qp *ibqp)
>  	return container_of(ibqp, struct c4iw_qp, ibqp);
>  }
>
> +struct c4iw_srq {
> +	struct ib_srq ibsrq;
> +	struct list_head db_fc_entry;
> +	struct c4iw_dev *rhp;
> +	struct t4_srq wq;
> +	struct sk_buff *destroy_skb;
> +	u32 srq_limit;
> +	u32 pdid;
> +	int idx;
> +	__u32 flags;
> +	spinlock_t lock;
> +	struct c4iw_wr_wait *wr_waitp;
> +	bool armed;
> +};
> +
> +static inline struct c4iw_srq *to_c4iw_srq(struct ib_srq *ibsrq)
> +{
> +	return container_of(ibsrq, struct c4iw_srq, ibsrq);
> +}
> +
>  struct c4iw_ucontext {
>  	struct ib_ucontext ibucontext;
>  	struct c4iw_dev_ucontext uctx;
> @@ -1034,6 +1058,13 @@ struct ib_cq *c4iw_create_cq(struct ib_device *ibdev,
>  			     struct ib_udata *udata);
>  int c4iw_resize_cq(struct ib_cq *cq, int cqe, struct ib_udata *udata);
>  int c4iw_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags);
> +int c4iw_modify_srq(struct ib_srq *ib_srq, struct ib_srq_attr *attr,
> +		    enum ib_srq_attr_mask srq_attr_mask,
> +		    struct ib_udata *udata);
> +int c4iw_destroy_srq(struct ib_srq *ib_srq);
> +struct ib_srq *c4iw_create_srq(struct ib_pd *pd,
> +			       struct ib_srq_init_attr *attrs,
> +			       struct ib_udata *udata);
>  int c4iw_destroy_qp(struct ib_qp *ib_qp);
>  struct ib_qp *c4iw_create_qp(struct ib_pd *pd,
>  			     struct ib_qp_init_attr *attrs,
> @@ -1070,12 +1101,19 @@ extern c4iw_handler_func c4iw_handlers[NUM_CPL_CMDS];
>  void __iomem *c4iw_bar2_addrs(struct c4iw_rdev *rdev, unsigned int qid,
>  			      enum cxgb4_bar2_qtype qtype,
>  			      unsigned int *pbar2_qid, u64 *pbar2_pa);
> +int c4iw_alloc_srq_idx(struct c4iw_rdev *rdev);
> +void c4iw_free_srq_idx(struct c4iw_rdev *rdev, int idx);
>  extern void c4iw_log_wr_stats(struct t4_wq *wq, struct t4_cqe *cqe);
>  extern int c4iw_wr_log;
>  extern int db_fc_threshold;
>  extern int db_coalescing_threshold;
>  extern int use_dsgl;
>  void c4iw_invalidate_mr(struct c4iw_dev *rhp, u32 rkey);
> +void c4iw_dispatch_srq_limit_reached_event(struct c4iw_srq *srq);
> +void c4iw_copy_wr_to_srq(struct t4_srq *srq, union t4_recv_wr *wqe, u8 len16);
> +void c4iw_flush_srqidx(struct c4iw_qp *qhp, u32 srqidx);
> +int c4iw_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
> +		       struct ib_recv_wr **bad_wr);
>  struct c4iw_wr_wait *c4iw_alloc_wr_wait(gfp_t gfp);
>
>  #endif
> diff --git a/drivers/infiniband/hw/cxgb4/t4.h b/drivers/infiniband/hw/cxgb4/t4.h
> index 8369c7c8de83..33d7fdc490cd 100644
> --- a/drivers/infiniband/hw/cxgb4/t4.h
> +++ b/drivers/infiniband/hw/cxgb4/t4.h
> @@ -56,8 +56,12 @@ struct t4_status_page {
>  	u16 host_wq_pidx;
>  	u16 host_cidx;
>  	u16 host_pidx;
> +	u16 pad2;
> +	u32 srqidx;
>  };
>
> +#define T4_RQT_ENTRY_SHIFT 6
> +#define T4_RQT_ENTRY_SIZE (1 << T4_RQT_ENTRY_SHIFT)
>  #define T4_EQ_ENTRY_SIZE 64
>
>  #define T4_SQ_NUM_SLOTS 5
> @@ -237,6 +241,7 @@ struct t4_cqe {
>  /* used for RQ completion processing */
>  #define CQE_WRID_STAG(x)  (be32_to_cpu((x)->u.rcqe.stag))
>  #define CQE_WRID_MSN(x)   (be32_to_cpu((x)->u.rcqe.msn))
> +#define CQE_ABS_RQE_IDX(x) (be32_to_cpu((x)->u.srcqe.abs_rqe_idx))
>
>  /* used for SQ completion processing */
>  #define CQE_WRID_SQ_IDX(x)	((x)->u.scqe.cidx)
> @@ -320,6 +325,7 @@ struct t4_swrqe {
>  	u64 wr_id;
>  	ktime_t	host_time;
>  	u64 sge_ts;
> +	int valid;
>  };
>
>  struct t4_rq {
> @@ -349,8 +355,116 @@ struct t4_wq {
>  	void __iomem *db;
>  	struct c4iw_rdev *rdev;
>  	int flushed;
> +	u8 *qp_errp;
> +	u32 *srqidxp;
> +};
> +
> +struct t4_srq_pending_wr {
> +	u64 wr_id;
> +	union t4_recv_wr wqe;
> +	u8 len16;
> +};
> +
> +struct t4_srq {
> +	union t4_recv_wr *queue;
> +	dma_addr_t dma_addr;
> +	DECLARE_PCI_UNMAP_ADDR(mapping);
> +	struct t4_swrqe *sw_rq;
> +	void __iomem *bar2_va;
> +	u64 bar2_pa;
> +	size_t memsize;
> +	u32 bar2_qid;
> +	u32 qid;
> +	u32 msn;
> +	u32 rqt_hwaddr;
> +	u32 rqt_abs_idx;
> +	u16 rqt_size;
> +	u16 in_use;
> +	u16 size;
> +	u16 cidx;
> +	u16 pidx;
> +	u16 wq_pidx;
> +	u16 wq_pidx_inc;
> +	struct t4_srq_pending_wr *pending_wrs;
> +	u16 pending_cidx;
> +	u16 pending_pidx;
> +	u16 pending_in_use;
> +	u16 ooo_count;
>  };
>
> +static inline u32 t4_srq_avail(struct t4_srq *srq)
> +{
> +	return srq->size - 1 - srq->in_use;
> +}
> +
> +static inline int t4_srq_empty(struct t4_srq *srq)
> +{
> +	return srq->in_use == 0;
> +}

Please use proper types - bool for this function and for the function below.

> +
> +static inline int t4_srq_cidx_at_end(struct t4_srq *srq)
> +{
> +	if (srq->cidx < srq->pidx)
> +		return srq->cidx == (srq->pidx - 1);
> +	else
> +		return srq->cidx == (srq->size - 1) && srq->pidx == 0;
> +}
> +
> +static inline int t4_srq_wrs_pending(struct t4_srq *srq)
> +{
> +	return srq->pending_cidx != srq->pending_pidx;
> +}
> +
> +static inline void t4_srq_produce(struct t4_srq *srq, u8 len16)
> +{
> +	srq->in_use++;

My general comment is to use refcount_t for such type of variables, for
use (mlx), it helped to catch number of use-after-free bugs.

> +	if (++srq->pidx == srq->size)
> +		srq->pidx = 0;
> +	srq->wq_pidx += DIV_ROUND_UP(len16*16, T4_EQ_ENTRY_SIZE);
> +	if (srq->wq_pidx >= srq->size * T4_RQ_NUM_SLOTS)
> +		srq->wq_pidx %= srq->size * T4_RQ_NUM_SLOTS;
> +	srq->queue[srq->size].status.host_pidx = srq->pidx;
> +}
> +
> +static inline void t4_srq_produce_pending_wr(struct t4_srq *srq)
> +{
> +	srq->pending_in_use++;
> +	srq->in_use++;
> +	if (++srq->pending_pidx == srq->size)
> +		srq->pending_pidx = 0;
> +}
> +
> +static inline void t4_srq_consume_pending_wr(struct t4_srq *srq)
> +{
> +	srq->pending_in_use--;
> +	srq->in_use--;
> +	if (++srq->pending_cidx == srq->size)
> +		srq->pending_cidx = 0;
> +}
> +
> +static inline void t4_srq_produce_ooo(struct t4_srq *srq)
> +{
> +	srq->in_use--;
> +	srq->ooo_count++;
> +}
> +
> +static inline void t4_srq_consume_ooo(struct t4_srq *srq)
> +{
> +	srq->cidx++;
> +	if (srq->cidx == srq->size)
> +		srq->cidx  = 0;
> +	srq->queue[srq->size].status.host_cidx = srq->cidx;
> +	srq->ooo_count--;
> +}
> +
> +static inline void t4_srq_consume(struct t4_srq *srq)
> +{
> +	srq->in_use--;
> +	if (++srq->cidx == srq->size)
> +		srq->cidx = 0;
> +	srq->queue[srq->size].status.host_cidx = srq->cidx;
> +}
> +
>  static inline int t4_rqes_posted(struct t4_wq *wq)
>  {
>  	return wq->rq.in_use;
> @@ -464,6 +578,26 @@ static inline void pio_copy(u64 __iomem *dst, u64 *src)
>  	}
>  }
>
> +static inline void t4_ring_srq_db(struct t4_srq *srq, u16 inc, u8 len16,
> +				  union t4_recv_wr *wqe)
> +{
> +	wmb();
> +	if (inc == 1 && srq->bar2_qid == 0 && wqe) {
> +		pr_debug("%s : WC srq->pidx = %d; len16=%d\n",
> +			 __func__, srq->pidx, len16);
> +		pio_copy((u64 __iomem *)
> +			 (srq->bar2_va + SGE_UDB_WCDOORBELL),
> +			 (void *)wqe);
> +	} else {
> +		pr_debug("%s: DB srq->pidx = %d; len16=%d\n",
> +			 __func__, srq->pidx, len16);
> +		writel(PIDX_T5_V(inc) | QID_V(srq->bar2_qid),
> +		       srq->bar2_va + SGE_UDB_KDOORBELL);
> +	}
> +	wmb();
> +	return;
> +}
> +
>  static inline void t4_ring_sq_db(struct t4_wq *wq, u16 inc, union t4_wr *wqe)
>  {
>
> diff --git a/drivers/infiniband/hw/cxgb4/t4fw_ri_api.h b/drivers/infiniband/hw/cxgb4/t4fw_ri_api.h
> index 58c531db4f4a..0f4f86b004d6 100644
> --- a/drivers/infiniband/hw/cxgb4/t4fw_ri_api.h
> +++ b/drivers/infiniband/hw/cxgb4/t4fw_ri_api.h
> @@ -263,6 +263,7 @@ enum fw_ri_res_type {
>  	FW_RI_RES_TYPE_SQ,
>  	FW_RI_RES_TYPE_RQ,
>  	FW_RI_RES_TYPE_CQ,
> +	FW_RI_RES_TYPE_SRQ,
>  };
>
>  enum fw_ri_res_op {
> @@ -296,6 +297,20 @@ struct fw_ri_res {
>  			__be32 r6_lo;
>  			__be64 r7;
>  		} cq;
> +		struct fw_ri_res_srq {
> +			__u8   restype;
> +			__u8   op;
> +			__be16 r3;
> +			__be32 eqid;
> +			__be32 r4[2];
> +			__be32 fetchszm_to_iqid;
> +			__be32 dcaen_to_eqsize;
> +			__be64 eqaddr;
> +			__be32 srqid;
> +			__be32 pdid;
> +			__be32 hwsrqsize;
> +			__be32 hwsrqaddr;
> +		} srq;
>  	} u;
>  };
>
> @@ -707,6 +722,10 @@ enum fw_ri_init_p2ptype {
>  	FW_RI_INIT_P2PTYPE_DISABLED		= 0xf,
>  };
>
> +enum fw_ri_init_rqeqid_srq {
> +	FW_RI_INIT_RQEQID_SRQ			= 1 << 31,
> +};
> +
>  struct fw_ri_wr {
>  	__be32 op_compl;
>  	__be32 flowid_len16;
> diff --git a/include/uapi/rdma/cxgb4-abi.h b/include/uapi/rdma/cxgb4-abi.h
> index 05f71f1bc119..e82cfd69c3f8 100644
> --- a/include/uapi/rdma/cxgb4-abi.h
> +++ b/include/uapi/rdma/cxgb4-abi.h
> @@ -74,6 +74,21 @@ struct c4iw_create_qp_resp {
>  	__u32 flags;
>  };
>
> +struct c4iw_create_srq_resp {
> +	__u64 srq_key;
> +	__u64 srq_db_gts_key;
> +	__u64 srq_memsize;
> +	__u32 srqid;
> +	__u32 srq_size;
> +	__u32 rqt_abs_idx;
> +	__u32 qid_mask;
> +	__u32 flags;
> +};
> +
> +enum {
> +	T4_SRQ_LIMIT_SUPPORT = (1<<0), /* HW supports SRQ_LIMIT_REACHED event */
> +};
> +
>  struct c4iw_alloc_ucontext_resp {
>  	__u64 status_page_key;
>  	__u32 status_page_size;
> --
> 2.12.0
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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