5.1 First RC pull request
Several driver bug fixes post in the last three weeks - First part of a race condition fix in mlx4 with CATAS errors - Bad interaction with FW causing resource leaks in the mlx5 DCT flow - Bad reporting of link speed/width in new mlx5 devices - Userspace triggable OOPs in i40iw -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEfB7FMLh+8QxL+6i3OG33FX4gmxoFAlyO7B8ACgkQOG33FX4g mxoIPA//bfnWR/l0BdaGaOpZATqhYIvJXfGptmQD+/6SjNcv1ig0uDKh5Mfd4hf2 0ltxsDmrbLtd4JOgI0IvqOdXNnbwWJIxnGCyIX6UyVKogzZnJIuRKz0YLnALHgxt KbuPURZPDSgMLZZnj/3WghOVw8cae5K2xPt8so+x51mUzVdJeR6GwDJ7Iuslddqv c4IwG5zzsxoIZcgSSQZt2nUpUpVCly5rvII+guOXdctOCb/3BtjYfbVbAWVsK284 vTowvUS4OQJ/g2Jmej9ge9DY3Rw52+BW4NCzciJVz+QmY4hf85xt/E/6joQslRKl DdAYafvrg/XKW9z8FqCWm0PXPHtQ63MeOLHkLQi9n8NjXhyppHJR5fW69lOAtsrV V/yTTvLai+lA0Jv4bTDf/M9CkruFDjB1rlhzepytxvLGr5QcL5hwlSH0qCpVz+Xu v+ftS2hGKpi5uK4YNsye9tzP11eCLAzBUI5VkgvoOGWkUibUfkzOXLG0OzzkoUMK vaXGlkHus0dw/ojPQsNEVONZCsnB4V2LOF8wApcGtRqJocdxOzpbz0zZDLVCd7Nj JuOe44hWGzzDWrecqOepnV9sPi9UCPcZC6LWVdduF00RW38wxBMlLZTdpb8sEZje DB8QNgougQWg2UMfHAhDBFbV7/FsM/wHH7ZgIS7Xmyo8QdaAK2I= =klIw -----END PGP SIGNATURE----- Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma Pull rdma fixes from Jason Gunthorpe: "Several driver bug fixes post in the last three weeks - first part of a race condition fix in mlx4 with CATAS errors - bad interaction with FW causing resource leaks in the mlx5 DCT flow - bad reporting of link speed/width in new mlx5 devices - user triggable OOPS in i40iw" * tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma: i40iw: Avoid panic when handling the inetdev event IB/mlx5: Fix mapping of link-mode to IB width and speed IB/mlx5: Use mlx5 core to create/destroy a DEVX DCT net/mlx5: Fix DCT creation bad flow IB/mlx4: Fix race condition between catas error reset and aliasguid flows
This commit is contained in:
commit
01c8d80383
@ -173,7 +173,12 @@ int i40iw_inetaddr_event(struct notifier_block *notifier,
|
|||||||
|
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
in = __in_dev_get_rcu(upper_dev);
|
in = __in_dev_get_rcu(upper_dev);
|
||||||
local_ipaddr = ntohl(in->ifa_list->ifa_address);
|
|
||||||
|
if (!in->ifa_list)
|
||||||
|
local_ipaddr = 0;
|
||||||
|
else
|
||||||
|
local_ipaddr = ntohl(in->ifa_list->ifa_address);
|
||||||
|
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
} else {
|
} else {
|
||||||
local_ipaddr = ntohl(ifa->ifa_address);
|
local_ipaddr = ntohl(ifa->ifa_address);
|
||||||
@ -185,6 +190,11 @@ int i40iw_inetaddr_event(struct notifier_block *notifier,
|
|||||||
case NETDEV_UP:
|
case NETDEV_UP:
|
||||||
/* Fall through */
|
/* Fall through */
|
||||||
case NETDEV_CHANGEADDR:
|
case NETDEV_CHANGEADDR:
|
||||||
|
|
||||||
|
/* Just skip if no need to handle ARP cache */
|
||||||
|
if (!local_ipaddr)
|
||||||
|
break;
|
||||||
|
|
||||||
i40iw_manage_arp_cache(iwdev,
|
i40iw_manage_arp_cache(iwdev,
|
||||||
netdev->dev_addr,
|
netdev->dev_addr,
|
||||||
&local_ipaddr,
|
&local_ipaddr,
|
||||||
|
@ -804,8 +804,8 @@ void mlx4_ib_destroy_alias_guid_service(struct mlx4_ib_dev *dev)
|
|||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
for (i = 0 ; i < dev->num_ports; i++) {
|
for (i = 0 ; i < dev->num_ports; i++) {
|
||||||
cancel_delayed_work(&dev->sriov.alias_guid.ports_guid[i].alias_guid_work);
|
|
||||||
det = &sriov->alias_guid.ports_guid[i];
|
det = &sriov->alias_guid.ports_guid[i];
|
||||||
|
cancel_delayed_work_sync(&det->alias_guid_work);
|
||||||
spin_lock_irqsave(&sriov->alias_guid.ag_work_lock, flags);
|
spin_lock_irqsave(&sriov->alias_guid.ag_work_lock, flags);
|
||||||
while (!list_empty(&det->cb_list)) {
|
while (!list_empty(&det->cb_list)) {
|
||||||
cb_ctx = list_entry(det->cb_list.next,
|
cb_ctx = list_entry(det->cb_list.next,
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
enum devx_obj_flags {
|
enum devx_obj_flags {
|
||||||
DEVX_OBJ_FLAGS_INDIRECT_MKEY = 1 << 0,
|
DEVX_OBJ_FLAGS_INDIRECT_MKEY = 1 << 0,
|
||||||
|
DEVX_OBJ_FLAGS_DCT = 1 << 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct devx_async_data {
|
struct devx_async_data {
|
||||||
@ -39,7 +40,10 @@ struct devx_obj {
|
|||||||
u32 dinlen; /* destroy inbox length */
|
u32 dinlen; /* destroy inbox length */
|
||||||
u32 dinbox[MLX5_MAX_DESTROY_INBOX_SIZE_DW];
|
u32 dinbox[MLX5_MAX_DESTROY_INBOX_SIZE_DW];
|
||||||
u32 flags;
|
u32 flags;
|
||||||
struct mlx5_ib_devx_mr devx_mr;
|
union {
|
||||||
|
struct mlx5_ib_devx_mr devx_mr;
|
||||||
|
struct mlx5_core_dct core_dct;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct devx_umem {
|
struct devx_umem {
|
||||||
@ -347,7 +351,6 @@ static u64 devx_get_obj_id(const void *in)
|
|||||||
obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_RQ,
|
obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_RQ,
|
||||||
MLX5_GET(arm_rq_in, in, srq_number));
|
MLX5_GET(arm_rq_in, in, srq_number));
|
||||||
break;
|
break;
|
||||||
case MLX5_CMD_OP_DRAIN_DCT:
|
|
||||||
case MLX5_CMD_OP_ARM_DCT_FOR_KEY_VIOLATION:
|
case MLX5_CMD_OP_ARM_DCT_FOR_KEY_VIOLATION:
|
||||||
obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_DCT,
|
obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_DCT,
|
||||||
MLX5_GET(drain_dct_in, in, dctn));
|
MLX5_GET(drain_dct_in, in, dctn));
|
||||||
@ -618,7 +621,6 @@ static bool devx_is_obj_modify_cmd(const void *in)
|
|||||||
case MLX5_CMD_OP_2RST_QP:
|
case MLX5_CMD_OP_2RST_QP:
|
||||||
case MLX5_CMD_OP_ARM_XRC_SRQ:
|
case MLX5_CMD_OP_ARM_XRC_SRQ:
|
||||||
case MLX5_CMD_OP_ARM_RQ:
|
case MLX5_CMD_OP_ARM_RQ:
|
||||||
case MLX5_CMD_OP_DRAIN_DCT:
|
|
||||||
case MLX5_CMD_OP_ARM_DCT_FOR_KEY_VIOLATION:
|
case MLX5_CMD_OP_ARM_DCT_FOR_KEY_VIOLATION:
|
||||||
case MLX5_CMD_OP_ARM_XRQ:
|
case MLX5_CMD_OP_ARM_XRQ:
|
||||||
case MLX5_CMD_OP_SET_XRQ_DC_PARAMS_ENTRY:
|
case MLX5_CMD_OP_SET_XRQ_DC_PARAMS_ENTRY:
|
||||||
@ -1124,7 +1126,11 @@ static int devx_obj_cleanup(struct ib_uobject *uobject,
|
|||||||
if (obj->flags & DEVX_OBJ_FLAGS_INDIRECT_MKEY)
|
if (obj->flags & DEVX_OBJ_FLAGS_INDIRECT_MKEY)
|
||||||
devx_cleanup_mkey(obj);
|
devx_cleanup_mkey(obj);
|
||||||
|
|
||||||
ret = mlx5_cmd_exec(obj->mdev, obj->dinbox, obj->dinlen, out, sizeof(out));
|
if (obj->flags & DEVX_OBJ_FLAGS_DCT)
|
||||||
|
ret = mlx5_core_destroy_dct(obj->mdev, &obj->core_dct);
|
||||||
|
else
|
||||||
|
ret = mlx5_cmd_exec(obj->mdev, obj->dinbox, obj->dinlen, out,
|
||||||
|
sizeof(out));
|
||||||
if (ib_is_destroy_retryable(ret, why, uobject))
|
if (ib_is_destroy_retryable(ret, why, uobject))
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@ -1185,9 +1191,17 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OBJ_CREATE)(
|
|||||||
devx_set_umem_valid(cmd_in);
|
devx_set_umem_valid(cmd_in);
|
||||||
}
|
}
|
||||||
|
|
||||||
err = mlx5_cmd_exec(dev->mdev, cmd_in,
|
if (opcode == MLX5_CMD_OP_CREATE_DCT) {
|
||||||
cmd_in_len,
|
obj->flags |= DEVX_OBJ_FLAGS_DCT;
|
||||||
cmd_out, cmd_out_len);
|
err = mlx5_core_create_dct(dev->mdev, &obj->core_dct,
|
||||||
|
cmd_in, cmd_in_len,
|
||||||
|
cmd_out, cmd_out_len);
|
||||||
|
} else {
|
||||||
|
err = mlx5_cmd_exec(dev->mdev, cmd_in,
|
||||||
|
cmd_in_len,
|
||||||
|
cmd_out, cmd_out_len);
|
||||||
|
}
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
goto obj_free;
|
goto obj_free;
|
||||||
|
|
||||||
@ -1214,7 +1228,11 @@ err_copy:
|
|||||||
if (obj->flags & DEVX_OBJ_FLAGS_INDIRECT_MKEY)
|
if (obj->flags & DEVX_OBJ_FLAGS_INDIRECT_MKEY)
|
||||||
devx_cleanup_mkey(obj);
|
devx_cleanup_mkey(obj);
|
||||||
obj_destroy:
|
obj_destroy:
|
||||||
mlx5_cmd_exec(obj->mdev, obj->dinbox, obj->dinlen, out, sizeof(out));
|
if (obj->flags & DEVX_OBJ_FLAGS_DCT)
|
||||||
|
mlx5_core_destroy_dct(obj->mdev, &obj->core_dct);
|
||||||
|
else
|
||||||
|
mlx5_cmd_exec(obj->mdev, obj->dinbox, obj->dinlen, out,
|
||||||
|
sizeof(out));
|
||||||
obj_free:
|
obj_free:
|
||||||
kfree(obj);
|
kfree(obj);
|
||||||
return err;
|
return err;
|
||||||
|
@ -415,10 +415,17 @@ static int translate_eth_ext_proto_oper(u32 eth_proto_oper, u8 *active_speed,
|
|||||||
*active_speed = IB_SPEED_EDR;
|
*active_speed = IB_SPEED_EDR;
|
||||||
break;
|
break;
|
||||||
case MLX5E_PROT_MASK(MLX5E_50GAUI_2_LAUI_2_50GBASE_CR2_KR2):
|
case MLX5E_PROT_MASK(MLX5E_50GAUI_2_LAUI_2_50GBASE_CR2_KR2):
|
||||||
|
*active_width = IB_WIDTH_2X;
|
||||||
|
*active_speed = IB_SPEED_EDR;
|
||||||
|
break;
|
||||||
case MLX5E_PROT_MASK(MLX5E_50GAUI_1_LAUI_1_50GBASE_CR_KR):
|
case MLX5E_PROT_MASK(MLX5E_50GAUI_1_LAUI_1_50GBASE_CR_KR):
|
||||||
*active_width = IB_WIDTH_1X;
|
*active_width = IB_WIDTH_1X;
|
||||||
*active_speed = IB_SPEED_HDR;
|
*active_speed = IB_SPEED_HDR;
|
||||||
break;
|
break;
|
||||||
|
case MLX5E_PROT_MASK(MLX5E_CAUI_4_100GBASE_CR4_KR4):
|
||||||
|
*active_width = IB_WIDTH_4X;
|
||||||
|
*active_speed = IB_SPEED_EDR;
|
||||||
|
break;
|
||||||
case MLX5E_PROT_MASK(MLX5E_100GAUI_2_100GBASE_CR2_KR2):
|
case MLX5E_PROT_MASK(MLX5E_100GAUI_2_100GBASE_CR2_KR2):
|
||||||
*active_width = IB_WIDTH_2X;
|
*active_width = IB_WIDTH_2X;
|
||||||
*active_speed = IB_SPEED_HDR;
|
*active_speed = IB_SPEED_HDR;
|
||||||
|
@ -3729,6 +3729,7 @@ static int mlx5_ib_modify_dct(struct ib_qp *ibqp, struct ib_qp_attr *attr,
|
|||||||
|
|
||||||
} else if (cur_state == IB_QPS_INIT && new_state == IB_QPS_RTR) {
|
} else if (cur_state == IB_QPS_INIT && new_state == IB_QPS_RTR) {
|
||||||
struct mlx5_ib_modify_qp_resp resp = {};
|
struct mlx5_ib_modify_qp_resp resp = {};
|
||||||
|
u32 out[MLX5_ST_SZ_DW(create_dct_out)] = {0};
|
||||||
u32 min_resp_len = offsetof(typeof(resp), dctn) +
|
u32 min_resp_len = offsetof(typeof(resp), dctn) +
|
||||||
sizeof(resp.dctn);
|
sizeof(resp.dctn);
|
||||||
|
|
||||||
@ -3747,7 +3748,8 @@ static int mlx5_ib_modify_dct(struct ib_qp *ibqp, struct ib_qp_attr *attr,
|
|||||||
MLX5_SET(dctc, dctc, hop_limit, attr->ah_attr.grh.hop_limit);
|
MLX5_SET(dctc, dctc, hop_limit, attr->ah_attr.grh.hop_limit);
|
||||||
|
|
||||||
err = mlx5_core_create_dct(dev->mdev, &qp->dct.mdct, qp->dct.in,
|
err = mlx5_core_create_dct(dev->mdev, &qp->dct.mdct, qp->dct.in,
|
||||||
MLX5_ST_SZ_BYTES(create_dct_in));
|
MLX5_ST_SZ_BYTES(create_dct_in), out,
|
||||||
|
sizeof(out));
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
resp.dctn = qp->dct.mdct.mqp.qpn;
|
resp.dctn = qp->dct.mdct.mqp.qpn;
|
||||||
|
@ -40,6 +40,9 @@
|
|||||||
#include "mlx5_core.h"
|
#include "mlx5_core.h"
|
||||||
#include "lib/eq.h"
|
#include "lib/eq.h"
|
||||||
|
|
||||||
|
static int mlx5_core_drain_dct(struct mlx5_core_dev *dev,
|
||||||
|
struct mlx5_core_dct *dct);
|
||||||
|
|
||||||
static struct mlx5_core_rsc_common *
|
static struct mlx5_core_rsc_common *
|
||||||
mlx5_get_rsc(struct mlx5_qp_table *table, u32 rsn)
|
mlx5_get_rsc(struct mlx5_qp_table *table, u32 rsn)
|
||||||
{
|
{
|
||||||
@ -227,20 +230,49 @@ static void destroy_resource_common(struct mlx5_core_dev *dev,
|
|||||||
wait_for_completion(&qp->common.free);
|
wait_for_completion(&qp->common.free);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int _mlx5_core_destroy_dct(struct mlx5_core_dev *dev,
|
||||||
|
struct mlx5_core_dct *dct, bool need_cleanup)
|
||||||
|
{
|
||||||
|
u32 out[MLX5_ST_SZ_DW(destroy_dct_out)] = {0};
|
||||||
|
u32 in[MLX5_ST_SZ_DW(destroy_dct_in)] = {0};
|
||||||
|
struct mlx5_core_qp *qp = &dct->mqp;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = mlx5_core_drain_dct(dev, dct);
|
||||||
|
if (err) {
|
||||||
|
if (dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR) {
|
||||||
|
goto destroy;
|
||||||
|
} else {
|
||||||
|
mlx5_core_warn(
|
||||||
|
dev, "failed drain DCT 0x%x with error 0x%x\n",
|
||||||
|
qp->qpn, err);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wait_for_completion(&dct->drained);
|
||||||
|
destroy:
|
||||||
|
if (need_cleanup)
|
||||||
|
destroy_resource_common(dev, &dct->mqp);
|
||||||
|
MLX5_SET(destroy_dct_in, in, opcode, MLX5_CMD_OP_DESTROY_DCT);
|
||||||
|
MLX5_SET(destroy_dct_in, in, dctn, qp->qpn);
|
||||||
|
MLX5_SET(destroy_dct_in, in, uid, qp->uid);
|
||||||
|
err = mlx5_cmd_exec(dev, (void *)&in, sizeof(in),
|
||||||
|
(void *)&out, sizeof(out));
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
int mlx5_core_create_dct(struct mlx5_core_dev *dev,
|
int mlx5_core_create_dct(struct mlx5_core_dev *dev,
|
||||||
struct mlx5_core_dct *dct,
|
struct mlx5_core_dct *dct,
|
||||||
u32 *in, int inlen)
|
u32 *in, int inlen,
|
||||||
|
u32 *out, int outlen)
|
||||||
{
|
{
|
||||||
u32 out[MLX5_ST_SZ_DW(create_dct_out)] = {0};
|
|
||||||
u32 din[MLX5_ST_SZ_DW(destroy_dct_in)] = {0};
|
|
||||||
u32 dout[MLX5_ST_SZ_DW(destroy_dct_out)] = {0};
|
|
||||||
struct mlx5_core_qp *qp = &dct->mqp;
|
struct mlx5_core_qp *qp = &dct->mqp;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
init_completion(&dct->drained);
|
init_completion(&dct->drained);
|
||||||
MLX5_SET(create_dct_in, in, opcode, MLX5_CMD_OP_CREATE_DCT);
|
MLX5_SET(create_dct_in, in, opcode, MLX5_CMD_OP_CREATE_DCT);
|
||||||
|
|
||||||
err = mlx5_cmd_exec(dev, in, inlen, &out, sizeof(out));
|
err = mlx5_cmd_exec(dev, in, inlen, out, outlen);
|
||||||
if (err) {
|
if (err) {
|
||||||
mlx5_core_warn(dev, "create DCT failed, ret %d\n", err);
|
mlx5_core_warn(dev, "create DCT failed, ret %d\n", err);
|
||||||
return err;
|
return err;
|
||||||
@ -254,11 +286,7 @@ int mlx5_core_create_dct(struct mlx5_core_dev *dev,
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
err_cmd:
|
err_cmd:
|
||||||
MLX5_SET(destroy_dct_in, din, opcode, MLX5_CMD_OP_DESTROY_DCT);
|
_mlx5_core_destroy_dct(dev, dct, false);
|
||||||
MLX5_SET(destroy_dct_in, din, dctn, qp->qpn);
|
|
||||||
MLX5_SET(destroy_dct_in, din, uid, qp->uid);
|
|
||||||
mlx5_cmd_exec(dev, (void *)&in, sizeof(din),
|
|
||||||
(void *)&out, sizeof(dout));
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(mlx5_core_create_dct);
|
EXPORT_SYMBOL_GPL(mlx5_core_create_dct);
|
||||||
@ -323,29 +351,7 @@ static int mlx5_core_drain_dct(struct mlx5_core_dev *dev,
|
|||||||
int mlx5_core_destroy_dct(struct mlx5_core_dev *dev,
|
int mlx5_core_destroy_dct(struct mlx5_core_dev *dev,
|
||||||
struct mlx5_core_dct *dct)
|
struct mlx5_core_dct *dct)
|
||||||
{
|
{
|
||||||
u32 out[MLX5_ST_SZ_DW(destroy_dct_out)] = {0};
|
return _mlx5_core_destroy_dct(dev, dct, true);
|
||||||
u32 in[MLX5_ST_SZ_DW(destroy_dct_in)] = {0};
|
|
||||||
struct mlx5_core_qp *qp = &dct->mqp;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
err = mlx5_core_drain_dct(dev, dct);
|
|
||||||
if (err) {
|
|
||||||
if (dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR) {
|
|
||||||
goto destroy;
|
|
||||||
} else {
|
|
||||||
mlx5_core_warn(dev, "failed drain DCT 0x%x with error 0x%x\n", qp->qpn, err);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
wait_for_completion(&dct->drained);
|
|
||||||
destroy:
|
|
||||||
destroy_resource_common(dev, &dct->mqp);
|
|
||||||
MLX5_SET(destroy_dct_in, in, opcode, MLX5_CMD_OP_DESTROY_DCT);
|
|
||||||
MLX5_SET(destroy_dct_in, in, dctn, qp->qpn);
|
|
||||||
MLX5_SET(destroy_dct_in, in, uid, qp->uid);
|
|
||||||
err = mlx5_cmd_exec(dev, (void *)&in, sizeof(in),
|
|
||||||
(void *)&out, sizeof(out));
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(mlx5_core_destroy_dct);
|
EXPORT_SYMBOL_GPL(mlx5_core_destroy_dct);
|
||||||
|
|
||||||
|
@ -557,7 +557,8 @@ static inline struct mlx5_core_mkey *__mlx5_mr_lookup(struct mlx5_core_dev *dev,
|
|||||||
|
|
||||||
int mlx5_core_create_dct(struct mlx5_core_dev *dev,
|
int mlx5_core_create_dct(struct mlx5_core_dev *dev,
|
||||||
struct mlx5_core_dct *qp,
|
struct mlx5_core_dct *qp,
|
||||||
u32 *in, int inlen);
|
u32 *in, int inlen,
|
||||||
|
u32 *out, int outlen);
|
||||||
int mlx5_core_create_qp(struct mlx5_core_dev *dev,
|
int mlx5_core_create_qp(struct mlx5_core_dev *dev,
|
||||||
struct mlx5_core_qp *qp,
|
struct mlx5_core_qp *qp,
|
||||||
u32 *in,
|
u32 *in,
|
||||||
|
Loading…
Reference in New Issue
Block a user