Skip to content

Commit 1ee47ab

Browse files
yishaihjgunthorpe
authored andcommitted
IB/mlx5: Enable QP creation with a given blue flame index
This patch enables QP creation with a given BF index, this allows the user space driver to share same BF between few QPs or alternatively have a dedicated BF per QP. Signed-off-by: Yishai Hadas <[email protected]> Signed-off-by: Leon Romanovsky <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]>
1 parent 4ed131d commit 1ee47ab

File tree

3 files changed

+43
-12
lines changed

3 files changed

+43
-12
lines changed

drivers/infiniband/hw/mlx5/mlx5_ib.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ enum {
115115

116116
enum {
117117
MLX5_IB_INVALID_UAR_INDEX = BIT(31),
118+
MLX5_IB_INVALID_BFREG = BIT(31),
118119
};
119120

120121
struct mlx5_ib_vma_private_data {

drivers/infiniband/hw/mlx5/qp.c

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -627,7 +627,8 @@ static void mlx5_ib_unlock_cqs(struct mlx5_ib_cq *send_cq,
627627
struct mlx5_ib_cq *recv_cq);
628628

629629
static int bfregn_to_uar_index(struct mlx5_ib_dev *dev,
630-
struct mlx5_bfreg_info *bfregi, int bfregn)
630+
struct mlx5_bfreg_info *bfregi, int bfregn,
631+
bool dyn_bfreg)
631632
{
632633
int bfregs_per_sys_page;
633634
int index_of_sys_page;
@@ -637,8 +638,16 @@ static int bfregn_to_uar_index(struct mlx5_ib_dev *dev,
637638
MLX5_NON_FP_BFREGS_PER_UAR;
638639
index_of_sys_page = bfregn / bfregs_per_sys_page;
639640

640-
offset = bfregn % bfregs_per_sys_page / MLX5_NON_FP_BFREGS_PER_UAR;
641+
if (dyn_bfreg) {
642+
index_of_sys_page += bfregi->num_static_sys_pages;
643+
if (bfregn > bfregi->num_dyn_bfregs ||
644+
bfregi->sys_pages[index_of_sys_page] == MLX5_IB_INVALID_UAR_INDEX) {
645+
mlx5_ib_dbg(dev, "Invalid dynamic uar index\n");
646+
return -EINVAL;
647+
}
648+
}
641649

650+
offset = bfregn % bfregs_per_sys_page / MLX5_NON_FP_BFREGS_PER_UAR;
642651
return bfregi->sys_pages[index_of_sys_page] + offset;
643652
}
644653

@@ -764,7 +773,7 @@ static int create_user_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd,
764773
struct mlx5_ib_create_qp ucmd;
765774
struct mlx5_ib_ubuffer *ubuffer = &base->ubuffer;
766775
int page_shift = 0;
767-
int uar_index;
776+
int uar_index = 0;
768777
int npages;
769778
u32 offset = 0;
770779
int bfregn;
@@ -780,12 +789,20 @@ static int create_user_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd,
780789
}
781790

782791
context = to_mucontext(pd->uobject->context);
783-
/*
784-
* TBD: should come from the verbs when we have the API
785-
*/
786-
if (qp->flags & MLX5_IB_QP_CROSS_CHANNEL)
792+
if (ucmd.flags & MLX5_QP_FLAG_BFREG_INDEX) {
793+
uar_index = bfregn_to_uar_index(dev, &context->bfregi,
794+
ucmd.bfreg_index, true);
795+
if (uar_index < 0)
796+
return uar_index;
797+
798+
bfregn = MLX5_IB_INVALID_BFREG;
799+
} else if (qp->flags & MLX5_IB_QP_CROSS_CHANNEL) {
800+
/*
801+
* TBD: should come from the verbs when we have the API
802+
*/
787803
/* In CROSS_CHANNEL CQ and QP must use the same UAR */
788804
bfregn = MLX5_CROSS_CHANNEL_BFREG;
805+
}
789806
else {
790807
bfregn = alloc_bfreg(dev, &context->bfregi, MLX5_IB_LATENCY_CLASS_HIGH);
791808
if (bfregn < 0) {
@@ -804,8 +821,10 @@ static int create_user_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd,
804821
}
805822
}
806823

807-
uar_index = bfregn_to_uar_index(dev, &context->bfregi, bfregn);
808824
mlx5_ib_dbg(dev, "bfregn 0x%x, uar_index 0x%x\n", bfregn, uar_index);
825+
if (bfregn != MLX5_IB_INVALID_BFREG)
826+
uar_index = bfregn_to_uar_index(dev, &context->bfregi, bfregn,
827+
false);
809828

810829
qp->rq.offset = 0;
811830
qp->sq.wqe_shift = ilog2(MLX5_SEND_WQE_BB);
@@ -845,7 +864,10 @@ static int create_user_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd,
845864
MLX5_SET(qpc, qpc, page_offset, offset);
846865

847866
MLX5_SET(qpc, qpc, uar_page, uar_index);
848-
resp->bfreg_index = adjust_bfregn(dev, &context->bfregi, bfregn);
867+
if (bfregn != MLX5_IB_INVALID_BFREG)
868+
resp->bfreg_index = adjust_bfregn(dev, &context->bfregi, bfregn);
869+
else
870+
resp->bfreg_index = MLX5_IB_INVALID_BFREG;
849871
qp->bfregn = bfregn;
850872

851873
err = mlx5_ib_db_map_user(context, ucmd.db_addr, &qp->db);
@@ -874,7 +896,8 @@ static int create_user_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd,
874896
ib_umem_release(ubuffer->umem);
875897

876898
err_bfreg:
877-
mlx5_ib_free_bfreg(dev, &context->bfregi, bfregn);
899+
if (bfregn != MLX5_IB_INVALID_BFREG)
900+
mlx5_ib_free_bfreg(dev, &context->bfregi, bfregn);
878901
return err;
879902
}
880903

@@ -887,7 +910,13 @@ static void destroy_qp_user(struct mlx5_ib_dev *dev, struct ib_pd *pd,
887910
mlx5_ib_db_unmap_user(context, &qp->db);
888911
if (base->ubuffer.umem)
889912
ib_umem_release(base->ubuffer.umem);
890-
mlx5_ib_free_bfreg(dev, &context->bfregi, qp->bfregn);
913+
914+
/*
915+
* Free only the BFREGs which are handled by the kernel.
916+
* BFREGs of UARs allocated dynamically are handled by user.
917+
*/
918+
if (qp->bfregn != MLX5_IB_INVALID_BFREG)
919+
mlx5_ib_free_bfreg(dev, &context->bfregi, qp->bfregn);
891920
}
892921

893922
static int create_kernel_qp(struct mlx5_ib_dev *dev,

include/uapi/rdma/mlx5-abi.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ enum {
4141
MLX5_QP_FLAG_SIGNATURE = 1 << 0,
4242
MLX5_QP_FLAG_SCATTER_CQE = 1 << 1,
4343
MLX5_QP_FLAG_TUNNEL_OFFLOADS = 1 << 2,
44+
MLX5_QP_FLAG_BFREG_INDEX = 1 << 3,
4445
};
4546

4647
enum {
@@ -282,7 +283,7 @@ struct mlx5_ib_create_qp {
282283
__u32 rq_wqe_shift;
283284
__u32 flags;
284285
__u32 uidx;
285-
__u32 reserved0;
286+
__u32 bfreg_index;
286287
__u64 sq_buf_addr;
287288
};
288289

0 commit comments

Comments
 (0)