| @@ -92,6 +92,25 @@ struct mlx5_core_srq *mlx5_cmd_get_srq(struct mlx5_ib_dev *dev, u32 srqn) · 91 unmodified lines |
| 92 | 92 | return srq; |
| 93 | 93 | } |
| 94 | 94 | |
| 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 | + |
| 95 | 114 | static int create_srq_cmd(struct mlx5_ib_dev *dev, struct mlx5_core_srq *srq, |
| 96 | 115 | struct mlx5_srq_attr *in) |
| 97 | 116 | { |
| @@ -103,6 +122,12 @@ static int create_srq_cmd(struct mlx5_ib_dev *dev, struct mlx5_core_srq *srq, · 5 unmodified lines |
| 103 | 122 | int inlen; |
| 104 | 123 | int err; |
| 105 | 124 | |
| 125 | + if (in->umem) { |
| 126 | + err = set_srq_page_size(in, srqc, log_page_size); |
| 127 | + if (err) |
| 128 | + return err; |
| 129 | + } |
| 130 | + |
| 106 | 131 | pas_size = get_pas_size(in); |
| 107 | 132 | inlen = MLX5_ST_SZ_BYTES(create_srq_in) + pas_size; |
| 108 | 133 | 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 |
| 114 | 139 | pas = MLX5_ADDR_OF(create_srq_in, create_in, pas); |
| 115 | 140 | |
| 116 | 141 | 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); |
| 118 | 149 | |
| 119 | 150 | MLX5_SET(create_srq_in, create_in, opcode, |
| 120 | 151 | MLX5_CMD_OP_CREATE_SRQ); |
| @@ -194,6 +225,12 @@ static int create_xrc_srq_cmd(struct mlx5_ib_dev *dev, · 73 unmodified lines |
| 194 | 225 | int inlen; |
| 195 | 226 | int err; |
| 196 | 227 | |
| 228 | + if (in->umem) { |
| 229 | + err = set_srq_page_size(in, xrc_srqc, log_page_size); |
| 230 | + if (err) |
| 231 | + return err; |
| 232 | + } |
| 233 | + |
| 197 | 234 | pas_size = get_pas_size(in); |
| 198 | 235 | inlen = MLX5_ST_SZ_BYTES(create_xrc_srq_in) + pas_size; |
| 199 | 236 | create_in = kvzalloc(inlen, GFP_KERNEL); |
| @@ -207,7 +244,13 @@ static int create_xrc_srq_cmd(struct mlx5_ib_dev *dev, · 7 unmodified lines |
| 207 | 244 | |
| 208 | 245 | set_srqc(xrc_srqc, in); |
| 209 | 246 | 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); |
| 211 | 254 | MLX5_SET(create_xrc_srq_in, create_in, opcode, |
| 212 | 255 | MLX5_CMD_OP_CREATE_XRC_SRQ); |
| 213 | 256 | |
| @@ -289,11 +332,18 @@ static int create_rmp_cmd(struct mlx5_ib_dev *dev, struct mlx5_core_srq *srq, · 75 unmodified lines |
| 289 | 332 | void *create_in = NULL; |
| 290 | 333 | void *rmpc; |
| 291 | 334 | void *wq; |
| 335 | + void *pas; |
| 292 | 336 | int pas_size; |
| 293 | 337 | int outlen; |
| 294 | 338 | int inlen; |
| 295 | 339 | int err; |
| 296 | 340 | |
| 341 | + if (in->umem) { |
| 342 | + err = set_srq_page_size(in, wq, log_wq_pg_sz); |
| 343 | + if (err) |
| 344 | + return err; |
| 345 | + } |
| 346 | + |
| 297 | 347 | pas_size = get_pas_size(in); |
| 298 | 348 | inlen = MLX5_ST_SZ_BYTES(create_rmp_in) + pas_size; |
| 299 | 349 | 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 |
| 309 | 359 | |
| 310 | 360 | MLX5_SET(rmpc, rmpc, state, MLX5_RMPC_STATE_RDY); |
| 311 | 361 | MLX5_SET(create_rmp_in, create_in, uid, in->uid); |
| 362 | + pas = MLX5_ADDR_OF(rmpc, rmpc, wq.pas); |
| 363 | + |
| 312 | 364 | 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); |
| 314 | 372 | |
| 315 | 373 | MLX5_SET(create_rmp_in, create_in, opcode, MLX5_CMD_OP_CREATE_RMP); |
| 316 | 374 | 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 |
| 421 | 479 | void *create_in; |
| 422 | 480 | void *xrqc; |
| 423 | 481 | void *wq; |
| 482 | + void *pas; |
| 424 | 483 | int pas_size; |
| 425 | 484 | int inlen; |
| 426 | 485 | int err; |
| 427 | 486 | |
| 487 | + if (in->umem) { |
| 488 | + err = set_srq_page_size(in, wq, log_wq_pg_sz); |
| 489 | + if (err) |
| 490 | + return err; |
| 491 | + } |
| 492 | + |
| 428 | 493 | pas_size = get_pas_size(in); |
| 429 | 494 | inlen = MLX5_ST_SZ_BYTES(create_xrq_in) + pas_size; |
| 430 | 495 | 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 |
| 433 | 498 | |
| 434 | 499 | xrqc = MLX5_ADDR_OF(create_xrq_in, create_in, xrq_context); |
| 435 | 500 | wq = MLX5_ADDR_OF(xrqc, xrqc, wq); |
| 501 | + pas = MLX5_ADDR_OF(xrqc, xrqc, wq.pas); |
| 436 | 502 | |
| 437 | 503 | 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); |
| 439 | 511 | |
| 440 | 512 | if (in->type == IB_SRQT_TM) { |
| 441 | 513 | MLX5_SET(xrqc, xrqc, topology, MLX5_XRQC_TOPOLOGY_TAG_MATCHING); |