History

RDMA/mlx5: Lower setting the umem's PAS for SRQ

Some of the SRQ types are created using a WQ, and the WQ requires a different parameter set to mlx5_umem_find_best_quantized_pgoff() as it has a 5 bit page_offset. Add the umem to the mlx5_srq_attr and defer computing the PAS data until the code has figured out what kind of mailbox to use. Compute the PAS directly from the umem for each of the four unique mailbox types. This also avoids allocating memory to store the user PAS, instead it is written directly to the mailbox as in most other cases.

Jason Gunthorpe committed 6 years ago

Commit 8a7904a1 parent 878f7b33 files · +79 −29Browse files

Unified · Split

3 files
  1. drivers/infiniband/hw/mlx5/srq.c +2 −25
  2. drivers/infiniband/hw/mlx5/srq.h +1 −0
  3. drivers/infiniband/hw/mlx5/srq_cmd.c +76 −4
drivers/infiniband/hw/mlx5/srq.c+2−25
@@ -51,8 +51,6 @@ static int create_srq_user(struct ib_pd *pd, struct mlx5_ib_srq *srq, · 50 unmodified lines
5151 udata, struct mlx5_ib_ucontext, ibucontext);
5252 size_t ucmdlen;
5353 int err;
54− unsigned int page_offset_quantized;
55− unsigned int page_size;
5654 u32 uidx = MLX5_IB_DEFAULT_UIDX;
5755
5856 ucmdlen = min(udata->inlen, sizeof(ucmd));
@@ -84,32 +82,14 @@ static int create_srq_user(struct ib_pd *pd, struct mlx5_ib_srq *srq, · 25 unmodified lines
8482 err = PTR_ERR(srq->umem);
8583 return err;
8684 }
87−
88− page_size = mlx5_umem_find_best_quantized_pgoff(
89− srq->umem, srqc, log_page_size, MLX5_ADAPTER_PAGE_SHIFT,
90− page_offset, 64, &page_offset_quantized);
91− if (!page_size) {
92− mlx5_ib_warn(dev, "bad offset\n");
93− goto err_umem;
94− }
95−
96− in->pas = kvcalloc(ib_umem_num_dma_blocks(srq->umem, page_size),
97− sizeof(*in->pas), GFP_KERNEL);
98− if (!in->pas) {
99− err = -ENOMEM;
100− goto err_umem;
101− }
102−
103− mlx5_ib_populate_pas(srq->umem, page_size, in->pas, 0);
85+ in->umem = srq->umem;
10486
10587 err = mlx5_ib_db_map_user(ucontext, udata, ucmd.db_addr, &srq->db);
10688 if (err) {
10789 mlx5_ib_dbg(dev, "map doorbell failed\n");
108− goto err_in;
90+ goto err_umem;
10991 }
11092
111− in->log_page_size = order_base_2(page_size) - MLX5_ADAPTER_PAGE_SHIFT;
112− in->page_offset = page_offset_quantized;
11393 in->uid = (in->type != IB_SRQT_XRC) ? to_mpd(pd)->uid : 0;
11494 if (MLX5_CAP_GEN(dev->mdev, cqe_version) == MLX5_CQE_VERSION_V1 &&
11595 in->type != IB_SRQT_BASIC)
@@ -117,9 +97,6 @@ static int create_srq_user(struct ib_pd *pd, struct mlx5_ib_srq *srq, · 1 unmodified line
11797
11898 return 0;
11999
120−err_in:
121− kvfree(in->pas);
122−
123100 err_umem:
124101 ib_umem_release(srq->umem);
125102
drivers/infiniband/hw/mlx5/srq.h+1−0
@@ -28,6 +28,7 @@ struct mlx5_srq_attr { · 27 unmodified lines
2828 u32 user_index;
2929 u64 db_record;
3030 __be64 *pas;
31+ struct ib_umem *umem;
3132 u32 tm_log_list_size;
3233 u32 tm_next_tag;
3334 u32 tm_hw_phase_cnt;
drivers/infiniband/hw/mlx5/srq_cmd.c+76−4
@@ -92,6 +92,25 @@ struct mlx5_core_srq *mlx5_cmd_get_srq(struct mlx5_ib_dev *dev, u32 srqn) · 91 unmodified lines
9292 return srq;
9393 }
9494
95+static int __set_srq_page_size(struct mlx5_srq_attr *in,
96+ unsigned long page_size)
97+{
98+ if (!page_size)
99+ return -EINVAL;
100+ in->log_page_size = order_base_2(page_size) - MLX5_ADAPTER_PAGE_SHIFT;
101+
102+ if (WARN_ON(get_pas_size(in) !=
103+ ib_umem_num_dma_blocks(in->umem, page_size) * sizeof(u64)))
104+ return -EINVAL;
105+ return 0;
106+}
107+
108+#define set_srq_page_size(in, typ, log_pgsz_fld) \
109+ __set_srq_page_size(in, mlx5_umem_find_best_quantized_pgoff( \
110+ (in)->umem, typ, log_pgsz_fld, \
111+ MLX5_ADAPTER_PAGE_SHIFT, page_offset, \
112+ 64, &(in)->page_offset))
113+
95114 static int create_srq_cmd(struct mlx5_ib_dev *dev, struct mlx5_core_srq *srq,
96115 struct mlx5_srq_attr *in)
97116 {
@@ -103,6 +122,12 @@ static int create_srq_cmd(struct mlx5_ib_dev *dev, struct mlx5_core_srq *srq, · 5 unmodified lines
103122 int inlen;
104123 int err;
105124
125+ if (in->umem) {
126+ err = set_srq_page_size(in, srqc, log_page_size);
127+ if (err)
128+ return err;
129+ }
130+
106131 pas_size = get_pas_size(in);
107132 inlen = MLX5_ST_SZ_BYTES(create_srq_in) + pas_size;
108133 create_in = kvzalloc(inlen, GFP_KERNEL);
@@ -114,7 +139,13 @@ static int create_srq_cmd(struct mlx5_ib_dev *dev, struct mlx5_core_srq *srq, · 5 unmodified lines
114139 pas = MLX5_ADDR_OF(create_srq_in, create_in, pas);
115140
116141 set_srqc(srqc, in);
117− memcpy(pas, in->pas, pas_size);
142+ if (in->umem)
143+ mlx5_ib_populate_pas(
144+ in->umem,
145+ 1UL << (in->log_page_size + MLX5_ADAPTER_PAGE_SHIFT),
146+ pas, 0);
147+ else
148+ memcpy(pas, in->pas, pas_size);
118149
119150 MLX5_SET(create_srq_in, create_in, opcode,
120151 MLX5_CMD_OP_CREATE_SRQ);
@@ -194,6 +225,12 @@ static int create_xrc_srq_cmd(struct mlx5_ib_dev *dev, · 73 unmodified lines
194225 int inlen;
195226 int err;
196227
228+ if (in->umem) {
229+ err = set_srq_page_size(in, xrc_srqc, log_page_size);
230+ if (err)
231+ return err;
232+ }
233+
197234 pas_size = get_pas_size(in);
198235 inlen = MLX5_ST_SZ_BYTES(create_xrc_srq_in) + pas_size;
199236 create_in = kvzalloc(inlen, GFP_KERNEL);
@@ -207,7 +244,13 @@ static int create_xrc_srq_cmd(struct mlx5_ib_dev *dev, · 7 unmodified lines
207244
208245 set_srqc(xrc_srqc, in);
209246 MLX5_SET(xrc_srqc, xrc_srqc, user_index, in->user_index);
210− memcpy(pas, in->pas, pas_size);
247+ if (in->umem)
248+ mlx5_ib_populate_pas(
249+ in->umem,
250+ 1UL << (in->log_page_size + MLX5_ADAPTER_PAGE_SHIFT),
251+ pas, 0);
252+ else
253+ memcpy(pas, in->pas, pas_size);
211254 MLX5_SET(create_xrc_srq_in, create_in, opcode,
212255 MLX5_CMD_OP_CREATE_XRC_SRQ);
213256
@@ -289,11 +332,18 @@ static int create_rmp_cmd(struct mlx5_ib_dev *dev, struct mlx5_core_srq *srq, · 75 unmodified lines
289332 void *create_in = NULL;
290333 void *rmpc;
291334 void *wq;
335+ void *pas;
292336 int pas_size;
293337 int outlen;
294338 int inlen;
295339 int err;
296340
341+ if (in->umem) {
342+ err = set_srq_page_size(in, wq, log_wq_pg_sz);
343+ if (err)
344+ return err;
345+ }
346+
297347 pas_size = get_pas_size(in);
298348 inlen = MLX5_ST_SZ_BYTES(create_rmp_in) + pas_size;
299349 outlen = MLX5_ST_SZ_BYTES(create_rmp_out);
@@ -309,8 +359,16 @@ static int create_rmp_cmd(struct mlx5_ib_dev *dev, struct mlx5_core_srq *srq, · 9 unmodified lines
309359
310360 MLX5_SET(rmpc, rmpc, state, MLX5_RMPC_STATE_RDY);
311361 MLX5_SET(create_rmp_in, create_in, uid, in->uid);
362+ pas = MLX5_ADDR_OF(rmpc, rmpc, wq.pas);
363+
312364 set_wq(wq, in);
313− memcpy(MLX5_ADDR_OF(rmpc, rmpc, wq.pas), in->pas, pas_size);
365+ if (in->umem)
366+ mlx5_ib_populate_pas(
367+ in->umem,
368+ 1UL << (in->log_page_size + MLX5_ADAPTER_PAGE_SHIFT),
369+ pas, 0);
370+ else
371+ memcpy(pas, in->pas, pas_size);
314372
315373 MLX5_SET(create_rmp_in, create_in, opcode, MLX5_CMD_OP_CREATE_RMP);
316374 err = mlx5_cmd_exec(dev->mdev, create_in, inlen, create_out, outlen);
@@ -421,10 +479,17 @@ static int create_xrq_cmd(struct mlx5_ib_dev *dev, struct mlx5_core_srq *srq, · 104 unmodified lines
421479 void *create_in;
422480 void *xrqc;
423481 void *wq;
482+ void *pas;
424483 int pas_size;
425484 int inlen;
426485 int err;
427486
487+ if (in->umem) {
488+ err = set_srq_page_size(in, wq, log_wq_pg_sz);
489+ if (err)
490+ return err;
491+ }
492+
428493 pas_size = get_pas_size(in);
429494 inlen = MLX5_ST_SZ_BYTES(create_xrq_in) + pas_size;
430495 create_in = kvzalloc(inlen, GFP_KERNEL);
@@ -433,9 +498,16 @@ static int create_xrq_cmd(struct mlx5_ib_dev *dev, struct mlx5_core_srq *srq, · 2 unmodified lines
433498
434499 xrqc = MLX5_ADDR_OF(create_xrq_in, create_in, xrq_context);
435500 wq = MLX5_ADDR_OF(xrqc, xrqc, wq);
501+ pas = MLX5_ADDR_OF(xrqc, xrqc, wq.pas);
436502
437503 set_wq(wq, in);
438− memcpy(MLX5_ADDR_OF(xrqc, xrqc, wq.pas), in->pas, pas_size);
504+ if (in->umem)
505+ mlx5_ib_populate_pas(
506+ in->umem,
507+ 1UL << (in->log_page_size + MLX5_ADAPTER_PAGE_SHIFT),
508+ pas, 0);
509+ else
510+ memcpy(pas, in->pas, pas_size);
439511
440512 if (in->type == IB_SRQT_TM) {
441513 MLX5_SET(xrqc, xrqc, topology, MLX5_XRQC_TOPOLOGY_TAG_MATCHING);