19
19
#include "erdma_cm.h"
20
20
#include "erdma_verbs.h"
21
21
22
+ static void assemble_qbuf_mtt_for_cmd (struct erdma_mem * mem , u32 * cfg ,
23
+ u64 * addr0 , u64 * addr1 )
24
+ {
25
+ struct erdma_mtt * mtt = mem -> mtt ;
26
+
27
+ if (mem -> mtt_nents > ERDMA_MAX_INLINE_MTT_ENTRIES ) {
28
+ * addr0 = mtt -> buf_dma ;
29
+ * cfg |= FIELD_PREP (ERDMA_CMD_CREATE_QP_MTT_TYPE_MASK ,
30
+ ERDMA_MR_INDIRECT_MTT );
31
+ } else {
32
+ * addr0 = mtt -> buf [0 ];
33
+ memcpy (addr1 , mtt -> buf + 1 , MTT_SIZE (mem -> mtt_nents - 1 ));
34
+ * cfg |= FIELD_PREP (ERDMA_CMD_CREATE_QP_MTT_TYPE_MASK ,
35
+ ERDMA_MR_INLINE_MTT );
36
+ }
37
+ }
38
+
22
39
static int create_qp_cmd (struct erdma_ucontext * uctx , struct erdma_qp * qp )
23
40
{
24
41
struct erdma_dev * dev = to_edev (qp -> ibqp .device );
@@ -79,18 +96,16 @@ static int create_qp_cmd(struct erdma_ucontext *uctx, struct erdma_qp *qp)
79
96
80
97
req .sq_mtt_cfg = user_qp -> sq_mem .page_offset ;
81
98
req .sq_mtt_cfg |= FIELD_PREP (ERDMA_CMD_CREATE_QP_MTT_CNT_MASK ,
82
- user_qp -> sq_mem .mtt_nents ) |
83
- FIELD_PREP (ERDMA_CMD_CREATE_QP_MTT_TYPE_MASK ,
84
- user_qp -> sq_mem .mtt_type );
99
+ user_qp -> sq_mem .mtt_nents );
85
100
86
101
req .rq_mtt_cfg = user_qp -> rq_mem .page_offset ;
87
102
req .rq_mtt_cfg |= FIELD_PREP (ERDMA_CMD_CREATE_QP_MTT_CNT_MASK ,
88
- user_qp -> rq_mem .mtt_nents ) |
89
- FIELD_PREP (ERDMA_CMD_CREATE_QP_MTT_TYPE_MASK ,
90
- user_qp -> rq_mem .mtt_type );
103
+ user_qp -> rq_mem .mtt_nents );
91
104
92
- req .sq_buf_addr = user_qp -> sq_mem .mtt_entry [0 ];
93
- req .rq_buf_addr = user_qp -> rq_mem .mtt_entry [0 ];
105
+ assemble_qbuf_mtt_for_cmd (& user_qp -> sq_mem , & req .sq_mtt_cfg ,
106
+ & req .sq_buf_addr , req .sq_mtt_entry );
107
+ assemble_qbuf_mtt_for_cmd (& user_qp -> rq_mem , & req .rq_mtt_cfg ,
108
+ & req .rq_buf_addr , req .rq_mtt_entry );
94
109
95
110
req .sq_db_info_dma_addr = user_qp -> sq_db_info_dma_addr ;
96
111
req .rq_db_info_dma_addr = user_qp -> rq_db_info_dma_addr ;
@@ -117,13 +132,22 @@ static int create_qp_cmd(struct erdma_ucontext *uctx, struct erdma_qp *qp)
117
132
118
133
static int regmr_cmd (struct erdma_dev * dev , struct erdma_mr * mr )
119
134
{
120
- struct erdma_cmdq_reg_mr_req req ;
121
135
struct erdma_pd * pd = to_epd (mr -> ibmr .pd );
122
- u64 * phy_addr ;
123
- int i ;
136
+ struct erdma_cmdq_reg_mr_req req ;
137
+ u32 mtt_level ;
124
138
125
139
erdma_cmdq_build_reqhdr (& req .hdr , CMDQ_SUBMOD_RDMA , CMDQ_OPCODE_REG_MR );
126
140
141
+ if (mr -> type == ERDMA_MR_TYPE_FRMR ||
142
+ mr -> mem .page_cnt > ERDMA_MAX_INLINE_MTT_ENTRIES ) {
143
+ req .phy_addr [0 ] = mr -> mem .mtt -> buf_dma ;
144
+ mtt_level = ERDMA_MR_INDIRECT_MTT ;
145
+ } else {
146
+ memcpy (req .phy_addr , mr -> mem .mtt -> buf ,
147
+ MTT_SIZE (mr -> mem .page_cnt ));
148
+ mtt_level = ERDMA_MR_INLINE_MTT ;
149
+ }
150
+
127
151
req .cfg0 = FIELD_PREP (ERDMA_CMD_MR_VALID_MASK , mr -> valid ) |
128
152
FIELD_PREP (ERDMA_CMD_MR_KEY_MASK , mr -> ibmr .lkey & 0xFF ) |
129
153
FIELD_PREP (ERDMA_CMD_MR_MPT_IDX_MASK , mr -> ibmr .lkey >> 8 );
@@ -132,7 +156,7 @@ static int regmr_cmd(struct erdma_dev *dev, struct erdma_mr *mr)
132
156
FIELD_PREP (ERDMA_CMD_REGMR_RIGHT_MASK , mr -> access );
133
157
req .cfg2 = FIELD_PREP (ERDMA_CMD_REGMR_PAGESIZE_MASK ,
134
158
ilog2 (mr -> mem .page_size )) |
135
- FIELD_PREP (ERDMA_CMD_REGMR_MTT_TYPE_MASK , mr -> mem . mtt_type ) |
159
+ FIELD_PREP (ERDMA_CMD_REGMR_MTT_LEVEL_MASK , mtt_level ) |
136
160
FIELD_PREP (ERDMA_CMD_REGMR_MTT_CNT_MASK , mr -> mem .page_cnt );
137
161
138
162
if (mr -> type == ERDMA_MR_TYPE_DMA )
@@ -143,16 +167,6 @@ static int regmr_cmd(struct erdma_dev *dev, struct erdma_mr *mr)
143
167
req .size = mr -> mem .len ;
144
168
}
145
169
146
- if (mr -> type == ERDMA_MR_TYPE_FRMR ||
147
- mr -> mem .mtt_type == ERDMA_MR_INDIRECT_MTT ) {
148
- phy_addr = req .phy_addr ;
149
- * phy_addr = mr -> mem .mtt_entry [0 ];
150
- } else {
151
- phy_addr = req .phy_addr ;
152
- for (i = 0 ; i < mr -> mem .mtt_nents ; i ++ )
153
- * phy_addr ++ = mr -> mem .mtt_entry [i ];
154
- }
155
-
156
170
post_cmd :
157
171
return erdma_post_cmd_wait (& dev -> cmdq , & req , sizeof (req ), NULL , NULL );
158
172
}
@@ -179,7 +193,7 @@ static int create_cq_cmd(struct erdma_ucontext *uctx, struct erdma_cq *cq)
179
193
req .qbuf_addr_h = upper_32_bits (cq -> kern_cq .qbuf_dma_addr );
180
194
181
195
req .cfg1 |= FIELD_PREP (ERDMA_CMD_CREATE_CQ_MTT_CNT_MASK , 1 ) |
182
- FIELD_PREP (ERDMA_CMD_CREATE_CQ_MTT_TYPE_MASK ,
196
+ FIELD_PREP (ERDMA_CMD_CREATE_CQ_MTT_LEVEL_MASK ,
183
197
ERDMA_MR_INLINE_MTT );
184
198
185
199
req .first_page_offset = 0 ;
@@ -191,16 +205,20 @@ static int create_cq_cmd(struct erdma_ucontext *uctx, struct erdma_cq *cq)
191
205
FIELD_PREP (ERDMA_CMD_CREATE_CQ_PAGESIZE_MASK ,
192
206
ilog2 (mem -> page_size ) - ERDMA_HW_PAGE_SHIFT );
193
207
if (mem -> mtt_nents == 1 ) {
194
- req .qbuf_addr_l = lower_32_bits (* (u64 * )mem -> mtt_buf );
195
- req .qbuf_addr_h = upper_32_bits (* (u64 * )mem -> mtt_buf );
208
+ req .qbuf_addr_l = lower_32_bits (mem -> mtt -> buf [0 ]);
209
+ req .qbuf_addr_h = upper_32_bits (mem -> mtt -> buf [0 ]);
210
+ req .cfg1 |=
211
+ FIELD_PREP (ERDMA_CMD_CREATE_CQ_MTT_LEVEL_MASK ,
212
+ ERDMA_MR_INLINE_MTT );
196
213
} else {
197
- req .qbuf_addr_l = lower_32_bits (mem -> mtt_entry [0 ]);
198
- req .qbuf_addr_h = upper_32_bits (mem -> mtt_entry [0 ]);
214
+ req .qbuf_addr_l = lower_32_bits (mem -> mtt -> buf_dma );
215
+ req .qbuf_addr_h = upper_32_bits (mem -> mtt -> buf_dma );
216
+ req .cfg1 |=
217
+ FIELD_PREP (ERDMA_CMD_CREATE_CQ_MTT_LEVEL_MASK ,
218
+ ERDMA_MR_INDIRECT_MTT );
199
219
}
200
220
req .cfg1 |= FIELD_PREP (ERDMA_CMD_CREATE_CQ_MTT_CNT_MASK ,
201
221
mem -> mtt_nents );
202
- req .cfg1 |= FIELD_PREP (ERDMA_CMD_CREATE_CQ_MTT_TYPE_MASK ,
203
- mem -> mtt_type );
204
222
205
223
req .first_page_offset = mem -> page_offset ;
206
224
req .cq_db_info_addr = cq -> user_cq .db_info_dma_addr ;
@@ -508,12 +526,77 @@ static int init_kernel_qp(struct erdma_dev *dev, struct erdma_qp *qp,
508
526
return - ENOMEM ;
509
527
}
510
528
529
+ static void erdma_fill_bottom_mtt (struct erdma_dev * dev , struct erdma_mem * mem )
530
+ {
531
+ struct erdma_mtt * mtt = mem -> mtt ;
532
+ struct ib_block_iter biter ;
533
+ u32 idx = 0 ;
534
+
535
+ while (mtt -> low_level )
536
+ mtt = mtt -> low_level ;
537
+
538
+ rdma_umem_for_each_dma_block (mem -> umem , & biter , mem -> page_size )
539
+ mtt -> buf [idx ++ ] = rdma_block_iter_dma_address (& biter );
540
+ }
541
+
542
+ static struct erdma_mtt * erdma_create_cont_mtt (struct erdma_dev * dev ,
543
+ size_t size )
544
+ {
545
+ struct erdma_mtt * mtt ;
546
+ int ret = - ENOMEM ;
547
+
548
+ mtt = kzalloc (sizeof (* mtt ), GFP_KERNEL );
549
+ if (!mtt )
550
+ return ERR_PTR (- ENOMEM );
551
+
552
+ mtt -> size = size ;
553
+ mtt -> buf = kzalloc (mtt -> size , GFP_KERNEL );
554
+ if (!mtt -> buf )
555
+ goto err_free_mtt ;
556
+
557
+ mtt -> continuous = true;
558
+ mtt -> buf_dma = dma_map_single (& dev -> pdev -> dev , mtt -> buf , mtt -> size ,
559
+ DMA_TO_DEVICE );
560
+ if (dma_mapping_error (& dev -> pdev -> dev , mtt -> buf_dma ))
561
+ goto err_free_mtt_buf ;
562
+
563
+ return mtt ;
564
+
565
+ err_free_mtt_buf :
566
+ kfree (mtt -> buf );
567
+
568
+ err_free_mtt :
569
+ kfree (mtt );
570
+
571
+ return ERR_PTR (ret );
572
+ }
573
+
574
+ static struct erdma_mtt * erdma_create_mtt (struct erdma_dev * dev , size_t size ,
575
+ bool force_continuous )
576
+ {
577
+ ibdev_dbg (& dev -> ibdev , "create_mtt, size:%lu, force cont:%d\n" , size ,
578
+ force_continuous );
579
+
580
+ if (force_continuous )
581
+ return erdma_create_cont_mtt (dev , size );
582
+
583
+ return ERR_PTR (- EOPNOTSUPP );
584
+ }
585
+
586
+ static void erdma_destroy_mtt (struct erdma_dev * dev , struct erdma_mtt * mtt )
587
+ {
588
+ if (mtt -> continuous ) {
589
+ dma_unmap_single (& dev -> pdev -> dev , mtt -> buf_dma , mtt -> size ,
590
+ DMA_TO_DEVICE );
591
+ kfree (mtt -> buf );
592
+ kfree (mtt );
593
+ }
594
+ }
595
+
511
596
static int get_mtt_entries (struct erdma_dev * dev , struct erdma_mem * mem ,
512
597
u64 start , u64 len , int access , u64 virt ,
513
598
unsigned long req_page_size , u8 force_indirect_mtt )
514
599
{
515
- struct ib_block_iter biter ;
516
- uint64_t * phy_addr = NULL ;
517
600
int ret = 0 ;
518
601
519
602
mem -> umem = ib_umem_get (& dev -> ibdev , start , len , access );
@@ -529,38 +612,13 @@ static int get_mtt_entries(struct erdma_dev *dev, struct erdma_mem *mem,
529
612
mem -> page_offset = start & (mem -> page_size - 1 );
530
613
mem -> mtt_nents = ib_umem_num_dma_blocks (mem -> umem , mem -> page_size );
531
614
mem -> page_cnt = mem -> mtt_nents ;
532
-
533
- if (mem -> page_cnt > ERDMA_MAX_INLINE_MTT_ENTRIES ||
534
- force_indirect_mtt ) {
535
- mem -> mtt_type = ERDMA_MR_INDIRECT_MTT ;
536
- mem -> mtt_buf =
537
- alloc_pages_exact (MTT_SIZE (mem -> page_cnt ), GFP_KERNEL );
538
- if (!mem -> mtt_buf ) {
539
- ret = - ENOMEM ;
540
- goto error_ret ;
541
- }
542
- phy_addr = mem -> mtt_buf ;
543
- } else {
544
- mem -> mtt_type = ERDMA_MR_INLINE_MTT ;
545
- phy_addr = mem -> mtt_entry ;
546
- }
547
-
548
- rdma_umem_for_each_dma_block (mem -> umem , & biter , mem -> page_size ) {
549
- * phy_addr = rdma_block_iter_dma_address (& biter );
550
- phy_addr ++ ;
615
+ mem -> mtt = erdma_create_mtt (dev , MTT_SIZE (mem -> page_cnt ), true);
616
+ if (IS_ERR (mem -> mtt )) {
617
+ ret = PTR_ERR (mem -> mtt );
618
+ goto error_ret ;
551
619
}
552
620
553
- if (mem -> mtt_type == ERDMA_MR_INDIRECT_MTT ) {
554
- mem -> mtt_entry [0 ] =
555
- dma_map_single (& dev -> pdev -> dev , mem -> mtt_buf ,
556
- MTT_SIZE (mem -> page_cnt ), DMA_TO_DEVICE );
557
- if (dma_mapping_error (& dev -> pdev -> dev , mem -> mtt_entry [0 ])) {
558
- free_pages_exact (mem -> mtt_buf , MTT_SIZE (mem -> page_cnt ));
559
- mem -> mtt_buf = NULL ;
560
- ret = - ENOMEM ;
561
- goto error_ret ;
562
- }
563
- }
621
+ erdma_fill_bottom_mtt (dev , mem );
564
622
565
623
return 0 ;
566
624
@@ -575,11 +633,8 @@ static int get_mtt_entries(struct erdma_dev *dev, struct erdma_mem *mem,
575
633
576
634
static void put_mtt_entries (struct erdma_dev * dev , struct erdma_mem * mem )
577
635
{
578
- if (mem -> mtt_buf ) {
579
- dma_unmap_single (& dev -> pdev -> dev , mem -> mtt_entry [0 ],
580
- MTT_SIZE (mem -> page_cnt ), DMA_TO_DEVICE );
581
- free_pages_exact (mem -> mtt_buf , MTT_SIZE (mem -> page_cnt ));
582
- }
636
+ if (mem -> mtt )
637
+ erdma_destroy_mtt (dev , mem -> mtt );
583
638
584
639
if (mem -> umem ) {
585
640
ib_umem_release (mem -> umem );
@@ -875,33 +930,20 @@ struct ib_mr *erdma_ib_alloc_mr(struct ib_pd *ibpd, enum ib_mr_type mr_type,
875
930
876
931
mr -> mem .page_size = PAGE_SIZE ; /* update it later. */
877
932
mr -> mem .page_cnt = max_num_sg ;
878
- mr -> mem .mtt_type = ERDMA_MR_INDIRECT_MTT ;
879
- mr -> mem .mtt_buf =
880
- alloc_pages_exact (MTT_SIZE (mr -> mem .page_cnt ), GFP_KERNEL );
881
- if (!mr -> mem .mtt_buf ) {
882
- ret = - ENOMEM ;
933
+ mr -> mem .mtt = erdma_create_mtt (dev , MTT_SIZE (max_num_sg ), true);
934
+ if (IS_ERR (mr -> mem .mtt )) {
935
+ ret = PTR_ERR (mr -> mem .mtt );
883
936
goto out_remove_stag ;
884
937
}
885
938
886
- mr -> mem .mtt_entry [0 ] =
887
- dma_map_single (& dev -> pdev -> dev , mr -> mem .mtt_buf ,
888
- MTT_SIZE (mr -> mem .page_cnt ), DMA_TO_DEVICE );
889
- if (dma_mapping_error (& dev -> pdev -> dev , mr -> mem .mtt_entry [0 ])) {
890
- ret = - ENOMEM ;
891
- goto out_free_mtt ;
892
- }
893
-
894
939
ret = regmr_cmd (dev , mr );
895
940
if (ret )
896
- goto out_dma_unmap ;
941
+ goto out_destroy_mtt ;
897
942
898
943
return & mr -> ibmr ;
899
944
900
- out_dma_unmap :
901
- dma_unmap_single (& dev -> pdev -> dev , mr -> mem .mtt_entry [0 ],
902
- MTT_SIZE (mr -> mem .page_cnt ), DMA_TO_DEVICE );
903
- out_free_mtt :
904
- free_pages_exact (mr -> mem .mtt_buf , MTT_SIZE (mr -> mem .page_cnt ));
945
+ out_destroy_mtt :
946
+ erdma_destroy_mtt (dev , mr -> mem .mtt );
905
947
906
948
out_remove_stag :
907
949
erdma_free_idx (& dev -> res_cb [ERDMA_RES_TYPE_STAG_IDX ],
@@ -920,7 +962,7 @@ static int erdma_set_page(struct ib_mr *ibmr, u64 addr)
920
962
if (mr -> mem .mtt_nents >= mr -> mem .page_cnt )
921
963
return -1 ;
922
964
923
- * (( u64 * ) mr -> mem .mtt_buf + mr -> mem .mtt_nents ) = addr ;
965
+ mr -> mem .mtt -> buf [ mr -> mem .mtt_nents ] = addr ;
924
966
mr -> mem .mtt_nents ++ ;
925
967
926
968
return 0 ;
0 commit comments