net/mlx5: Move QP logic to mlx5_ib
The mlx5_core doesn't need any functionality coded in qp.c, so move that file to drivers/infiniband/ be under mlx5_ib responsibility. Reviewed-by: Saeed Mahameed <saeedm@mellanox.com> Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
Цей коміт міститься в:
@@ -13,6 +13,7 @@ mlx5_ib-y := ah.o \
|
||||
mem.o \
|
||||
mr.o \
|
||||
qp.o \
|
||||
qpc.o \
|
||||
restrack.o \
|
||||
srq.o \
|
||||
srq_cmd.o
|
||||
|
@@ -36,6 +36,7 @@
|
||||
#include <rdma/ib_cache.h>
|
||||
#include "mlx5_ib.h"
|
||||
#include "srq.h"
|
||||
#include "qp.h"
|
||||
|
||||
static void mlx5_ib_cq_comp(struct mlx5_core_cq *cq, struct mlx5_eqe *eqe)
|
||||
{
|
||||
@@ -484,7 +485,7 @@ repoll:
|
||||
* because CQs will be locked while QPs are removed
|
||||
* from the table.
|
||||
*/
|
||||
mqp = __mlx5_qp_lookup(dev->mdev, qpn);
|
||||
mqp = radix_tree_lookup(&dev->qp_table.tree, qpn);
|
||||
*cur_qp = to_mibqp(mqp);
|
||||
}
|
||||
|
||||
|
@@ -14,6 +14,7 @@
|
||||
#include <linux/mlx5/driver.h>
|
||||
#include <linux/mlx5/fs.h>
|
||||
#include "mlx5_ib.h"
|
||||
#include "qp.h"
|
||||
#include <linux/xarray.h>
|
||||
|
||||
#define UVERBS_MODULE_NAME mlx5_ib
|
||||
@@ -1356,7 +1357,7 @@ static int devx_obj_cleanup(struct ib_uobject *uobject,
|
||||
}
|
||||
|
||||
if (obj->flags & DEVX_OBJ_FLAGS_DCT)
|
||||
ret = mlx5_core_destroy_dct(obj->ib_dev->mdev, &obj->core_dct);
|
||||
ret = mlx5_core_destroy_dct(obj->ib_dev, &obj->core_dct);
|
||||
else if (obj->flags & DEVX_OBJ_FLAGS_CQ)
|
||||
ret = mlx5_core_destroy_cq(obj->ib_dev->mdev, &obj->core_cq);
|
||||
else
|
||||
@@ -1450,9 +1451,8 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OBJ_CREATE)(
|
||||
|
||||
if (opcode == MLX5_CMD_OP_CREATE_DCT) {
|
||||
obj->flags |= DEVX_OBJ_FLAGS_DCT;
|
||||
err = mlx5_core_create_dct(dev->mdev, &obj->core_dct,
|
||||
cmd_in, cmd_in_len,
|
||||
cmd_out, cmd_out_len);
|
||||
err = mlx5_core_create_dct(dev, &obj->core_dct, cmd_in,
|
||||
cmd_in_len, cmd_out, cmd_out_len);
|
||||
} else if (opcode == MLX5_CMD_OP_CREATE_CQ) {
|
||||
obj->flags |= DEVX_OBJ_FLAGS_CQ;
|
||||
obj->core_cq.comp = devx_cq_comp;
|
||||
@@ -1499,7 +1499,7 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OBJ_CREATE)(
|
||||
|
||||
obj_destroy:
|
||||
if (obj->flags & DEVX_OBJ_FLAGS_DCT)
|
||||
mlx5_core_destroy_dct(obj->ib_dev->mdev, &obj->core_dct);
|
||||
mlx5_core_destroy_dct(obj->ib_dev, &obj->core_dct);
|
||||
else if (obj->flags & DEVX_OBJ_FLAGS_CQ)
|
||||
mlx5_core_destroy_cq(obj->ib_dev->mdev, &obj->core_cq);
|
||||
else
|
||||
|
@@ -59,6 +59,7 @@
|
||||
#include "ib_rep.h"
|
||||
#include "cmd.h"
|
||||
#include "srq.h"
|
||||
#include "qp.h"
|
||||
#include <linux/mlx5/fs_helpers.h>
|
||||
#include <linux/mlx5/accel.h>
|
||||
#include <rdma/uverbs_std_types.h>
|
||||
@@ -4632,8 +4633,7 @@ static void delay_drop_handler(struct work_struct *work)
|
||||
atomic_inc(&delay_drop->events_cnt);
|
||||
|
||||
mutex_lock(&delay_drop->lock);
|
||||
err = mlx5_core_set_delay_drop(delay_drop->dev->mdev,
|
||||
delay_drop->timeout);
|
||||
err = mlx5_core_set_delay_drop(delay_drop->dev, delay_drop->timeout);
|
||||
if (err) {
|
||||
mlx5_ib_warn(delay_drop->dev, "Failed to set delay drop, timeout=%u\n",
|
||||
delay_drop->timeout);
|
||||
@@ -7193,6 +7193,9 @@ static const struct mlx5_ib_profile pf_profile = {
|
||||
STAGE_CREATE(MLX5_IB_STAGE_ROCE,
|
||||
mlx5_ib_stage_roce_init,
|
||||
mlx5_ib_stage_roce_cleanup),
|
||||
STAGE_CREATE(MLX5_IB_STAGE_QP,
|
||||
mlx5_init_qp_table,
|
||||
mlx5_cleanup_qp_table),
|
||||
STAGE_CREATE(MLX5_IB_STAGE_SRQ,
|
||||
mlx5_init_srq_table,
|
||||
mlx5_cleanup_srq_table),
|
||||
@@ -7250,6 +7253,9 @@ const struct mlx5_ib_profile raw_eth_profile = {
|
||||
STAGE_CREATE(MLX5_IB_STAGE_ROCE,
|
||||
mlx5_ib_stage_raw_eth_roce_init,
|
||||
mlx5_ib_stage_raw_eth_roce_cleanup),
|
||||
STAGE_CREATE(MLX5_IB_STAGE_QP,
|
||||
mlx5_init_qp_table,
|
||||
mlx5_cleanup_qp_table),
|
||||
STAGE_CREATE(MLX5_IB_STAGE_SRQ,
|
||||
mlx5_init_srq_table,
|
||||
mlx5_cleanup_srq_table),
|
||||
|
@@ -869,6 +869,7 @@ enum mlx5_ib_stages {
|
||||
MLX5_IB_STAGE_CAPS,
|
||||
MLX5_IB_STAGE_NON_DEFAULT_CB,
|
||||
MLX5_IB_STAGE_ROCE,
|
||||
MLX5_IB_STAGE_QP,
|
||||
MLX5_IB_STAGE_SRQ,
|
||||
MLX5_IB_STAGE_DEVICE_RESOURCES,
|
||||
MLX5_IB_STAGE_DEVICE_NOTIFIER,
|
||||
@@ -1064,6 +1065,7 @@ struct mlx5_ib_dev {
|
||||
struct mlx5_dm dm;
|
||||
u16 devx_whitelist_uid;
|
||||
struct mlx5_srq_table srq_table;
|
||||
struct mlx5_qp_table qp_table;
|
||||
struct mlx5_async_ctx async_ctx;
|
||||
struct mlx5_devx_event_table devx_event_table;
|
||||
struct mlx5_var_table var_table;
|
||||
|
@@ -36,6 +36,7 @@
|
||||
|
||||
#include "mlx5_ib.h"
|
||||
#include "cmd.h"
|
||||
#include "qp.h"
|
||||
|
||||
#include <linux/mlx5/eq.h>
|
||||
|
||||
@@ -1219,7 +1220,7 @@ static inline struct mlx5_core_rsc_common *odp_get_rsc(struct mlx5_ib_dev *dev,
|
||||
case MLX5_WQE_PF_TYPE_REQ_SEND_OR_WRITE:
|
||||
case MLX5_WQE_PF_TYPE_RESP:
|
||||
case MLX5_WQE_PF_TYPE_REQ_READ_OR_ATOMIC:
|
||||
common = mlx5_core_res_hold(dev->mdev, wq_num, MLX5_RES_QP);
|
||||
common = mlx5_core_res_hold(dev, wq_num, MLX5_RES_QP);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@@ -39,6 +39,7 @@
|
||||
#include "mlx5_ib.h"
|
||||
#include "ib_rep.h"
|
||||
#include "cmd.h"
|
||||
#include "qp.h"
|
||||
|
||||
/* not supported currently */
|
||||
static int wq_signature;
|
||||
@@ -1336,7 +1337,7 @@ static int create_raw_packet_qp_sq(struct mlx5_ib_dev *dev,
|
||||
pas = (__be64 *)MLX5_ADDR_OF(wq, wq, pas);
|
||||
mlx5_ib_populate_pas(dev, sq->ubuffer.umem, page_shift, pas, 0);
|
||||
|
||||
err = mlx5_core_create_sq_tracked(dev->mdev, in, inlen, &sq->base.mqp);
|
||||
err = mlx5_core_create_sq_tracked(dev, in, inlen, &sq->base.mqp);
|
||||
|
||||
kvfree(in);
|
||||
|
||||
@@ -1356,7 +1357,7 @@ static void destroy_raw_packet_qp_sq(struct mlx5_ib_dev *dev,
|
||||
struct mlx5_ib_sq *sq)
|
||||
{
|
||||
destroy_flow_rule_vport_sq(sq);
|
||||
mlx5_core_destroy_sq_tracked(dev->mdev, &sq->base.mqp);
|
||||
mlx5_core_destroy_sq_tracked(dev, &sq->base.mqp);
|
||||
ib_umem_release(sq->ubuffer.umem);
|
||||
}
|
||||
|
||||
@@ -1426,7 +1427,7 @@ static int create_raw_packet_qp_rq(struct mlx5_ib_dev *dev,
|
||||
qp_pas = (__be64 *)MLX5_ADDR_OF(create_qp_in, qpin, pas);
|
||||
memcpy(pas, qp_pas, rq_pas_size);
|
||||
|
||||
err = mlx5_core_create_rq_tracked(dev->mdev, in, inlen, &rq->base.mqp);
|
||||
err = mlx5_core_create_rq_tracked(dev, in, inlen, &rq->base.mqp);
|
||||
|
||||
kvfree(in);
|
||||
|
||||
@@ -1436,7 +1437,7 @@ static int create_raw_packet_qp_rq(struct mlx5_ib_dev *dev,
|
||||
static void destroy_raw_packet_qp_rq(struct mlx5_ib_dev *dev,
|
||||
struct mlx5_ib_rq *rq)
|
||||
{
|
||||
mlx5_core_destroy_rq_tracked(dev->mdev, &rq->base.mqp);
|
||||
mlx5_core_destroy_rq_tracked(dev, &rq->base.mqp);
|
||||
}
|
||||
|
||||
static bool tunnel_offload_supported(struct mlx5_core_dev *dev)
|
||||
@@ -2347,7 +2348,7 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd,
|
||||
err = create_raw_packet_qp(dev, qp, in, inlen, pd, udata,
|
||||
&resp);
|
||||
} else {
|
||||
err = mlx5_core_create_qp(dev->mdev, &base->mqp, in, inlen);
|
||||
err = mlx5_core_create_qp(dev, &base->mqp, in, inlen);
|
||||
}
|
||||
|
||||
if (err) {
|
||||
@@ -2513,8 +2514,7 @@ static void destroy_qp_common(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
|
||||
if (qp->state != IB_QPS_RESET) {
|
||||
if (qp->ibqp.qp_type != IB_QPT_RAW_PACKET &&
|
||||
!(qp->flags & MLX5_IB_QP_UNDERLAY)) {
|
||||
err = mlx5_core_qp_modify(dev->mdev,
|
||||
MLX5_CMD_OP_2RST_QP, 0,
|
||||
err = mlx5_core_qp_modify(dev, MLX5_CMD_OP_2RST_QP, 0,
|
||||
NULL, &base->mqp);
|
||||
} else {
|
||||
struct mlx5_modify_raw_qp_param raw_qp_param = {
|
||||
@@ -2555,7 +2555,7 @@ static void destroy_qp_common(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
|
||||
qp->flags & MLX5_IB_QP_UNDERLAY) {
|
||||
destroy_raw_packet_qp(dev, qp);
|
||||
} else {
|
||||
err = mlx5_core_destroy_qp(dev->mdev, &base->mqp);
|
||||
err = mlx5_core_destroy_qp(dev, &base->mqp);
|
||||
if (err)
|
||||
mlx5_ib_warn(dev, "failed to destroy QP 0x%x\n",
|
||||
base->mqp.qpn);
|
||||
@@ -2818,7 +2818,7 @@ static int mlx5_ib_destroy_dct(struct mlx5_ib_qp *mqp)
|
||||
if (mqp->state == IB_QPS_RTR) {
|
||||
int err;
|
||||
|
||||
err = mlx5_core_destroy_dct(dev->mdev, &mqp->dct.mdct);
|
||||
err = mlx5_core_destroy_dct(dev, &mqp->dct.mdct);
|
||||
if (err) {
|
||||
mlx5_ib_warn(dev, "failed to destroy DCT %d\n", err);
|
||||
return err;
|
||||
@@ -3462,10 +3462,9 @@ static int __mlx5_ib_qp_set_counter(struct ib_qp *qp,
|
||||
base = &mqp->trans_qp.base;
|
||||
context.qp_counter_set_usr_page &= cpu_to_be32(0xffffff);
|
||||
context.qp_counter_set_usr_page |= cpu_to_be32(set_id << 24);
|
||||
return mlx5_core_qp_modify(dev->mdev,
|
||||
MLX5_CMD_OP_RTS2RTS_QP,
|
||||
MLX5_QP_OPTPAR_COUNTER_SET_ID,
|
||||
&context, &base->mqp);
|
||||
return mlx5_core_qp_modify(dev, MLX5_CMD_OP_RTS2RTS_QP,
|
||||
MLX5_QP_OPTPAR_COUNTER_SET_ID, &context,
|
||||
&base->mqp);
|
||||
}
|
||||
|
||||
static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
|
||||
@@ -3752,8 +3751,7 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
|
||||
|
||||
err = modify_raw_packet_qp(dev, qp, &raw_qp_param, tx_affinity);
|
||||
} else {
|
||||
err = mlx5_core_qp_modify(dev->mdev, op, optpar, context,
|
||||
&base->mqp);
|
||||
err = mlx5_core_qp_modify(dev, op, optpar, context, &base->mqp);
|
||||
}
|
||||
|
||||
if (err)
|
||||
@@ -3927,7 +3925,7 @@ static int mlx5_ib_modify_dct(struct ib_qp *ibqp, struct ib_qp_attr *attr,
|
||||
MLX5_SET(dctc, dctc, my_addr_index, attr->ah_attr.grh.sgid_index);
|
||||
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, &qp->dct.mdct, qp->dct.in,
|
||||
MLX5_ST_SZ_BYTES(create_dct_in), out,
|
||||
sizeof(out));
|
||||
if (err)
|
||||
@@ -3935,7 +3933,7 @@ static int mlx5_ib_modify_dct(struct ib_qp *ibqp, struct ib_qp_attr *attr,
|
||||
resp.dctn = qp->dct.mdct.mqp.qpn;
|
||||
err = ib_copy_to_udata(udata, &resp, resp.response_length);
|
||||
if (err) {
|
||||
mlx5_core_destroy_dct(dev->mdev, &qp->dct.mdct);
|
||||
mlx5_core_destroy_dct(dev, &qp->dct.mdct);
|
||||
return err;
|
||||
}
|
||||
} else {
|
||||
@@ -5697,8 +5695,7 @@ static int query_qp_attr(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
|
||||
if (!outb)
|
||||
return -ENOMEM;
|
||||
|
||||
err = mlx5_core_qp_query(dev->mdev, &qp->trans_qp.base.mqp, outb,
|
||||
outlen);
|
||||
err = mlx5_core_qp_query(dev, &qp->trans_qp.base.mqp, outb, outlen);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
@@ -5776,7 +5773,7 @@ static int mlx5_ib_dct_query_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *mqp,
|
||||
if (!out)
|
||||
return -ENOMEM;
|
||||
|
||||
err = mlx5_core_dct_query(dev->mdev, dct, out, outlen);
|
||||
err = mlx5_core_dct_query(dev, dct, out, outlen);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
@@ -5962,7 +5959,7 @@ static int set_delay_drop(struct mlx5_ib_dev *dev)
|
||||
if (dev->delay_drop.activate)
|
||||
goto out;
|
||||
|
||||
err = mlx5_core_set_delay_drop(dev->mdev, dev->delay_drop.timeout);
|
||||
err = mlx5_core_set_delay_drop(dev, dev->delay_drop.timeout);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
@@ -6068,13 +6065,13 @@ static int create_rq(struct mlx5_ib_rwq *rwq, struct ib_pd *pd,
|
||||
}
|
||||
rq_pas0 = (__be64 *)MLX5_ADDR_OF(wq, wq, pas);
|
||||
mlx5_ib_populate_pas(dev, rwq->umem, rwq->page_shift, rq_pas0, 0);
|
||||
err = mlx5_core_create_rq_tracked(dev->mdev, in, inlen, &rwq->core_qp);
|
||||
err = mlx5_core_create_rq_tracked(dev, in, inlen, &rwq->core_qp);
|
||||
if (!err && init_attr->create_flags & IB_WQ_FLAGS_DELAY_DROP) {
|
||||
err = set_delay_drop(dev);
|
||||
if (err) {
|
||||
mlx5_ib_warn(dev, "Failed to enable delay drop err=%d\n",
|
||||
err);
|
||||
mlx5_core_destroy_rq_tracked(dev->mdev, &rwq->core_qp);
|
||||
mlx5_core_destroy_rq_tracked(dev, &rwq->core_qp);
|
||||
} else {
|
||||
rwq->create_flags |= MLX5_IB_WQ_FLAGS_DELAY_DROP;
|
||||
}
|
||||
@@ -6256,7 +6253,7 @@ struct ib_wq *mlx5_ib_create_wq(struct ib_pd *pd,
|
||||
return &rwq->ibwq;
|
||||
|
||||
err_copy:
|
||||
mlx5_core_destroy_rq_tracked(dev->mdev, &rwq->core_qp);
|
||||
mlx5_core_destroy_rq_tracked(dev, &rwq->core_qp);
|
||||
err_user_rq:
|
||||
destroy_user_rq(dev, pd, rwq, udata);
|
||||
err:
|
||||
@@ -6269,7 +6266,7 @@ void mlx5_ib_destroy_wq(struct ib_wq *wq, struct ib_udata *udata)
|
||||
struct mlx5_ib_dev *dev = to_mdev(wq->device);
|
||||
struct mlx5_ib_rwq *rwq = to_mrwq(wq);
|
||||
|
||||
mlx5_core_destroy_rq_tracked(dev->mdev, &rwq->core_qp);
|
||||
mlx5_core_destroy_rq_tracked(dev, &rwq->core_qp);
|
||||
destroy_user_rq(dev, wq->pd, rwq, udata);
|
||||
kfree(rwq);
|
||||
}
|
||||
|
46
drivers/infiniband/hw/mlx5/qp.h
Звичайний файл
46
drivers/infiniband/hw/mlx5/qp.h
Звичайний файл
@@ -0,0 +1,46 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
|
||||
/*
|
||||
* Copyright (c) 2013-2020, Mellanox Technologies inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MLX5_IB_QP_H
|
||||
#define _MLX5_IB_QP_H
|
||||
|
||||
#include "mlx5_ib.h"
|
||||
|
||||
int mlx5_init_qp_table(struct mlx5_ib_dev *dev);
|
||||
void mlx5_cleanup_qp_table(struct mlx5_ib_dev *dev);
|
||||
|
||||
int mlx5_core_create_dct(struct mlx5_ib_dev *dev, struct mlx5_core_dct *qp,
|
||||
u32 *in, int inlen, u32 *out, int outlen);
|
||||
int mlx5_core_create_qp(struct mlx5_ib_dev *dev, struct mlx5_core_qp *qp,
|
||||
u32 *in, int inlen);
|
||||
int mlx5_core_qp_modify(struct mlx5_ib_dev *dev, u16 opcode, u32 opt_param_mask,
|
||||
void *qpc, struct mlx5_core_qp *qp);
|
||||
int mlx5_core_destroy_qp(struct mlx5_ib_dev *dev, struct mlx5_core_qp *qp);
|
||||
int mlx5_core_destroy_dct(struct mlx5_ib_dev *dev, struct mlx5_core_dct *dct);
|
||||
int mlx5_core_qp_query(struct mlx5_ib_dev *dev, struct mlx5_core_qp *qp,
|
||||
u32 *out, int outlen);
|
||||
int mlx5_core_dct_query(struct mlx5_ib_dev *dev, struct mlx5_core_dct *dct,
|
||||
u32 *out, int outlen);
|
||||
|
||||
int mlx5_core_set_delay_drop(struct mlx5_ib_dev *dev, u32 timeout_usec);
|
||||
|
||||
void mlx5_core_destroy_rq_tracked(struct mlx5_ib_dev *dev,
|
||||
struct mlx5_core_qp *rq);
|
||||
int mlx5_core_create_sq_tracked(struct mlx5_ib_dev *dev, u32 *in, int inlen,
|
||||
struct mlx5_core_qp *sq);
|
||||
void mlx5_core_destroy_sq_tracked(struct mlx5_ib_dev *dev,
|
||||
struct mlx5_core_qp *sq);
|
||||
|
||||
int mlx5_core_create_rq_tracked(struct mlx5_ib_dev *dev, u32 *in, int inlen,
|
||||
struct mlx5_core_qp *rq);
|
||||
|
||||
struct mlx5_core_rsc_common *mlx5_core_res_hold(struct mlx5_ib_dev *dev,
|
||||
int res_num,
|
||||
enum mlx5_res_type res_type);
|
||||
void mlx5_core_res_put(struct mlx5_core_rsc_common *res);
|
||||
|
||||
int mlx5_core_xrcd_alloc(struct mlx5_ib_dev *dev, u32 *xrcdn);
|
||||
int mlx5_core_xrcd_dealloc(struct mlx5_ib_dev *dev, u32 xrcdn);
|
||||
#endif /* _MLX5_IB_QP_H */
|
605
drivers/infiniband/hw/mlx5/qpc.c
Звичайний файл
605
drivers/infiniband/hw/mlx5/qpc.c
Звичайний файл
@@ -0,0 +1,605 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
|
||||
/*
|
||||
* Copyright (c) 2013-2020, Mellanox Technologies inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/gfp.h>
|
||||
#include <linux/mlx5/qp.h>
|
||||
#include <linux/mlx5/driver.h>
|
||||
#include "mlx5_ib.h"
|
||||
#include "qp.h"
|
||||
|
||||
static int mlx5_core_drain_dct(struct mlx5_ib_dev *dev,
|
||||
struct mlx5_core_dct *dct);
|
||||
|
||||
static struct mlx5_core_rsc_common *
|
||||
mlx5_get_rsc(struct mlx5_qp_table *table, u32 rsn)
|
||||
{
|
||||
struct mlx5_core_rsc_common *common;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&table->lock, flags);
|
||||
|
||||
common = radix_tree_lookup(&table->tree, rsn);
|
||||
if (common)
|
||||
refcount_inc(&common->refcount);
|
||||
|
||||
spin_unlock_irqrestore(&table->lock, flags);
|
||||
|
||||
return common;
|
||||
}
|
||||
|
||||
void mlx5_core_put_rsc(struct mlx5_core_rsc_common *common)
|
||||
{
|
||||
if (refcount_dec_and_test(&common->refcount))
|
||||
complete(&common->free);
|
||||
}
|
||||
|
||||
static u64 qp_allowed_event_types(void)
|
||||
{
|
||||
u64 mask;
|
||||
|
||||
mask = BIT(MLX5_EVENT_TYPE_PATH_MIG) |
|
||||
BIT(MLX5_EVENT_TYPE_COMM_EST) |
|
||||
BIT(MLX5_EVENT_TYPE_SQ_DRAINED) |
|
||||
BIT(MLX5_EVENT_TYPE_SRQ_LAST_WQE) |
|
||||
BIT(MLX5_EVENT_TYPE_WQ_CATAS_ERROR) |
|
||||
BIT(MLX5_EVENT_TYPE_PATH_MIG_FAILED) |
|
||||
BIT(MLX5_EVENT_TYPE_WQ_INVAL_REQ_ERROR) |
|
||||
BIT(MLX5_EVENT_TYPE_WQ_ACCESS_ERROR);
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
static u64 rq_allowed_event_types(void)
|
||||
{
|
||||
u64 mask;
|
||||
|
||||
mask = BIT(MLX5_EVENT_TYPE_SRQ_LAST_WQE) |
|
||||
BIT(MLX5_EVENT_TYPE_WQ_CATAS_ERROR);
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
static u64 sq_allowed_event_types(void)
|
||||
{
|
||||
return BIT(MLX5_EVENT_TYPE_WQ_CATAS_ERROR);
|
||||
}
|
||||
|
||||
static u64 dct_allowed_event_types(void)
|
||||
{
|
||||
return BIT(MLX5_EVENT_TYPE_DCT_DRAINED);
|
||||
}
|
||||
|
||||
static bool is_event_type_allowed(int rsc_type, int event_type)
|
||||
{
|
||||
switch (rsc_type) {
|
||||
case MLX5_EVENT_QUEUE_TYPE_QP:
|
||||
return BIT(event_type) & qp_allowed_event_types();
|
||||
case MLX5_EVENT_QUEUE_TYPE_RQ:
|
||||
return BIT(event_type) & rq_allowed_event_types();
|
||||
case MLX5_EVENT_QUEUE_TYPE_SQ:
|
||||
return BIT(event_type) & sq_allowed_event_types();
|
||||
case MLX5_EVENT_QUEUE_TYPE_DCT:
|
||||
return BIT(event_type) & dct_allowed_event_types();
|
||||
default:
|
||||
WARN(1, "Event arrived for unknown resource type");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static int rsc_event_notifier(struct notifier_block *nb,
|
||||
unsigned long type, void *data)
|
||||
{
|
||||
struct mlx5_core_rsc_common *common;
|
||||
struct mlx5_qp_table *table;
|
||||
struct mlx5_core_dct *dct;
|
||||
u8 event_type = (u8)type;
|
||||
struct mlx5_core_qp *qp;
|
||||
struct mlx5_eqe *eqe;
|
||||
u32 rsn;
|
||||
|
||||
switch (event_type) {
|
||||
case MLX5_EVENT_TYPE_DCT_DRAINED:
|
||||
eqe = data;
|
||||
rsn = be32_to_cpu(eqe->data.dct.dctn) & 0xffffff;
|
||||
rsn |= (MLX5_RES_DCT << MLX5_USER_INDEX_LEN);
|
||||
break;
|
||||
case MLX5_EVENT_TYPE_PATH_MIG:
|
||||
case MLX5_EVENT_TYPE_COMM_EST:
|
||||
case MLX5_EVENT_TYPE_SQ_DRAINED:
|
||||
case MLX5_EVENT_TYPE_SRQ_LAST_WQE:
|
||||
case MLX5_EVENT_TYPE_WQ_CATAS_ERROR:
|
||||
case MLX5_EVENT_TYPE_PATH_MIG_FAILED:
|
||||
case MLX5_EVENT_TYPE_WQ_INVAL_REQ_ERROR:
|
||||
case MLX5_EVENT_TYPE_WQ_ACCESS_ERROR:
|
||||
eqe = data;
|
||||
rsn = be32_to_cpu(eqe->data.qp_srq.qp_srq_n) & 0xffffff;
|
||||
rsn |= (eqe->data.qp_srq.type << MLX5_USER_INDEX_LEN);
|
||||
break;
|
||||
default:
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
table = container_of(nb, struct mlx5_qp_table, nb);
|
||||
common = mlx5_get_rsc(table, rsn);
|
||||
if (!common)
|
||||
return NOTIFY_OK;
|
||||
|
||||
if (!is_event_type_allowed((rsn >> MLX5_USER_INDEX_LEN), event_type))
|
||||
goto out;
|
||||
|
||||
switch (common->res) {
|
||||
case MLX5_RES_QP:
|
||||
case MLX5_RES_RQ:
|
||||
case MLX5_RES_SQ:
|
||||
qp = (struct mlx5_core_qp *)common;
|
||||
qp->event(qp, event_type);
|
||||
break;
|
||||
case MLX5_RES_DCT:
|
||||
dct = (struct mlx5_core_dct *)common;
|
||||
if (event_type == MLX5_EVENT_TYPE_DCT_DRAINED)
|
||||
complete(&dct->drained);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
out:
|
||||
mlx5_core_put_rsc(common);
|
||||
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
static int create_resource_common(struct mlx5_ib_dev *dev,
|
||||
struct mlx5_core_qp *qp, int rsc_type)
|
||||
{
|
||||
struct mlx5_qp_table *table = &dev->qp_table;
|
||||
int err;
|
||||
|
||||
qp->common.res = rsc_type;
|
||||
spin_lock_irq(&table->lock);
|
||||
err = radix_tree_insert(&table->tree,
|
||||
qp->qpn | (rsc_type << MLX5_USER_INDEX_LEN),
|
||||
qp);
|
||||
spin_unlock_irq(&table->lock);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
refcount_set(&qp->common.refcount, 1);
|
||||
init_completion(&qp->common.free);
|
||||
qp->pid = current->pid;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void destroy_resource_common(struct mlx5_ib_dev *dev,
|
||||
struct mlx5_core_qp *qp)
|
||||
{
|
||||
struct mlx5_qp_table *table = &dev->qp_table;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&table->lock, flags);
|
||||
radix_tree_delete(&table->tree,
|
||||
qp->qpn | (qp->common.res << MLX5_USER_INDEX_LEN));
|
||||
spin_unlock_irqrestore(&table->lock, flags);
|
||||
mlx5_core_put_rsc((struct mlx5_core_rsc_common *)qp);
|
||||
wait_for_completion(&qp->common.free);
|
||||
}
|
||||
|
||||
static int _mlx5_core_destroy_dct(struct mlx5_ib_dev *dev,
|
||||
struct mlx5_core_dct *dct, bool need_cleanup)
|
||||
{
|
||||
u32 in[MLX5_ST_SZ_DW(destroy_dct_in)] = {};
|
||||
struct mlx5_core_qp *qp = &dct->mqp;
|
||||
int err;
|
||||
|
||||
err = mlx5_core_drain_dct(dev, dct);
|
||||
if (err) {
|
||||
if (dev->mdev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR)
|
||||
goto destroy;
|
||||
|
||||
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_in(dev->mdev, destroy_dct, in);
|
||||
return err;
|
||||
}
|
||||
|
||||
int mlx5_core_create_dct(struct mlx5_ib_dev *dev, struct mlx5_core_dct *dct,
|
||||
u32 *in, int inlen, u32 *out, int outlen)
|
||||
{
|
||||
struct mlx5_core_qp *qp = &dct->mqp;
|
||||
int err;
|
||||
|
||||
init_completion(&dct->drained);
|
||||
MLX5_SET(create_dct_in, in, opcode, MLX5_CMD_OP_CREATE_DCT);
|
||||
|
||||
err = mlx5_cmd_exec(dev->mdev, in, inlen, out, outlen);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
qp->qpn = MLX5_GET(create_dct_out, out, dctn);
|
||||
qp->uid = MLX5_GET(create_dct_in, in, uid);
|
||||
err = create_resource_common(dev, qp, MLX5_RES_DCT);
|
||||
if (err)
|
||||
goto err_cmd;
|
||||
|
||||
return 0;
|
||||
err_cmd:
|
||||
_mlx5_core_destroy_dct(dev, dct, false);
|
||||
return err;
|
||||
}
|
||||
|
||||
int mlx5_core_create_qp(struct mlx5_ib_dev *dev, struct mlx5_core_qp *qp,
|
||||
u32 *in, int inlen)
|
||||
{
|
||||
u32 out[MLX5_ST_SZ_DW(create_qp_out)] = {};
|
||||
u32 din[MLX5_ST_SZ_DW(destroy_qp_in)] = {};
|
||||
int err;
|
||||
|
||||
MLX5_SET(create_qp_in, in, opcode, MLX5_CMD_OP_CREATE_QP);
|
||||
|
||||
err = mlx5_cmd_exec(dev->mdev, in, inlen, out, sizeof(out));
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
qp->uid = MLX5_GET(create_qp_in, in, uid);
|
||||
qp->qpn = MLX5_GET(create_qp_out, out, qpn);
|
||||
|
||||
err = create_resource_common(dev, qp, MLX5_RES_QP);
|
||||
if (err)
|
||||
goto err_cmd;
|
||||
|
||||
mlx5_debug_qp_add(dev->mdev, qp);
|
||||
|
||||
return 0;
|
||||
|
||||
err_cmd:
|
||||
MLX5_SET(destroy_qp_in, din, opcode, MLX5_CMD_OP_DESTROY_QP);
|
||||
MLX5_SET(destroy_qp_in, din, qpn, qp->qpn);
|
||||
MLX5_SET(destroy_qp_in, din, uid, qp->uid);
|
||||
mlx5_cmd_exec_in(dev->mdev, destroy_qp, din);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int mlx5_core_drain_dct(struct mlx5_ib_dev *dev,
|
||||
struct mlx5_core_dct *dct)
|
||||
{
|
||||
u32 in[MLX5_ST_SZ_DW(drain_dct_in)] = {};
|
||||
struct mlx5_core_qp *qp = &dct->mqp;
|
||||
|
||||
MLX5_SET(drain_dct_in, in, opcode, MLX5_CMD_OP_DRAIN_DCT);
|
||||
MLX5_SET(drain_dct_in, in, dctn, qp->qpn);
|
||||
MLX5_SET(drain_dct_in, in, uid, qp->uid);
|
||||
return mlx5_cmd_exec_in(dev->mdev, drain_dct, in);
|
||||
}
|
||||
|
||||
int mlx5_core_destroy_dct(struct mlx5_ib_dev *dev,
|
||||
struct mlx5_core_dct *dct)
|
||||
{
|
||||
return _mlx5_core_destroy_dct(dev, dct, true);
|
||||
}
|
||||
|
||||
int mlx5_core_destroy_qp(struct mlx5_ib_dev *dev, struct mlx5_core_qp *qp)
|
||||
{
|
||||
u32 in[MLX5_ST_SZ_DW(destroy_qp_in)] = {};
|
||||
|
||||
mlx5_debug_qp_remove(dev->mdev, qp);
|
||||
|
||||
destroy_resource_common(dev, qp);
|
||||
|
||||
MLX5_SET(destroy_qp_in, in, opcode, MLX5_CMD_OP_DESTROY_QP);
|
||||
MLX5_SET(destroy_qp_in, in, qpn, qp->qpn);
|
||||
MLX5_SET(destroy_qp_in, in, uid, qp->uid);
|
||||
mlx5_cmd_exec_in(dev->mdev, destroy_qp, in);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mlx5_core_set_delay_drop(struct mlx5_ib_dev *dev,
|
||||
u32 timeout_usec)
|
||||
{
|
||||
u32 in[MLX5_ST_SZ_DW(set_delay_drop_params_in)] = {};
|
||||
|
||||
MLX5_SET(set_delay_drop_params_in, in, opcode,
|
||||
MLX5_CMD_OP_SET_DELAY_DROP_PARAMS);
|
||||
MLX5_SET(set_delay_drop_params_in, in, delay_drop_timeout,
|
||||
timeout_usec / 100);
|
||||
return mlx5_cmd_exec_in(dev->mdev, set_delay_drop_params, in);
|
||||
}
|
||||
|
||||
struct mbox_info {
|
||||
u32 *in;
|
||||
u32 *out;
|
||||
int inlen;
|
||||
int outlen;
|
||||
};
|
||||
|
||||
static int mbox_alloc(struct mbox_info *mbox, int inlen, int outlen)
|
||||
{
|
||||
mbox->inlen = inlen;
|
||||
mbox->outlen = outlen;
|
||||
mbox->in = kzalloc(mbox->inlen, GFP_KERNEL);
|
||||
mbox->out = kzalloc(mbox->outlen, GFP_KERNEL);
|
||||
if (!mbox->in || !mbox->out) {
|
||||
kfree(mbox->in);
|
||||
kfree(mbox->out);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mbox_free(struct mbox_info *mbox)
|
||||
{
|
||||
kfree(mbox->in);
|
||||
kfree(mbox->out);
|
||||
}
|
||||
|
||||
static int modify_qp_mbox_alloc(struct mlx5_core_dev *dev, u16 opcode, int qpn,
|
||||
u32 opt_param_mask, void *qpc,
|
||||
struct mbox_info *mbox, u16 uid)
|
||||
{
|
||||
mbox->out = NULL;
|
||||
mbox->in = NULL;
|
||||
|
||||
#define MBOX_ALLOC(mbox, typ) \
|
||||
mbox_alloc(mbox, MLX5_ST_SZ_BYTES(typ##_in), MLX5_ST_SZ_BYTES(typ##_out))
|
||||
|
||||
#define MOD_QP_IN_SET(typ, in, _opcode, _qpn, _uid) \
|
||||
do { \
|
||||
MLX5_SET(typ##_in, in, opcode, _opcode); \
|
||||
MLX5_SET(typ##_in, in, qpn, _qpn); \
|
||||
MLX5_SET(typ##_in, in, uid, _uid); \
|
||||
} while (0)
|
||||
|
||||
#define MOD_QP_IN_SET_QPC(typ, in, _opcode, _qpn, _opt_p, _qpc, _uid) \
|
||||
do { \
|
||||
MOD_QP_IN_SET(typ, in, _opcode, _qpn, _uid); \
|
||||
MLX5_SET(typ##_in, in, opt_param_mask, _opt_p); \
|
||||
memcpy(MLX5_ADDR_OF(typ##_in, in, qpc), _qpc, \
|
||||
MLX5_ST_SZ_BYTES(qpc)); \
|
||||
} while (0)
|
||||
|
||||
switch (opcode) {
|
||||
/* 2RST & 2ERR */
|
||||
case MLX5_CMD_OP_2RST_QP:
|
||||
if (MBOX_ALLOC(mbox, qp_2rst))
|
||||
return -ENOMEM;
|
||||
MOD_QP_IN_SET(qp_2rst, mbox->in, opcode, qpn, uid);
|
||||
break;
|
||||
case MLX5_CMD_OP_2ERR_QP:
|
||||
if (MBOX_ALLOC(mbox, qp_2err))
|
||||
return -ENOMEM;
|
||||
MOD_QP_IN_SET(qp_2err, mbox->in, opcode, qpn, uid);
|
||||
break;
|
||||
|
||||
/* MODIFY with QPC */
|
||||
case MLX5_CMD_OP_RST2INIT_QP:
|
||||
if (MBOX_ALLOC(mbox, rst2init_qp))
|
||||
return -ENOMEM;
|
||||
MOD_QP_IN_SET_QPC(rst2init_qp, mbox->in, opcode, qpn,
|
||||
opt_param_mask, qpc, uid);
|
||||
break;
|
||||
case MLX5_CMD_OP_INIT2RTR_QP:
|
||||
if (MBOX_ALLOC(mbox, init2rtr_qp))
|
||||
return -ENOMEM;
|
||||
MOD_QP_IN_SET_QPC(init2rtr_qp, mbox->in, opcode, qpn,
|
||||
opt_param_mask, qpc, uid);
|
||||
break;
|
||||
case MLX5_CMD_OP_RTR2RTS_QP:
|
||||
if (MBOX_ALLOC(mbox, rtr2rts_qp))
|
||||
return -ENOMEM;
|
||||
MOD_QP_IN_SET_QPC(rtr2rts_qp, mbox->in, opcode, qpn,
|
||||
opt_param_mask, qpc, uid);
|
||||
break;
|
||||
case MLX5_CMD_OP_RTS2RTS_QP:
|
||||
if (MBOX_ALLOC(mbox, rts2rts_qp))
|
||||
return -ENOMEM;
|
||||
MOD_QP_IN_SET_QPC(rts2rts_qp, mbox->in, opcode, qpn,
|
||||
opt_param_mask, qpc, uid);
|
||||
break;
|
||||
case MLX5_CMD_OP_SQERR2RTS_QP:
|
||||
if (MBOX_ALLOC(mbox, sqerr2rts_qp))
|
||||
return -ENOMEM;
|
||||
MOD_QP_IN_SET_QPC(sqerr2rts_qp, mbox->in, opcode, qpn,
|
||||
opt_param_mask, qpc, uid);
|
||||
break;
|
||||
case MLX5_CMD_OP_INIT2INIT_QP:
|
||||
if (MBOX_ALLOC(mbox, init2init_qp))
|
||||
return -ENOMEM;
|
||||
MOD_QP_IN_SET_QPC(init2init_qp, mbox->in, opcode, qpn,
|
||||
opt_param_mask, qpc, uid);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mlx5_core_qp_modify(struct mlx5_ib_dev *dev, u16 opcode, u32 opt_param_mask,
|
||||
void *qpc, struct mlx5_core_qp *qp)
|
||||
{
|
||||
struct mbox_info mbox;
|
||||
int err;
|
||||
|
||||
err = modify_qp_mbox_alloc(dev->mdev, opcode, qp->qpn,
|
||||
opt_param_mask, qpc, &mbox, qp->uid);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = mlx5_cmd_exec(dev->mdev, mbox.in, mbox.inlen, mbox.out,
|
||||
mbox.outlen);
|
||||
mbox_free(&mbox);
|
||||
return err;
|
||||
}
|
||||
|
||||
int mlx5_init_qp_table(struct mlx5_ib_dev *dev)
|
||||
{
|
||||
struct mlx5_qp_table *table = &dev->qp_table;
|
||||
|
||||
spin_lock_init(&table->lock);
|
||||
INIT_RADIX_TREE(&table->tree, GFP_ATOMIC);
|
||||
mlx5_qp_debugfs_init(dev->mdev);
|
||||
|
||||
table->nb.notifier_call = rsc_event_notifier;
|
||||
mlx5_notifier_register(dev->mdev, &table->nb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mlx5_cleanup_qp_table(struct mlx5_ib_dev *dev)
|
||||
{
|
||||
struct mlx5_qp_table *table = &dev->qp_table;
|
||||
|
||||
mlx5_notifier_unregister(dev->mdev, &table->nb);
|
||||
mlx5_qp_debugfs_cleanup(dev->mdev);
|
||||
}
|
||||
|
||||
int mlx5_core_qp_query(struct mlx5_ib_dev *dev, struct mlx5_core_qp *qp,
|
||||
u32 *out, int outlen)
|
||||
{
|
||||
u32 in[MLX5_ST_SZ_DW(query_qp_in)] = {};
|
||||
|
||||
MLX5_SET(query_qp_in, in, opcode, MLX5_CMD_OP_QUERY_QP);
|
||||
MLX5_SET(query_qp_in, in, qpn, qp->qpn);
|
||||
return mlx5_cmd_exec(dev->mdev, in, sizeof(in), out, outlen);
|
||||
}
|
||||
|
||||
int mlx5_core_dct_query(struct mlx5_ib_dev *dev, struct mlx5_core_dct *dct,
|
||||
u32 *out, int outlen)
|
||||
{
|
||||
u32 in[MLX5_ST_SZ_DW(query_dct_in)] = {};
|
||||
struct mlx5_core_qp *qp = &dct->mqp;
|
||||
|
||||
MLX5_SET(query_dct_in, in, opcode, MLX5_CMD_OP_QUERY_DCT);
|
||||
MLX5_SET(query_dct_in, in, dctn, qp->qpn);
|
||||
|
||||
return mlx5_cmd_exec(dev->mdev, (void *)&in, sizeof(in), (void *)out,
|
||||
outlen);
|
||||
}
|
||||
|
||||
int mlx5_core_xrcd_alloc(struct mlx5_ib_dev *dev, u32 *xrcdn)
|
||||
{
|
||||
u32 out[MLX5_ST_SZ_DW(alloc_xrcd_out)] = {};
|
||||
u32 in[MLX5_ST_SZ_DW(alloc_xrcd_in)] = {};
|
||||
int err;
|
||||
|
||||
MLX5_SET(alloc_xrcd_in, in, opcode, MLX5_CMD_OP_ALLOC_XRCD);
|
||||
err = mlx5_cmd_exec_inout(dev->mdev, alloc_xrcd, in, out);
|
||||
if (!err)
|
||||
*xrcdn = MLX5_GET(alloc_xrcd_out, out, xrcd);
|
||||
return err;
|
||||
}
|
||||
|
||||
int mlx5_core_xrcd_dealloc(struct mlx5_ib_dev *dev, u32 xrcdn)
|
||||
{
|
||||
u32 in[MLX5_ST_SZ_DW(dealloc_xrcd_in)] = {};
|
||||
|
||||
MLX5_SET(dealloc_xrcd_in, in, opcode, MLX5_CMD_OP_DEALLOC_XRCD);
|
||||
MLX5_SET(dealloc_xrcd_in, in, xrcd, xrcdn);
|
||||
return mlx5_cmd_exec_in(dev->mdev, dealloc_xrcd, in);
|
||||
}
|
||||
|
||||
static void destroy_rq_tracked(struct mlx5_ib_dev *dev, u32 rqn, u16 uid)
|
||||
{
|
||||
u32 in[MLX5_ST_SZ_DW(destroy_rq_in)] = {};
|
||||
|
||||
MLX5_SET(destroy_rq_in, in, opcode, MLX5_CMD_OP_DESTROY_RQ);
|
||||
MLX5_SET(destroy_rq_in, in, rqn, rqn);
|
||||
MLX5_SET(destroy_rq_in, in, uid, uid);
|
||||
mlx5_cmd_exec_in(dev->mdev, destroy_rq, in);
|
||||
}
|
||||
|
||||
int mlx5_core_create_rq_tracked(struct mlx5_ib_dev *dev, u32 *in, int inlen,
|
||||
struct mlx5_core_qp *rq)
|
||||
{
|
||||
int err;
|
||||
u32 rqn;
|
||||
|
||||
err = mlx5_core_create_rq(dev->mdev, in, inlen, &rqn);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
rq->uid = MLX5_GET(create_rq_in, in, uid);
|
||||
rq->qpn = rqn;
|
||||
err = create_resource_common(dev, rq, MLX5_RES_RQ);
|
||||
if (err)
|
||||
goto err_destroy_rq;
|
||||
|
||||
return 0;
|
||||
|
||||
err_destroy_rq:
|
||||
destroy_rq_tracked(dev, rq->qpn, rq->uid);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
void mlx5_core_destroy_rq_tracked(struct mlx5_ib_dev *dev,
|
||||
struct mlx5_core_qp *rq)
|
||||
{
|
||||
destroy_resource_common(dev, rq);
|
||||
destroy_rq_tracked(dev, rq->qpn, rq->uid);
|
||||
}
|
||||
|
||||
static void destroy_sq_tracked(struct mlx5_ib_dev *dev, u32 sqn, u16 uid)
|
||||
{
|
||||
u32 in[MLX5_ST_SZ_DW(destroy_sq_in)] = {};
|
||||
|
||||
MLX5_SET(destroy_sq_in, in, opcode, MLX5_CMD_OP_DESTROY_SQ);
|
||||
MLX5_SET(destroy_sq_in, in, sqn, sqn);
|
||||
MLX5_SET(destroy_sq_in, in, uid, uid);
|
||||
mlx5_cmd_exec_in(dev->mdev, destroy_sq, in);
|
||||
}
|
||||
|
||||
int mlx5_core_create_sq_tracked(struct mlx5_ib_dev *dev, u32 *in, int inlen,
|
||||
struct mlx5_core_qp *sq)
|
||||
{
|
||||
u32 out[MLX5_ST_SZ_DW(create_sq_out)] = {};
|
||||
int err;
|
||||
|
||||
MLX5_SET(create_sq_in, in, opcode, MLX5_CMD_OP_CREATE_SQ);
|
||||
err = mlx5_cmd_exec(dev->mdev, in, inlen, out, sizeof(out));
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
sq->qpn = MLX5_GET(create_sq_out, out, sqn);
|
||||
sq->uid = MLX5_GET(create_sq_in, in, uid);
|
||||
err = create_resource_common(dev, sq, MLX5_RES_SQ);
|
||||
if (err)
|
||||
goto err_destroy_sq;
|
||||
|
||||
return 0;
|
||||
|
||||
err_destroy_sq:
|
||||
destroy_sq_tracked(dev, sq->qpn, sq->uid);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
void mlx5_core_destroy_sq_tracked(struct mlx5_ib_dev *dev,
|
||||
struct mlx5_core_qp *sq)
|
||||
{
|
||||
destroy_resource_common(dev, sq);
|
||||
destroy_sq_tracked(dev, sq->qpn, sq->uid);
|
||||
}
|
||||
|
||||
struct mlx5_core_rsc_common *mlx5_core_res_hold(struct mlx5_ib_dev *dev,
|
||||
int res_num,
|
||||
enum mlx5_res_type res_type)
|
||||
{
|
||||
u32 rsn = res_num | (res_type << MLX5_USER_INDEX_LEN);
|
||||
struct mlx5_qp_table *table = &dev->qp_table;
|
||||
|
||||
return mlx5_get_rsc(table, rsn);
|
||||
}
|
||||
|
||||
void mlx5_core_res_put(struct mlx5_core_rsc_common *res)
|
||||
{
|
||||
mlx5_core_put_rsc(res);
|
||||
}
|
@@ -7,6 +7,7 @@
|
||||
#include <linux/mlx5/driver.h>
|
||||
#include "mlx5_ib.h"
|
||||
#include "srq.h"
|
||||
#include "qp.h"
|
||||
|
||||
static int get_pas_size(struct mlx5_srq_attr *in)
|
||||
{
|
||||
|
Посилання в новій задачі
Заблокувати користувача