@@ -627,7 +627,8 @@ static void mlx5_ib_unlock_cqs(struct mlx5_ib_cq *send_cq,
627
627
struct mlx5_ib_cq * recv_cq );
628
628
629
629
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 )
631
632
{
632
633
int bfregs_per_sys_page ;
633
634
int index_of_sys_page ;
@@ -637,8 +638,16 @@ static int bfregn_to_uar_index(struct mlx5_ib_dev *dev,
637
638
MLX5_NON_FP_BFREGS_PER_UAR ;
638
639
index_of_sys_page = bfregn / bfregs_per_sys_page ;
639
640
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
+ }
641
649
650
+ offset = bfregn % bfregs_per_sys_page / MLX5_NON_FP_BFREGS_PER_UAR ;
642
651
return bfregi -> sys_pages [index_of_sys_page ] + offset ;
643
652
}
644
653
@@ -764,7 +773,7 @@ static int create_user_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd,
764
773
struct mlx5_ib_create_qp ucmd ;
765
774
struct mlx5_ib_ubuffer * ubuffer = & base -> ubuffer ;
766
775
int page_shift = 0 ;
767
- int uar_index ;
776
+ int uar_index = 0 ;
768
777
int npages ;
769
778
u32 offset = 0 ;
770
779
int bfregn ;
@@ -780,12 +789,20 @@ static int create_user_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd,
780
789
}
781
790
782
791
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
+ */
787
803
/* In CROSS_CHANNEL CQ and QP must use the same UAR */
788
804
bfregn = MLX5_CROSS_CHANNEL_BFREG ;
805
+ }
789
806
else {
790
807
bfregn = alloc_bfreg (dev , & context -> bfregi , MLX5_IB_LATENCY_CLASS_HIGH );
791
808
if (bfregn < 0 ) {
@@ -804,8 +821,10 @@ static int create_user_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd,
804
821
}
805
822
}
806
823
807
- uar_index = bfregn_to_uar_index (dev , & context -> bfregi , bfregn );
808
824
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);
809
828
810
829
qp -> rq .offset = 0 ;
811
830
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,
845
864
MLX5_SET (qpc , qpc , page_offset , offset );
846
865
847
866
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 ;
849
871
qp -> bfregn = bfregn ;
850
872
851
873
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,
874
896
ib_umem_release (ubuffer -> umem );
875
897
876
898
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 );
878
901
return err ;
879
902
}
880
903
@@ -887,7 +910,13 @@ static void destroy_qp_user(struct mlx5_ib_dev *dev, struct ib_pd *pd,
887
910
mlx5_ib_db_unmap_user (context , & qp -> db );
888
911
if (base -> ubuffer .umem )
889
912
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 );
891
920
}
892
921
893
922
static int create_kernel_qp (struct mlx5_ib_dev * dev ,
0 commit comments