IB/mlx5: Allow creation of QPs with zero-length work queues
The current code attmepts to call ib_umem_get() even if the length is zero, which causes a failure. Since the spec allows zero length work queues, change the code so we don't call ib_umem_get() in those cases. Signed-off-by: Eli Cohen <eli@mellanox.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
This commit is contained in:
@@ -523,12 +523,12 @@ static int create_user_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd,
|
|||||||
{
|
{
|
||||||
struct mlx5_ib_ucontext *context;
|
struct mlx5_ib_ucontext *context;
|
||||||
struct mlx5_ib_create_qp ucmd;
|
struct mlx5_ib_create_qp ucmd;
|
||||||
int page_shift;
|
int page_shift = 0;
|
||||||
int uar_index;
|
int uar_index;
|
||||||
int npages;
|
int npages;
|
||||||
u32 offset;
|
u32 offset = 0;
|
||||||
int uuarn;
|
int uuarn;
|
||||||
int ncont;
|
int ncont = 0;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = ib_copy_from_udata(&ucmd, udata, sizeof(ucmd));
|
err = ib_copy_from_udata(&ucmd, udata, sizeof(ucmd));
|
||||||
@@ -564,6 +564,7 @@ static int create_user_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd,
|
|||||||
if (err)
|
if (err)
|
||||||
goto err_uuar;
|
goto err_uuar;
|
||||||
|
|
||||||
|
if (ucmd.buf_addr && qp->buf_size) {
|
||||||
qp->umem = ib_umem_get(pd->uobject->context, ucmd.buf_addr,
|
qp->umem = ib_umem_get(pd->uobject->context, ucmd.buf_addr,
|
||||||
qp->buf_size, 0, 0);
|
qp->buf_size, 0, 0);
|
||||||
if (IS_ERR(qp->umem)) {
|
if (IS_ERR(qp->umem)) {
|
||||||
@@ -571,7 +572,11 @@ static int create_user_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd,
|
|||||||
err = PTR_ERR(qp->umem);
|
err = PTR_ERR(qp->umem);
|
||||||
goto err_uuar;
|
goto err_uuar;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
qp->umem = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (qp->umem) {
|
||||||
mlx5_ib_cont_pages(qp->umem, ucmd.buf_addr, &npages, &page_shift,
|
mlx5_ib_cont_pages(qp->umem, ucmd.buf_addr, &npages, &page_shift,
|
||||||
&ncont, NULL);
|
&ncont, NULL);
|
||||||
err = mlx5_ib_get_buf_offset(ucmd.buf_addr, page_shift, &offset);
|
err = mlx5_ib_get_buf_offset(ucmd.buf_addr, page_shift, &offset);
|
||||||
@@ -581,6 +586,7 @@ static int create_user_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd,
|
|||||||
}
|
}
|
||||||
mlx5_ib_dbg(dev, "addr 0x%llx, size %d, npages %d, page_shift %d, ncont %d, offset %d\n",
|
mlx5_ib_dbg(dev, "addr 0x%llx, size %d, npages %d, page_shift %d, ncont %d, offset %d\n",
|
||||||
ucmd.buf_addr, qp->buf_size, npages, page_shift, ncont, offset);
|
ucmd.buf_addr, qp->buf_size, npages, page_shift, ncont, offset);
|
||||||
|
}
|
||||||
|
|
||||||
*inlen = sizeof(**in) + sizeof(*(*in)->pas) * ncont;
|
*inlen = sizeof(**in) + sizeof(*(*in)->pas) * ncont;
|
||||||
*in = mlx5_vzalloc(*inlen);
|
*in = mlx5_vzalloc(*inlen);
|
||||||
@@ -588,6 +594,7 @@ static int create_user_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd,
|
|||||||
err = -ENOMEM;
|
err = -ENOMEM;
|
||||||
goto err_umem;
|
goto err_umem;
|
||||||
}
|
}
|
||||||
|
if (qp->umem)
|
||||||
mlx5_ib_populate_pas(dev, qp->umem, page_shift, (*in)->pas, 0);
|
mlx5_ib_populate_pas(dev, qp->umem, page_shift, (*in)->pas, 0);
|
||||||
(*in)->ctx.log_pg_sz_remote_qpn =
|
(*in)->ctx.log_pg_sz_remote_qpn =
|
||||||
cpu_to_be32((page_shift - MLX5_ADAPTER_PAGE_SHIFT) << 24);
|
cpu_to_be32((page_shift - MLX5_ADAPTER_PAGE_SHIFT) << 24);
|
||||||
@@ -619,6 +626,7 @@ err_free:
|
|||||||
mlx5_vfree(*in);
|
mlx5_vfree(*in);
|
||||||
|
|
||||||
err_umem:
|
err_umem:
|
||||||
|
if (qp->umem)
|
||||||
ib_umem_release(qp->umem);
|
ib_umem_release(qp->umem);
|
||||||
|
|
||||||
err_uuar:
|
err_uuar:
|
||||||
@@ -632,6 +640,7 @@ static void destroy_qp_user(struct ib_pd *pd, struct mlx5_ib_qp *qp)
|
|||||||
|
|
||||||
context = to_mucontext(pd->uobject->context);
|
context = to_mucontext(pd->uobject->context);
|
||||||
mlx5_ib_db_unmap_user(context, &qp->db);
|
mlx5_ib_db_unmap_user(context, &qp->db);
|
||||||
|
if (qp->umem)
|
||||||
ib_umem_release(qp->umem);
|
ib_umem_release(qp->umem);
|
||||||
free_uuar(&context->uuari, qp->uuarn);
|
free_uuar(&context->uuari, qp->uuarn);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user