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:
@@ -4415,6 +4415,84 @@ int mlx5_ib_destroy_wq(struct ib_wq *wq)
|
||||
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,
|
||||
u32 wq_attr_mask, struct ib_udata *udata)
|
||||
{
|
||||
|
Reference in New Issue
Block a user