aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShani Michaeli <shanim@mellanox.com>2013-02-06 11:19:15 -0500
committerRoland Dreier <roland@purestorage.com>2013-02-25 13:44:32 -0500
commit6ff63e194066a1f14aee805366a1d79c541fddae (patch)
treed619416f696cf6859587fa5875845609a9ba6a4e
parent804d6a89a5c0b076317966bcbcd7a63d42241831 (diff)
IB/mlx4: Support memory window binding
* Implement memory windows binding in mlx4_ib_post_send. * Implement mlx4_ib_bind_mw by deferring to mlx4_ib_post_send. * Rename MLX4_WQE_FMR_PERM_* flags to MLX4_WQE_FMR_AND_BIND_PERM_*, indicating that they are used both for fast registration work requests, and for memory window bind work requests. Signed-off-by: Haggai Eran <haggaie@mellanox.com> Signed-off-by: Shani Michaeli <shanim@mellanox.com> Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
-rw-r--r--drivers/infiniband/hw/mlx4/mlx4_ib.h2
-rw-r--r--drivers/infiniband/hw/mlx4/mr.c22
-rw-r--r--drivers/infiniband/hw/mlx4/qp.c35
-rw-r--r--include/linux/mlx4/qp.h11
4 files changed, 64 insertions, 6 deletions
diff --git a/drivers/infiniband/hw/mlx4/mlx4_ib.h b/drivers/infiniband/hw/mlx4/mlx4_ib.h
index 9ba0aaf3a58e..f61ec26500c4 100644
--- a/drivers/infiniband/hw/mlx4/mlx4_ib.h
+++ b/drivers/infiniband/hw/mlx4/mlx4_ib.h
@@ -592,6 +592,8 @@ struct ib_mr *mlx4_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
592 struct ib_udata *udata); 592 struct ib_udata *udata);
593int mlx4_ib_dereg_mr(struct ib_mr *mr); 593int mlx4_ib_dereg_mr(struct ib_mr *mr);
594struct ib_mw *mlx4_ib_alloc_mw(struct ib_pd *pd, enum ib_mw_type type); 594struct ib_mw *mlx4_ib_alloc_mw(struct ib_pd *pd, enum ib_mw_type type);
595int mlx4_ib_bind_mw(struct ib_qp *qp, struct ib_mw *mw,
596 struct ib_mw_bind *mw_bind);
595int mlx4_ib_dealloc_mw(struct ib_mw *mw); 597int mlx4_ib_dealloc_mw(struct ib_mw *mw);
596struct ib_mr *mlx4_ib_alloc_fast_reg_mr(struct ib_pd *pd, 598struct ib_mr *mlx4_ib_alloc_fast_reg_mr(struct ib_pd *pd,
597 int max_page_list_len); 599 int max_page_list_len);
diff --git a/drivers/infiniband/hw/mlx4/mr.c b/drivers/infiniband/hw/mlx4/mr.c
index 5adf4c47ee18..e471f089ff00 100644
--- a/drivers/infiniband/hw/mlx4/mr.c
+++ b/drivers/infiniband/hw/mlx4/mr.c
@@ -231,6 +231,28 @@ err_free:
231 return ERR_PTR(err); 231 return ERR_PTR(err);
232} 232}
233 233
234int mlx4_ib_bind_mw(struct ib_qp *qp, struct ib_mw *mw,
235 struct ib_mw_bind *mw_bind)
236{
237 struct ib_send_wr wr;
238 struct ib_send_wr *bad_wr;
239 int ret;
240
241 memset(&wr, 0, sizeof(wr));
242 wr.opcode = IB_WR_BIND_MW;
243 wr.wr_id = mw_bind->wr_id;
244 wr.send_flags = mw_bind->send_flags;
245 wr.wr.bind_mw.mw = mw;
246 wr.wr.bind_mw.bind_info = mw_bind->bind_info;
247 wr.wr.bind_mw.rkey = ib_inc_rkey(mw->rkey);
248
249 ret = mlx4_ib_post_send(qp, &wr, &bad_wr);
250 if (!ret)
251 mw->rkey = wr.wr.bind_mw.rkey;
252
253 return ret;
254}
255
234int mlx4_ib_dealloc_mw(struct ib_mw *ibmw) 256int mlx4_ib_dealloc_mw(struct ib_mw *ibmw)
235{ 257{
236 struct mlx4_ib_mw *mw = to_mmw(ibmw); 258 struct mlx4_ib_mw *mw = to_mmw(ibmw);
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c
index ebadebe83b11..35cced2a4da8 100644
--- a/drivers/infiniband/hw/mlx4/qp.c
+++ b/drivers/infiniband/hw/mlx4/qp.c
@@ -104,6 +104,7 @@ static const __be32 mlx4_ib_opcode[] = {
104 [IB_WR_FAST_REG_MR] = cpu_to_be32(MLX4_OPCODE_FMR), 104 [IB_WR_FAST_REG_MR] = cpu_to_be32(MLX4_OPCODE_FMR),
105 [IB_WR_MASKED_ATOMIC_CMP_AND_SWP] = cpu_to_be32(MLX4_OPCODE_MASKED_ATOMIC_CS), 105 [IB_WR_MASKED_ATOMIC_CMP_AND_SWP] = cpu_to_be32(MLX4_OPCODE_MASKED_ATOMIC_CS),
106 [IB_WR_MASKED_ATOMIC_FETCH_AND_ADD] = cpu_to_be32(MLX4_OPCODE_MASKED_ATOMIC_FA), 106 [IB_WR_MASKED_ATOMIC_FETCH_AND_ADD] = cpu_to_be32(MLX4_OPCODE_MASKED_ATOMIC_FA),
107 [IB_WR_BIND_MW] = cpu_to_be32(MLX4_OPCODE_BIND_MW),
107}; 108};
108 109
109static struct mlx4_ib_sqp *to_msqp(struct mlx4_ib_qp *mqp) 110static struct mlx4_ib_sqp *to_msqp(struct mlx4_ib_qp *mqp)
@@ -1953,9 +1954,12 @@ static int mlx4_wq_overflow(struct mlx4_ib_wq *wq, int nreq, struct ib_cq *ib_cq
1953 1954
1954static __be32 convert_access(int acc) 1955static __be32 convert_access(int acc)
1955{ 1956{
1956 return (acc & IB_ACCESS_REMOTE_ATOMIC ? cpu_to_be32(MLX4_WQE_FMR_PERM_ATOMIC) : 0) | 1957 return (acc & IB_ACCESS_REMOTE_ATOMIC ?
1957 (acc & IB_ACCESS_REMOTE_WRITE ? cpu_to_be32(MLX4_WQE_FMR_PERM_REMOTE_WRITE) : 0) | 1958 cpu_to_be32(MLX4_WQE_FMR_AND_BIND_PERM_ATOMIC) : 0) |
1958 (acc & IB_ACCESS_REMOTE_READ ? cpu_to_be32(MLX4_WQE_FMR_PERM_REMOTE_READ) : 0) | 1959 (acc & IB_ACCESS_REMOTE_WRITE ?
1960 cpu_to_be32(MLX4_WQE_FMR_AND_BIND_PERM_REMOTE_WRITE) : 0) |
1961 (acc & IB_ACCESS_REMOTE_READ ?
1962 cpu_to_be32(MLX4_WQE_FMR_AND_BIND_PERM_REMOTE_READ) : 0) |
1959 (acc & IB_ACCESS_LOCAL_WRITE ? cpu_to_be32(MLX4_WQE_FMR_PERM_LOCAL_WRITE) : 0) | 1963 (acc & IB_ACCESS_LOCAL_WRITE ? cpu_to_be32(MLX4_WQE_FMR_PERM_LOCAL_WRITE) : 0) |
1960 cpu_to_be32(MLX4_WQE_FMR_PERM_LOCAL_READ); 1964 cpu_to_be32(MLX4_WQE_FMR_PERM_LOCAL_READ);
1961} 1965}
@@ -1981,6 +1985,24 @@ static void set_fmr_seg(struct mlx4_wqe_fmr_seg *fseg, struct ib_send_wr *wr)
1981 fseg->reserved[1] = 0; 1985 fseg->reserved[1] = 0;
1982} 1986}
1983 1987
1988static void set_bind_seg(struct mlx4_wqe_bind_seg *bseg, struct ib_send_wr *wr)
1989{
1990 bseg->flags1 =
1991 convert_access(wr->wr.bind_mw.bind_info.mw_access_flags) &
1992 cpu_to_be32(MLX4_WQE_FMR_AND_BIND_PERM_REMOTE_READ |
1993 MLX4_WQE_FMR_AND_BIND_PERM_REMOTE_WRITE |
1994 MLX4_WQE_FMR_AND_BIND_PERM_ATOMIC);
1995 bseg->flags2 = 0;
1996 if (wr->wr.bind_mw.mw->type == IB_MW_TYPE_2)
1997 bseg->flags2 |= cpu_to_be32(MLX4_WQE_BIND_TYPE_2);
1998 if (wr->wr.bind_mw.bind_info.mw_access_flags & IB_ZERO_BASED)
1999 bseg->flags2 |= cpu_to_be32(MLX4_WQE_BIND_ZERO_BASED);
2000 bseg->new_rkey = cpu_to_be32(wr->wr.bind_mw.rkey);
2001 bseg->lkey = cpu_to_be32(wr->wr.bind_mw.bind_info.mr->lkey);
2002 bseg->addr = cpu_to_be64(wr->wr.bind_mw.bind_info.addr);
2003 bseg->length = cpu_to_be64(wr->wr.bind_mw.bind_info.length);
2004}
2005
1984static void set_local_inv_seg(struct mlx4_wqe_local_inval_seg *iseg, u32 rkey) 2006static void set_local_inv_seg(struct mlx4_wqe_local_inval_seg *iseg, u32 rkey)
1985{ 2007{
1986 memset(iseg, 0, sizeof(*iseg)); 2008 memset(iseg, 0, sizeof(*iseg));
@@ -2289,6 +2311,13 @@ int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
2289 size += sizeof (struct mlx4_wqe_fmr_seg) / 16; 2311 size += sizeof (struct mlx4_wqe_fmr_seg) / 16;
2290 break; 2312 break;
2291 2313
2314 case IB_WR_BIND_MW:
2315 ctrl->srcrb_flags |=
2316 cpu_to_be32(MLX4_WQE_CTRL_STRONG_ORDER);
2317 set_bind_seg(wqe, wr);
2318 wqe += sizeof(struct mlx4_wqe_bind_seg);
2319 size += sizeof(struct mlx4_wqe_bind_seg) / 16;
2320 break;
2292 default: 2321 default:
2293 /* No extra segments required for sends */ 2322 /* No extra segments required for sends */
2294 break; 2323 break;
diff --git a/include/linux/mlx4/qp.h b/include/linux/mlx4/qp.h
index 6c8a68c602be..67f46ad6920a 100644
--- a/include/linux/mlx4/qp.h
+++ b/include/linux/mlx4/qp.h
@@ -265,6 +265,11 @@ struct mlx4_wqe_lso_seg {
265 __be32 header[0]; 265 __be32 header[0];
266}; 266};
267 267
268enum mlx4_wqe_bind_seg_flags2 {
269 MLX4_WQE_BIND_ZERO_BASED = (1 << 30),
270 MLX4_WQE_BIND_TYPE_2 = (1 << 31),
271};
272
268struct mlx4_wqe_bind_seg { 273struct mlx4_wqe_bind_seg {
269 __be32 flags1; 274 __be32 flags1;
270 __be32 flags2; 275 __be32 flags2;
@@ -277,9 +282,9 @@ struct mlx4_wqe_bind_seg {
277enum { 282enum {
278 MLX4_WQE_FMR_PERM_LOCAL_READ = 1 << 27, 283 MLX4_WQE_FMR_PERM_LOCAL_READ = 1 << 27,
279 MLX4_WQE_FMR_PERM_LOCAL_WRITE = 1 << 28, 284 MLX4_WQE_FMR_PERM_LOCAL_WRITE = 1 << 28,
280 MLX4_WQE_FMR_PERM_REMOTE_READ = 1 << 29, 285 MLX4_WQE_FMR_AND_BIND_PERM_REMOTE_READ = 1 << 29,
281 MLX4_WQE_FMR_PERM_REMOTE_WRITE = 1 << 30, 286 MLX4_WQE_FMR_AND_BIND_PERM_REMOTE_WRITE = 1 << 30,
282 MLX4_WQE_FMR_PERM_ATOMIC = 1 << 31 287 MLX4_WQE_FMR_AND_BIND_PERM_ATOMIC = 1 << 31
283}; 288};
284 289
285struct mlx4_wqe_fmr_seg { 290struct mlx4_wqe_fmr_seg {