Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

{net,IB}/mlx5: Modify QP commands via mlx5 ifc

Prior to this patch we assumed that modify QP commands have the
same layout.

In ConnectX-4 for each QP transition there is a specific command
and their layout can vary.

e.g: 2err/2rst commands don't have QP context in their layout and before
this patch we posted the QP context in those commands.

Fortunately the FW only checks the suffix of the commands and executes
them, while ignoring all invalid data sent after the valid command
layout.

This patch removes mlx5_modify_qp_mbox_in and changes
mlx5_core_qp_modify to receive the required transition and QP context
with opt_param_mask if needed. This way the caller is not required to
provide the command inbox layout and it will be generated automatically.

mlx5_core_qp_modify will generate the command inbox/outbox layouts
according to the requested transition and will fill the requested
parameters.

Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
Signed-off-by: Leon Romanovsky <leon@kernel.org>

authored by

Saeed Mahameed and committed by
Leon Romanovsky
1a412fb1 09a7d9ec

+124 -42
+6 -16
drivers/infiniband/hw/mlx5/qp.c
··· 1871 1871 { 1872 1872 struct mlx5_ib_cq *send_cq, *recv_cq; 1873 1873 struct mlx5_ib_qp_base *base = &qp->trans_qp.base; 1874 - struct mlx5_modify_qp_mbox_in *in; 1875 1874 unsigned long flags; 1876 1875 int err; 1877 1876 ··· 1883 1884 &qp->raw_packet_qp.rq.base : 1884 1885 &qp->trans_qp.base; 1885 1886 1886 - in = kzalloc(sizeof(*in), GFP_KERNEL); 1887 - if (!in) 1888 - return; 1889 - 1890 1887 if (qp->state != IB_QPS_RESET) { 1891 1888 if (qp->ibqp.qp_type != IB_QPT_RAW_PACKET) { 1892 1889 mlx5_ib_qp_disable_pagefaults(qp); 1893 1890 err = mlx5_core_qp_modify(dev->mdev, 1894 - MLX5_CMD_OP_2RST_QP, in, 0, 1895 - &base->mqp); 1891 + MLX5_CMD_OP_2RST_QP, 0, 1892 + NULL, &base->mqp); 1896 1893 } else { 1897 1894 err = modify_raw_packet_qp(dev, qp, 1898 1895 MLX5_CMD_OP_2RST_QP); ··· 1929 1934 mlx5_ib_warn(dev, "failed to destroy QP 0x%x\n", 1930 1935 base->mqp.qpn); 1931 1936 } 1932 - 1933 - kfree(in); 1934 1937 1935 1938 if (qp->create_type == MLX5_QP_KERNEL) 1936 1939 destroy_qp_kernel(dev, qp); ··· 2515 2522 struct mlx5_ib_qp_base *base = &qp->trans_qp.base; 2516 2523 struct mlx5_ib_cq *send_cq, *recv_cq; 2517 2524 struct mlx5_qp_context *context; 2518 - struct mlx5_modify_qp_mbox_in *in; 2519 2525 struct mlx5_ib_pd *pd; 2520 2526 enum mlx5_qp_state mlx5_cur, mlx5_new; 2521 2527 enum mlx5_qp_optpar optpar; ··· 2523 2531 int err; 2524 2532 u16 op; 2525 2533 2526 - in = kzalloc(sizeof(*in), GFP_KERNEL); 2527 - if (!in) 2534 + context = kzalloc(sizeof(*context), GFP_KERNEL); 2535 + if (!context) 2528 2536 return -ENOMEM; 2529 2537 2530 - context = &in->ctx; 2531 2538 err = to_mlx5_st(ibqp->qp_type); 2532 2539 if (err < 0) { 2533 2540 mlx5_ib_dbg(dev, "unsupported qp type %d\n", ibqp->qp_type); ··· 2691 2700 op = optab[mlx5_cur][mlx5_new]; 2692 2701 optpar = ib_mask_to_mlx5_opt(attr_mask); 2693 2702 optpar &= opt_mask[mlx5_cur][mlx5_new][mlx5_st]; 2694 - in->optparam = cpu_to_be32(optpar); 2695 2703 2696 2704 if (qp->ibqp.qp_type == IB_QPT_RAW_PACKET) 2697 2705 err = modify_raw_packet_qp(dev, qp, op); 2698 2706 else 2699 - err = mlx5_core_qp_modify(dev->mdev, op, in, sqd_event, 2707 + err = mlx5_core_qp_modify(dev->mdev, op, optpar, context, 2700 2708 &base->mqp); 2701 2709 if (err) 2702 2710 goto out; ··· 2736 2746 } 2737 2747 2738 2748 out: 2739 - kfree(in); 2749 + kfree(context); 2740 2750 return err; 2741 2751 } 2742 2752
+115 -9
drivers/net/ethernet/mellanox/mlx5/core/qp.c
··· 335 335 } 336 336 EXPORT_SYMBOL_GPL(mlx5_core_destroy_qp); 337 337 338 - int mlx5_core_qp_modify(struct mlx5_core_dev *dev, u16 operation, 339 - struct mlx5_modify_qp_mbox_in *in, int sqd_event, 338 + struct mbox_info { 339 + u32 *in; 340 + u32 *out; 341 + int inlen; 342 + int outlen; 343 + }; 344 + 345 + static int mbox_alloc(struct mbox_info *mbox, int inlen, int outlen) 346 + { 347 + mbox->inlen = inlen; 348 + mbox->outlen = outlen; 349 + mbox->in = kzalloc(mbox->inlen, GFP_KERNEL); 350 + mbox->out = kzalloc(mbox->outlen, GFP_KERNEL); 351 + if (!mbox->in || !mbox->out) { 352 + kfree(mbox->in); 353 + kfree(mbox->out); 354 + return -ENOMEM; 355 + } 356 + 357 + return 0; 358 + } 359 + 360 + static void mbox_free(struct mbox_info *mbox) 361 + { 362 + kfree(mbox->in); 363 + kfree(mbox->out); 364 + } 365 + 366 + static int modify_qp_mbox_alloc(struct mlx5_core_dev *dev, u16 opcode, int qpn, 367 + u32 opt_param_mask, void *qpc, 368 + struct mbox_info *mbox) 369 + { 370 + mbox->out = NULL; 371 + mbox->in = NULL; 372 + 373 + #define MBOX_ALLOC(mbox, typ) \ 374 + mbox_alloc(mbox, MLX5_ST_SZ_BYTES(typ##_in), MLX5_ST_SZ_BYTES(typ##_out)) 375 + 376 + #define MOD_QP_IN_SET(typ, in, _opcode, _qpn) \ 377 + MLX5_SET(typ##_in, in, opcode, _opcode); \ 378 + MLX5_SET(typ##_in, in, qpn, _qpn) 379 + 380 + #define MOD_QP_IN_SET_QPC(typ, in, _opcode, _qpn, _opt_p, _qpc) \ 381 + MOD_QP_IN_SET(typ, in, _opcode, _qpn); \ 382 + MLX5_SET(typ##_in, in, opt_param_mask, _opt_p); \ 383 + memcpy(MLX5_ADDR_OF(typ##_in, in, qpc), _qpc, MLX5_ST_SZ_BYTES(qpc)) 384 + 385 + switch (opcode) { 386 + /* 2RST & 2ERR */ 387 + case MLX5_CMD_OP_2RST_QP: 388 + if (MBOX_ALLOC(mbox, qp_2rst)) 389 + return -ENOMEM; 390 + MOD_QP_IN_SET(qp_2rst, mbox->in, opcode, qpn); 391 + break; 392 + case MLX5_CMD_OP_2ERR_QP: 393 + if (MBOX_ALLOC(mbox, qp_2err)) 394 + return -ENOMEM; 395 + MOD_QP_IN_SET(qp_2err, mbox->in, opcode, qpn); 396 + break; 397 + 398 + /* MODIFY with QPC */ 399 + case MLX5_CMD_OP_RST2INIT_QP: 400 + if (MBOX_ALLOC(mbox, rst2init_qp)) 401 + return -ENOMEM; 402 + MOD_QP_IN_SET_QPC(rst2init_qp, mbox->in, opcode, qpn, 403 + opt_param_mask, qpc); 404 + break; 405 + case MLX5_CMD_OP_INIT2RTR_QP: 406 + if (MBOX_ALLOC(mbox, init2rtr_qp)) 407 + return -ENOMEM; 408 + MOD_QP_IN_SET_QPC(init2rtr_qp, mbox->in, opcode, qpn, 409 + opt_param_mask, qpc); 410 + break; 411 + case MLX5_CMD_OP_RTR2RTS_QP: 412 + if (MBOX_ALLOC(mbox, rtr2rts_qp)) 413 + return -ENOMEM; 414 + MOD_QP_IN_SET_QPC(rtr2rts_qp, mbox->in, opcode, qpn, 415 + opt_param_mask, qpc); 416 + break; 417 + case MLX5_CMD_OP_RTS2RTS_QP: 418 + if (MBOX_ALLOC(mbox, rts2rts_qp)) 419 + return -ENOMEM; 420 + MOD_QP_IN_SET_QPC(rts2rts_qp, mbox->in, opcode, qpn, 421 + opt_param_mask, qpc); 422 + break; 423 + case MLX5_CMD_OP_SQERR2RTS_QP: 424 + if (MBOX_ALLOC(mbox, sqerr2rts_qp)) 425 + return -ENOMEM; 426 + MOD_QP_IN_SET_QPC(sqerr2rts_qp, mbox->in, opcode, qpn, 427 + opt_param_mask, qpc); 428 + break; 429 + case MLX5_CMD_OP_INIT2INIT_QP: 430 + if (MBOX_ALLOC(mbox, init2init_qp)) 431 + return -ENOMEM; 432 + MOD_QP_IN_SET_QPC(init2init_qp, mbox->in, opcode, qpn, 433 + opt_param_mask, qpc); 434 + break; 435 + default: 436 + mlx5_core_err(dev, "Unknown transition for modify QP: OP(0x%x) QPN(0x%x)\n", 437 + opcode, qpn); 438 + return -EINVAL; 439 + } 440 + return 0; 441 + } 442 + 443 + int mlx5_core_qp_modify(struct mlx5_core_dev *dev, u16 opcode, 444 + u32 opt_param_mask, void *qpc, 340 445 struct mlx5_core_qp *qp) 341 446 { 342 - struct mlx5_modify_qp_mbox_out out; 343 - int err = 0; 447 + struct mbox_info mbox; 448 + int err; 344 449 345 - memset(&out, 0, sizeof(out)); 346 - in->hdr.opcode = cpu_to_be16(operation); 347 - in->qpn = cpu_to_be32(qp->qpn); 348 - err = mlx5_cmd_exec(dev, in, sizeof(*in), &out, sizeof(out)); 450 + err = modify_qp_mbox_alloc(dev, opcode, qp->qpn, 451 + opt_param_mask, qpc, &mbox); 349 452 if (err) 350 453 return err; 351 454 352 - return mlx5_cmd_status_to_err(&out.hdr); 455 + err = mlx5_cmd_exec(dev, mbox.in, mbox.inlen, mbox.out, mbox.outlen); 456 + err = err ? : mlx5_cmd_status_to_err_v2(mbox.out); 457 + mbox_free(&mbox); 458 + return err; 353 459 } 354 460 EXPORT_SYMBOL_GPL(mlx5_core_qp_modify); 355 461
+3 -17
include/linux/mlx5/qp.h
··· 479 479 u8 rmac[6]; 480 480 }; 481 481 482 + /* FIXME: use mlx5_ifc.h qpc */ 482 483 struct mlx5_qp_context { 483 484 __be32 flags; 484 485 __be32 flags_pd; ··· 521 520 u8 rsvd1[24]; 522 521 }; 523 522 524 - struct mlx5_modify_qp_mbox_in { 525 - struct mlx5_inbox_hdr hdr; 526 - __be32 qpn; 527 - u8 rsvd0[4]; 528 - __be32 optparam; 529 - u8 rsvd1[4]; 530 - struct mlx5_qp_context ctx; 531 - u8 rsvd2[16]; 532 - }; 533 - 534 - struct mlx5_modify_qp_mbox_out { 535 - struct mlx5_outbox_hdr hdr; 536 - u8 rsvd0[8]; 537 - }; 538 - 539 523 static inline struct mlx5_core_qp *__mlx5_qp_lookup(struct mlx5_core_dev *dev, u32 qpn) 540 524 { 541 525 return radix_tree_lookup(&dev->priv.qp_table.tree, qpn); ··· 535 549 struct mlx5_core_qp *qp, 536 550 u32 *in, 537 551 int inlen); 538 - int mlx5_core_qp_modify(struct mlx5_core_dev *dev, u16 operation, 539 - struct mlx5_modify_qp_mbox_in *in, int sqd_event, 552 + int mlx5_core_qp_modify(struct mlx5_core_dev *dev, u16 opcode, 553 + u32 opt_param_mask, void *qpc, 540 554 struct mlx5_core_qp *qp); 541 555 int mlx5_core_destroy_qp(struct mlx5_core_dev *dev, 542 556 struct mlx5_core_qp *qp);