IB/mlx5: Add Receive Work Queue Indirection table operations
Some mlx5 based hardwares support a RQ table object. This RQ table points to a few RQ objects. We implement the receive work queue indirection table API (create and destroy) by using this hardware object. Signed-off-by: Yishai Hadas <yishaih@mellanox.com> Signed-off-by: Matan Barak <matanb@mellanox.com> Reviewed-by: Sagi Grimberg <sagi@grimberg.me> Signed-off-by: Doug Ledford <dledford@redhat.com>
This commit is contained in:
parent
de019a9404
commit
c5f9092936
@ -2453,12 +2453,16 @@ static void *mlx5_ib_add(struct mlx5_core_dev *mdev)
|
|||||||
dev->ib_dev.create_wq = mlx5_ib_create_wq;
|
dev->ib_dev.create_wq = mlx5_ib_create_wq;
|
||||||
dev->ib_dev.modify_wq = mlx5_ib_modify_wq;
|
dev->ib_dev.modify_wq = mlx5_ib_modify_wq;
|
||||||
dev->ib_dev.destroy_wq = mlx5_ib_destroy_wq;
|
dev->ib_dev.destroy_wq = mlx5_ib_destroy_wq;
|
||||||
|
dev->ib_dev.create_rwq_ind_table = mlx5_ib_create_rwq_ind_table;
|
||||||
|
dev->ib_dev.destroy_rwq_ind_table = mlx5_ib_destroy_rwq_ind_table;
|
||||||
dev->ib_dev.uverbs_ex_cmd_mask |=
|
dev->ib_dev.uverbs_ex_cmd_mask |=
|
||||||
(1ull << IB_USER_VERBS_EX_CMD_CREATE_FLOW) |
|
(1ull << IB_USER_VERBS_EX_CMD_CREATE_FLOW) |
|
||||||
(1ull << IB_USER_VERBS_EX_CMD_DESTROY_FLOW) |
|
(1ull << IB_USER_VERBS_EX_CMD_DESTROY_FLOW) |
|
||||||
(1ull << IB_USER_VERBS_EX_CMD_CREATE_WQ) |
|
(1ull << IB_USER_VERBS_EX_CMD_CREATE_WQ) |
|
||||||
(1ull << IB_USER_VERBS_EX_CMD_MODIFY_WQ) |
|
(1ull << IB_USER_VERBS_EX_CMD_MODIFY_WQ) |
|
||||||
(1ull << IB_USER_VERBS_EX_CMD_DESTROY_WQ);
|
(1ull << IB_USER_VERBS_EX_CMD_DESTROY_WQ) |
|
||||||
|
(1ull << IB_USER_VERBS_EX_CMD_CREATE_RWQ_IND_TBL) |
|
||||||
|
(1ull << IB_USER_VERBS_EX_CMD_DESTROY_RWQ_IND_TBL);
|
||||||
}
|
}
|
||||||
err = init_node_data(dev);
|
err = init_node_data(dev);
|
||||||
if (err)
|
if (err)
|
||||||
|
@ -247,6 +247,11 @@ enum {
|
|||||||
MLX5_WQ_KERNEL
|
MLX5_WQ_KERNEL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct mlx5_ib_rwq_ind_table {
|
||||||
|
struct ib_rwq_ind_table ib_rwq_ind_tbl;
|
||||||
|
u32 rqtn;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Connect-IB can trigger up to four concurrent pagefaults
|
* Connect-IB can trigger up to four concurrent pagefaults
|
||||||
* per-QP.
|
* per-QP.
|
||||||
@ -657,6 +662,11 @@ static inline struct mlx5_ib_rwq *to_mrwq(struct ib_wq *ibwq)
|
|||||||
return container_of(ibwq, struct mlx5_ib_rwq, ibwq);
|
return container_of(ibwq, struct mlx5_ib_rwq, ibwq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline struct mlx5_ib_rwq_ind_table *to_mrwq_ind_table(struct ib_rwq_ind_table *ib_rwq_ind_tbl)
|
||||||
|
{
|
||||||
|
return container_of(ib_rwq_ind_tbl, struct mlx5_ib_rwq_ind_table, ib_rwq_ind_tbl);
|
||||||
|
}
|
||||||
|
|
||||||
static inline struct mlx5_ib_srq *to_mibsrq(struct mlx5_core_srq *msrq)
|
static inline struct mlx5_ib_srq *to_mibsrq(struct mlx5_core_srq *msrq)
|
||||||
{
|
{
|
||||||
return container_of(msrq, struct mlx5_ib_srq, msrq);
|
return container_of(msrq, struct mlx5_ib_srq, msrq);
|
||||||
@ -797,6 +807,10 @@ struct ib_wq *mlx5_ib_create_wq(struct ib_pd *pd,
|
|||||||
int mlx5_ib_destroy_wq(struct ib_wq *wq);
|
int mlx5_ib_destroy_wq(struct ib_wq *wq);
|
||||||
int mlx5_ib_modify_wq(struct ib_wq *wq, struct ib_wq_attr *wq_attr,
|
int mlx5_ib_modify_wq(struct ib_wq *wq, struct ib_wq_attr *wq_attr,
|
||||||
u32 wq_attr_mask, struct ib_udata *udata);
|
u32 wq_attr_mask, struct ib_udata *udata);
|
||||||
|
struct ib_rwq_ind_table *mlx5_ib_create_rwq_ind_table(struct ib_device *device,
|
||||||
|
struct ib_rwq_ind_table_init_attr *init_attr,
|
||||||
|
struct ib_udata *udata);
|
||||||
|
int mlx5_ib_destroy_rwq_ind_table(struct ib_rwq_ind_table *wq_ind_table);
|
||||||
|
|
||||||
#ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING
|
#ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING
|
||||||
extern struct workqueue_struct *mlx5_ib_page_fault_wq;
|
extern struct workqueue_struct *mlx5_ib_page_fault_wq;
|
||||||
|
@ -4415,6 +4415,84 @@ int mlx5_ib_destroy_wq(struct ib_wq *wq)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ib_rwq_ind_table *mlx5_ib_create_rwq_ind_table(struct ib_device *device,
|
||||||
|
struct ib_rwq_ind_table_init_attr *init_attr,
|
||||||
|
struct ib_udata *udata)
|
||||||
|
{
|
||||||
|
struct mlx5_ib_dev *dev = to_mdev(device);
|
||||||
|
struct mlx5_ib_rwq_ind_table *rwq_ind_tbl;
|
||||||
|
int sz = 1 << init_attr->log_ind_tbl_size;
|
||||||
|
struct mlx5_ib_create_rwq_ind_tbl_resp resp = {};
|
||||||
|
size_t min_resp_len;
|
||||||
|
int inlen;
|
||||||
|
int err;
|
||||||
|
int i;
|
||||||
|
u32 *in;
|
||||||
|
void *rqtc;
|
||||||
|
|
||||||
|
if (udata->inlen > 0 &&
|
||||||
|
!ib_is_udata_cleared(udata, 0,
|
||||||
|
udata->inlen))
|
||||||
|
return ERR_PTR(-EOPNOTSUPP);
|
||||||
|
|
||||||
|
min_resp_len = offsetof(typeof(resp), reserved) + sizeof(resp.reserved);
|
||||||
|
if (udata->outlen && udata->outlen < min_resp_len)
|
||||||
|
return ERR_PTR(-EINVAL);
|
||||||
|
|
||||||
|
rwq_ind_tbl = kzalloc(sizeof(*rwq_ind_tbl), GFP_KERNEL);
|
||||||
|
if (!rwq_ind_tbl)
|
||||||
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
|
inlen = MLX5_ST_SZ_BYTES(create_rqt_in) + sizeof(u32) * sz;
|
||||||
|
in = mlx5_vzalloc(inlen);
|
||||||
|
if (!in) {
|
||||||
|
err = -ENOMEM;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
rqtc = MLX5_ADDR_OF(create_rqt_in, in, rqt_context);
|
||||||
|
|
||||||
|
MLX5_SET(rqtc, rqtc, rqt_actual_size, sz);
|
||||||
|
MLX5_SET(rqtc, rqtc, rqt_max_size, sz);
|
||||||
|
|
||||||
|
for (i = 0; i < sz; i++)
|
||||||
|
MLX5_SET(rqtc, rqtc, rq_num[i], init_attr->ind_tbl[i]->wq_num);
|
||||||
|
|
||||||
|
err = mlx5_core_create_rqt(dev->mdev, in, inlen, &rwq_ind_tbl->rqtn);
|
||||||
|
kvfree(in);
|
||||||
|
|
||||||
|
if (err)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
rwq_ind_tbl->ib_rwq_ind_tbl.ind_tbl_num = rwq_ind_tbl->rqtn;
|
||||||
|
if (udata->outlen) {
|
||||||
|
resp.response_length = offsetof(typeof(resp), response_length) +
|
||||||
|
sizeof(resp.response_length);
|
||||||
|
err = ib_copy_to_udata(udata, &resp, resp.response_length);
|
||||||
|
if (err)
|
||||||
|
goto err_copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &rwq_ind_tbl->ib_rwq_ind_tbl;
|
||||||
|
|
||||||
|
err_copy:
|
||||||
|
mlx5_core_destroy_rqt(dev->mdev, rwq_ind_tbl->rqtn);
|
||||||
|
err:
|
||||||
|
kfree(rwq_ind_tbl);
|
||||||
|
return ERR_PTR(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
int mlx5_ib_destroy_rwq_ind_table(struct ib_rwq_ind_table *ib_rwq_ind_tbl)
|
||||||
|
{
|
||||||
|
struct mlx5_ib_rwq_ind_table *rwq_ind_tbl = to_mrwq_ind_table(ib_rwq_ind_tbl);
|
||||||
|
struct mlx5_ib_dev *dev = to_mdev(ib_rwq_ind_tbl->device);
|
||||||
|
|
||||||
|
mlx5_core_destroy_rqt(dev->mdev, rwq_ind_tbl->rqtn);
|
||||||
|
|
||||||
|
kfree(rwq_ind_tbl);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int mlx5_ib_modify_wq(struct ib_wq *wq, struct ib_wq_attr *wq_attr,
|
int mlx5_ib_modify_wq(struct ib_wq *wq, struct ib_wq_attr *wq_attr,
|
||||||
u32 wq_attr_mask, struct ib_udata *udata)
|
u32 wq_attr_mask, struct ib_udata *udata)
|
||||||
{
|
{
|
||||||
|
@ -179,6 +179,11 @@ struct mlx5_ib_create_wq_resp {
|
|||||||
__u32 reserved;
|
__u32 reserved;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct mlx5_ib_create_rwq_ind_tbl_resp {
|
||||||
|
__u32 response_length;
|
||||||
|
__u32 reserved;
|
||||||
|
};
|
||||||
|
|
||||||
struct mlx5_ib_modify_wq {
|
struct mlx5_ib_modify_wq {
|
||||||
__u32 comp_mask;
|
__u32 comp_mask;
|
||||||
__u32 reserved;
|
__u32 reserved;
|
||||||
|
Loading…
Reference in New Issue
Block a user