mlx4: XRC base implementation
PATCH 3/4 mlx4: XRC base implementation
Support for XRC base implementation in mlx4 low-level driver.
Signed-off-by Jack Morgenstein <[email protected]>
--- drivers/infiniband/hw/mlx4/cq.c | 39 +++++++++++++++++-- drivers/infiniband/hw/mlx4/main.c | 52 +++++++++++++++++++++++++ drivers/infiniband/hw/mlx4/mlx4_ib.h | 16 ++++++++ drivers/infiniband/hw/mlx4/qp.c | 49 +++++++++++++++++------ drivers/infiniband/hw/mlx4/srq.c | 39 ++++++++++++++++-- drivers/net/mlx4/Makefile | 2 +- drivers/net/mlx4/fw.c | 7 +++ drivers/net/mlx4/fw.h | 2 + drivers/net/mlx4/main.c | 22 ++++++++++- drivers/net/mlx4/mlx4.h | 4 +- drivers/net/mlx4/qp.c | 2 + drivers/net/mlx4/srq.c | 46 ++++++++++++++-------- drivers/net/mlx4/xrcd.c | 70 ++++++++++++++++++++++++++++++++++ include/linux/mlx4/device.h | 11 ++++- include/linux/mlx4/qp.h | 3 +- include/linux/mlx4/srq.h | 12 ++++++ 16 files changed, 331 insertions(+), 45 deletions(-) create mode 100644 drivers/net/mlx4/xrcd.c
drivers/infiniband/hw/mlx4/cq.c +35 -4
@@ -33,6 +33,7 @@#include <linux/mlx4/cq.h> #include <linux/mlx4/qp.h> +#include <linux/mlx4/srq.h> #include "mlx4_ib.h" #include "user.h"
@@ -543,10 +544,12 @@ static int mlx4_ib_poll_one(struct mlx4_ib_cq *cq,struct mlx4_cqe *cqe;struct mlx4_qp *mqp;struct mlx4_ib_wq *wq; -struct mlx4_ib_srq *srq; +struct mlx4_ib_srq *uninitialized_var (srq ); +struct mlx4_srq *msrq;int is_send;int is_error;u32 g_mlpath_rqpn; +int is_xrc_recv =0 ;u16 wqe_ctr; repoll:
@@ -588,7 +591,24 @@ repoll: goto repoll; } -if (!*cur_qp || +if ((be32_to_cpu (cqe->vlan_my_qpn) & (1 <<23 )) && !is_send) { +/* +* We do not have to take the XRC SRQ table lock here, +* because CQs will be locked while XRC SRQs are removed +* from the table. +*/ + msrq =__mlx4_srq_lookup (to_mdev (cq->ibcq.device)->dev, +be32_to_cpu (cqe->g_mlpath_rqpn) & +0xffffff ); +if (unlikely (!msrq)) { +printk (KERN_WARNING "CQ %06x with entry for unknown " +"XRC SRQ %06x\n" , cq->mcq.cqn, +be32_to_cpu (cqe->g_mlpath_rqpn) &0xffffff ); +return -EINVAL ; + } + is_xrc_recv =1 ; + srq =to_mibsrq (msrq); + }else if (!*cur_qp || (be32_to_cpu (cqe->vlan_my_qpn) &MLX4_CQE_QPN_MASK ) != (*cur_qp)->mqp.qpn) {/* * We do not have to take the QP table lock here,
@@ -606,7 +626,7 @@ repoll: *cur_qp =to_mibqp (mqp); } - wc->qp = &(*cur_qp)->ibqp; + wc->qp = is_xrc_recv ?NULL : &(*cur_qp)->ibqp;if (is_send) { wq = &(*cur_qp)->sq;
@@ -616,6 +636,10 @@ repoll: } wc->wr_id = wq->wrid[wq->tail & (wq->wqe_cnt -1 )]; ++wq->tail; + }else if (is_xrc_recv) { + wqe_ctr =be16_to_cpu (cqe->wqe_index); + wc->wr_id = srq->wrid[wqe_ctr]; +mlx4_ib_free_srq_wqe (srq, wqe_ctr); }else if ((*cur_qp)->ibqp.srq) { srq =to_msrq ((*cur_qp)->ibqp.srq); wqe_ctr =be16_to_cpu (cqe->wqe_index);
@@ -755,6 +779,10 @@ void __mlx4_ib_cq_clean(struct mlx4_ib_cq *cq, u32 qpn, struct mlx4_ib_srq *srq)int nfreed =0 ;struct mlx4_cqe *cqe, *dest;u8 owner_bit; +int is_xrc_srq =0 ; + +if (srq && srq->ibsrq.xrc_cq) + is_xrc_srq =1 ;/* * First we need to find the current producer index, so we
@@ -773,7 +801,10 @@ void __mlx4_ib_cq_clean(struct mlx4_ib_cq *cq, u32 qpn, struct mlx4_ib_srq *srq)*/ while ((int ) --prod_index - (int ) cq->mcq.cons_index >=0 ) { cqe =get_cqe (cq, prod_index & cq->ibcq.cqe); -if ((be32_to_cpu (cqe->vlan_my_qpn) &MLX4_CQE_QPN_MASK ) == qpn) { +if (((be32_to_cpu (cqe->vlan_my_qpn) &0xffffff ) == qpn) || + (is_xrc_srq && + (be32_to_cpu (cqe->g_mlpath_rqpn) &0xffffff ) == + srq->msrq.srqn)) {if (srq && !(cqe->owner_sr_opcode &MLX4_CQE_IS_SEND_MASK ))mlx4_ib_free_srq_wqe (srq,be16_to_cpu (cqe->wqe_index)); ++nfreed;
drivers/infiniband/hw/mlx4/main.c +52 -0
70 lines not on this page · raw message
drivers/infiniband/hw/mlx4/mlx4_ib.h +16 -0
@@ -56,6 +56,11 @@ struct mlx4_ib_pd {u32 pdn; }; +struct mlx4_ib_xrcd { +struct ib_xrcd ibxrcd; +u32 xrcdn; +}; +struct mlx4_ib_cq_buf {struct mlx4_buf buf;struct mlx4_mtt mtt;
@@ -132,6 +137,7 @@ struct mlx4_ib_qp {int buf_size;struct mutex mutex;u32 flags; +u16 xrcdn;u8 port;u8 alt_port;u8 atomic_rd_en;
@@ -193,6 +199,11 @@ static inline struct mlx4_ib_pd *to_mpd(struct ib_pd *ibpd) return container_of(ibpd, struct mlx4_ib_pd, ibpd); } +static inline struct mlx4_ib_xrcd *to_mxrcd (struct ib_xrcd *ibxrcd) +{ + return container_of(ibxrcd, struct mlx4_ib_xrcd, ibxrcd); +} +static inline struct mlx4_ib_cq *to_mcq (struct ib_cq *ibcq) { return container_of(ibcq, struct mlx4_ib_cq, ibcq);
@@ -277,6 +288,11 @@ int mlx4_ib_destroy_ah(struct ib_ah *ah);struct ib_srq *mlx4_ib_create_srq (struct ib_pd *pd,struct ib_srq_init_attr *init_attr,struct ib_udata *udata); +struct ib_srq *mlx4_ib_create_xrc_srq (struct ib_pd *pd, +struct ib_cq *xrc_cq, +struct ib_xrcd *xrcd, +struct ib_srq_init_attr *init_attr, +struct ib_udata *udata);int mlx4_ib_modify_srq (struct ib_srq *ibsrq,struct ib_srq_attr *attr,enum ib_srq_attr_mask attr_mask,struct ib_udata *udata);int mlx4_ib_query_srq (struct ib_srq *srq,struct ib_srq_attr *srq_attr);
drivers/infiniband/hw/mlx4/qp.c +36 -13
164 lines not on this page · raw message
drivers/infiniband/hw/mlx4/srq.c +34 -5
@@ -67,14 +67,18 @@ static void mlx4_ib_srq_event(struct mlx4_srq *srq, enum mlx4_event type) } } -struct ib_srq *mlx4_ib_create_srq (struct ib_pd *pd, -struct ib_srq_init_attr *init_attr, -struct ib_udata *udata) +struct ib_srq *mlx4_ib_create_xrc_srq (struct ib_pd *pd, +struct ib_cq *xrc_cq, +struct ib_xrcd *xrcd, +struct ib_srq_init_attr *init_attr, +struct ib_udata *udata) {struct mlx4_ib_dev *dev =to_mdev (pd->device);struct mlx4_ib_srq *srq;struct mlx4_wqe_srq_next_seg *next;struct mlx4_wqe_data_seg *scatter; +u32 cqn; +u16 xrcdn;int desc_size;int buf_size;int err;
@@ -173,18 +177,24 @@ struct ib_srq *mlx4_ib_create_srq(struct ib_pd *pd, } } - err =mlx4_srq_alloc (dev->dev,to_mpd (pd)->pdn, &srq->mtt, + cqn = xrc_cq ? (u32) (to_mcq (xrc_cq)->mcq.cqn) :0 ; + xrcdn = xrcd ? (u16) (to_mxrcd (xrcd)->xrcdn) : + (u16 ) dev->dev->caps.reserved_xrcds; + + err =mlx4_srq_alloc (dev->dev,to_mpd (pd)->pdn, cqn, xrcdn, &srq->mtt, srq->db.dma, &srq->msrq);if (err) goto err_wrid; srq->msrq.event = mlx4_ib_srq_event; -if (pd->uobject) +if (pd->uobject) {if (ib_copy_to_udata (udata, &srq->msrq.srqn,sizeof (__u32))) { err = -EFAULT ; goto err_wrid; } + }else + srq->ibsrq.xrc_srq_num = srq->msrq.srqn; init_attr->attr.max_wr = srq->msrq.max -1 ;
@@ -241,6 +251,13 @@ int mlx4_ib_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,return 0 ; } +struct ib_srq *mlx4_ib_create_srq (struct ib_pd *pd, +struct ib_srq_init_attr *init_attr, +struct ib_udata *udata) +{ +return mlx4_ib_create_xrc_srq (pd,NULL ,NULL , init_attr, udata); +} +int mlx4_ib_query_srq (struct ib_srq *ibsrq,struct ib_srq_attr *srq_attr) {struct mlx4_ib_dev *dev =to_mdev (ibsrq->device);
@@ -263,6 +280,18 @@ int mlx4_ib_destroy_srq(struct ib_srq *srq) {struct mlx4_ib_dev *dev =to_mdev (srq->device);struct mlx4_ib_srq *msrq =to_msrq (srq); +struct mlx4_ib_cq *cq; + +mlx4_srq_invalidate (dev->dev, &msrq->msrq); + +if (srq->xrc_cq && !srq->uobject) { + cq =to_mcq (srq->xrc_cq); +spin_lock_irq (&cq->lock); +__mlx4_ib_cq_clean (cq,-1 , msrq); +mlx4_srq_remove (dev->dev, &msrq->msrq); +spin_unlock_irq (&cq->lock); + }else +mlx4_srq_remove (dev->dev, &msrq->msrq);mlx4_srq_free (dev->dev, &msrq->msrq);mlx4_mtt_cleanup (dev->dev, &msrq->mtt);
drivers/net/mlx4/Makefile +1 -1
@@ -1,7 +1,7 @@ obj-$(CONFIG_MLX4_CORE) += mlx4_core.o mlx4_core-y := alloc.o catas.o cmd.o cq.o eq.o fw.o icm.o intf.o main.o mcg.o \ - mr.o pd.o port.o profile.o qp.o reset.o sense.o srq.o + mr.o pd.o port.o profile.o qp.o reset.o sense.o srq.o xrcd.o obj-$(CONFIG_MLX4_EN) += mlx4_en.o
drivers/net/mlx4/fw.c +7 -0
@@ -195,6 +195,8 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)#define QUERY_DEV_CAP_MAX_MCG_OFFSET 0x63#define QUERY_DEV_CAP_RSVD_PD_OFFSET 0x64#define QUERY_DEV_CAP_MAX_PD_OFFSET 0x65 +#define QUERY_DEV_CAP_RSVD_XRC_OFFSET 0x66 +#define QUERY_DEV_CAP_MAX_XRC_OFFSET 0x67#define QUERY_DEV_CAP_RDMARC_ENTRY_SZ_OFFSET 0x80#define QUERY_DEV_CAP_QPC_ENTRY_SZ_OFFSET 0x82#define QUERY_DEV_CAP_AUX_ENTRY_SZ_OFFSET 0x84
@@ -305,6 +307,11 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)MLX4_GET (field, outbox,QUERY_DEV_CAP_MAX_PD_OFFSET ); dev_cap->max_pds =1 << (field &0x3f ); +MLX4_GET (field, outbox,QUERY_DEV_CAP_RSVD_XRC_OFFSET ); + dev_cap->reserved_xrcds = field >>4 ; +MLX4_GET (field, outbox,QUERY_DEV_CAP_MAX_XRC_OFFSET ); + dev_cap->max_xrcds =1 << (field &0x1f ); +MLX4_GET (size, outbox,QUERY_DEV_CAP_RDMARC_ENTRY_SZ_OFFSET ); dev_cap->rdmarc_entry_sz = size;MLX4_GET (size, outbox,QUERY_DEV_CAP_QPC_ENTRY_SZ_OFFSET );
drivers/net/mlx4/fw.h +2 -0
@@ -89,6 +89,8 @@ struct mlx4_dev_cap {int max_mcgs;int reserved_pds;int max_pds; +int reserved_xrcds; +int max_xrcds;int qpc_entry_sz;int rdmarc_entry_sz;int altc_entry_sz;
drivers/net/mlx4/main.c +20 -2
@@ -221,7 +221,13 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) dev->caps.reserved_lkey = dev_cap->reserved_lkey; dev->caps.stat_rate_support = dev_cap->stat_rate_support; dev->caps.max_gso_sz = dev_cap->max_gso_sz; - +if (dev->caps.flags &MLX4_DEV_CAP_FLAG_XRC ) { + dev->caps.reserved_xrcds = dev_cap->reserved_xrcds; + dev->caps.max_xrcds = dev_cap->max_xrcds; + }else { + dev->caps.reserved_xrcds =0 ; + dev->caps.max_xrcds =0 ; + } dev->caps.log_num_macs = log_num_mac; dev->caps.log_num_vlans = log_num_vlan; dev->caps.log_num_prios = use_prio ?3 :0 ;
@@ -837,11 +843,18 @@ static int mlx4_setup_hca(struct mlx4_dev *dev) goto err_kar_unmap; } + err =mlx4_init_xrcd_table (dev); +if (err) { +mlx4_err (dev,"Failed to initialize extended " +"reliably connected domain table, aborting.\n" ); + goto err_pd_table_free; + } + err =mlx4_init_mr_table (dev);if (err) {mlx4_err (dev,"Failed to initialize " "memory region table, aborting.\n" ); - goto err_pd_table_free; + goto err_xrcd_table_free; } err =mlx4_init_eq_table (dev);
@@ -944,6 +957,9 @@ err_eq_table_free: err_mr_table_free:mlx4_cleanup_mr_table (dev); +err_xrcd_table_free: +mlx4_cleanup_xrcd_table (dev); + err_pd_table_free:mlx4_cleanup_pd_table (dev);
@@ -1184,6 +1200,7 @@ err_port:mlx4_cmd_use_polling (dev);mlx4_cleanup_eq_table (dev);mlx4_cleanup_mr_table (dev); +mlx4_cleanup_xrcd_table (dev);mlx4_cleanup_pd_table (dev);mlx4_cleanup_uar_table (dev);
@@ -1246,6 +1263,7 @@ static void mlx4_remove_one(struct pci_dev *pdev)mlx4_cmd_use_polling (dev);mlx4_cleanup_eq_table (dev);mlx4_cleanup_mr_table (dev); +mlx4_cleanup_xrcd_table (dev);mlx4_cleanup_pd_table (dev);iounmap (priv->kar);
drivers/net/mlx4/mlx4.h +3 -1
@@ -214,7 +214,6 @@ struct mlx4_eq_table {struct mlx4_srq_table {struct mlx4_bitmap bitmap;spinlock_t lock; -struct radix_tree_root tree;struct mlx4_icm_table table;struct mlx4_icm_table cmpt_table; };
@@ -296,6 +295,7 @@ struct mlx4_priv {struct mlx4_cmd cmd;struct mlx4_bitmap pd_bitmap; +struct mlx4_bitmap xrcd_bitmap;struct mlx4_uar_table uar_table;struct mlx4_mr_table mr_table;struct mlx4_cq_table cq_table;
@@ -338,6 +338,7 @@ int mlx4_alloc_eq_table(struct mlx4_dev *dev);void mlx4_free_eq_table (struct mlx4_dev *dev);int mlx4_init_pd_table (struct mlx4_dev *dev); +int mlx4_init_xrcd_table (struct mlx4_dev *dev);int mlx4_init_uar_table (struct mlx4_dev *dev);int mlx4_init_mr_table (struct mlx4_dev *dev);int mlx4_init_eq_table (struct mlx4_dev *dev);
@@ -354,6 +355,7 @@ void mlx4_cleanup_cq_table(struct mlx4_dev *dev);void mlx4_cleanup_qp_table (struct mlx4_dev *dev);void mlx4_cleanup_srq_table (struct mlx4_dev *dev);void mlx4_cleanup_mcg_table (struct mlx4_dev *dev); +void mlx4_cleanup_xrcd_table (struct mlx4_dev *dev);void mlx4_start_catas_poll (struct mlx4_dev *dev);void mlx4_stop_catas_poll (struct mlx4_dev *dev);
drivers/net/mlx4/qp.c +2 -0
@@ -279,6 +279,8 @@ int mlx4_init_qp_table(struct mlx4_dev *dev)* We reserve 2 extra QPs per port for the special QPs. The * block of special QPs must be aligned to a multiple of 8, so * round up. +* We also reserve the MSB of the 24-bit QP number to indicate +* an XRC qp. */ dev->caps.sqp_start =ALIGN (dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FW ],8 );
drivers/net/mlx4/srq.c +30 -16
110 lines not on this page · raw message
drivers/net/mlx4/xrcd.c new file +70 -0
70 lines not on this page · raw message
include/linux/mlx4/device.h +9 -2
@@ -56,6 +56,7 @@ enum {MLX4_DEV_CAP_FLAG_RC =1 <<0 ,MLX4_DEV_CAP_FLAG_UC =1 <<1 ,MLX4_DEV_CAP_FLAG_UD =1 <<2 , +MLX4_DEV_CAP_FLAG_XRC =1 <<3 ,MLX4_DEV_CAP_FLAG_SRQ =1 <<6 ,MLX4_DEV_CAP_FLAG_IPOIB_CSUM =1 <<7 , MLX4_DEV_CAP_FLAG_BAD_PKEY_CNTR = 1 << 8,
@@ -223,6 +224,8 @@ struct mlx4_caps {int num_pds;int reserved_pds;int mtt_entry_sz; +int reserved_xrcds; +int max_xrcds;u32 max_msg_sz;u32 page_size_cap;u32 flags;
@@ -378,6 +381,7 @@ struct mlx4_dev {unsigned long flags;struct mlx4_caps caps;struct radix_tree_root qp_table_tree; +struct radix_tree_root srq_table_tree;u32 rev_id;char board_id[MLX4_BOARD_ID_LEN ]; };
@@ -416,6 +420,9 @@ static inline void *mlx4_buf_offset(struct mlx4_buf *buf, int offset)int mlx4_pd_alloc (struct mlx4_dev *dev,u32 *pdn);void mlx4_pd_free (struct mlx4_dev *dev,u32 pdn); +int mlx4_xrcd_alloc (struct mlx4_dev *dev,u32 *xrcdn); +void mlx4_xrcd_free (struct mlx4_dev *dev,u32 xrcdn); +int mlx4_uar_alloc (struct mlx4_dev *dev,struct mlx4_uar *uar);void mlx4_uar_free (struct mlx4_dev *dev,struct mlx4_uar *uar);
@@ -452,8 +459,8 @@ void mlx4_qp_release_range(struct mlx4_dev *dev, int base_qpn, int cnt);int mlx4_qp_alloc (struct mlx4_dev *dev,int qpn,struct mlx4_qp *qp);void mlx4_qp_free (struct mlx4_dev *dev,struct mlx4_qp *qp); -int mlx4_srq_alloc (struct mlx4_dev *dev,u32 pdn,struct mlx4_mtt *mtt, -u64 db_rec,struct mlx4_srq *srq); +int mlx4_srq_alloc (struct mlx4_dev *dev,u32 pdn,u32 cqn,u16 xrcd, +struct mlx4_mtt *mtt,u64 db_rec,struct mlx4_srq *srq);void mlx4_srq_free (struct mlx4_dev *dev,struct mlx4_srq *srq);int mlx4_srq_arm (struct mlx4_dev *dev,struct mlx4_srq *srq,int limit_watermark);int mlx4_srq_query (struct mlx4_dev *dev,struct mlx4_srq *srq,int *limit_watermark);
include/linux/mlx4/qp.h +2 -1
@@ -74,6 +74,7 @@ enum {MLX4_QP_ST_UC =0x1 ,MLX4_QP_ST_RD =0x2 ,MLX4_QP_ST_UD =0x3 , +MLX4_QP_ST_XRC =0x6 , MLX4_QP_ST_MLX = 0x7 };
@@ -136,7 +137,7 @@ struct mlx4_qp_context {__be32 ssn;__be32 params2;__be32 rnr_nextrecvpsn; -__be32 srcd; +__be32 xrcd;__be32 cqn_recv;__be64 db_rec_addr;__be32 qkey;
include/linux/mlx4/srq.h +12 -0
@@ -33,10 +33,22 @@#ifndef MLX4_SRQ_H #define MLX4_SRQ_H +#include <linux/types.h> +#include <linux/mlx4/device.h> +struct mlx4_wqe_srq_next_seg {u16 reserved1;__be16 next_wqe_index;u32 reserved2[3 ]; }; +void mlx4_srq_invalidate (struct mlx4_dev *dev,struct mlx4_srq *srq); +void mlx4_srq_remove (struct mlx4_dev *dev,struct mlx4_srq *srq); + +static inline struct mlx4_srq *__mlx4_srq_lookup (struct mlx4_dev *dev,u32 srqn) +{ +return radix_tree_lookup (&dev->srq_table_tree, + srqn & (dev->caps.num_srqs -1 )); +} +#endif /* MLX4_SRQ_H */
Signature · 6 lines
1.6.3.2 -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html