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