@@ -828,16 +828,16 @@ static int smbd_post_send(struct smbd_connection *info,
828828 return rc ;
829829}
830830
831- static int smbd_post_send_sgl (struct smbd_connection * info ,
832- struct scatterlist * sgl , int data_length , int remaining_data_length )
831+ static int smbd_post_send_iter (struct smbd_connection * info ,
832+ struct iov_iter * iter ,
833+ int * _remaining_data_length )
833834{
834- int num_sgs ;
835835 int i , rc ;
836836 int header_length ;
837+ int data_length ;
837838 struct smbd_request * request ;
838839 struct smbd_data_transfer * packet ;
839840 int new_credits ;
840- struct scatterlist * sg ;
841841
842842wait_credit :
843843 /* Wait for send credits. A SMBD packet needs one credit */
@@ -881,6 +881,30 @@ static int smbd_post_send_sgl(struct smbd_connection *info,
881881 }
882882
883883 request -> info = info ;
884+ memset (request -> sge , 0 , sizeof (request -> sge ));
885+
886+ /* Fill in the data payload to find out how much data we can add */
887+ if (iter ) {
888+ struct smb_extract_to_rdma extract = {
889+ .nr_sge = 1 ,
890+ .max_sge = SMBDIRECT_MAX_SEND_SGE ,
891+ .sge = request -> sge ,
892+ .device = info -> id -> device ,
893+ .local_dma_lkey = info -> pd -> local_dma_lkey ,
894+ .direction = DMA_TO_DEVICE ,
895+ };
896+
897+ rc = smb_extract_iter_to_rdma (iter , * _remaining_data_length ,
898+ & extract );
899+ if (rc < 0 )
900+ goto err_dma ;
901+ data_length = rc ;
902+ request -> num_sge = extract .nr_sge ;
903+ * _remaining_data_length -= data_length ;
904+ } else {
905+ data_length = 0 ;
906+ request -> num_sge = 1 ;
907+ }
884908
885909 /* Fill in the packet header */
886910 packet = smbd_request_payload (request );
@@ -902,7 +926,7 @@ static int smbd_post_send_sgl(struct smbd_connection *info,
902926 else
903927 packet -> data_offset = cpu_to_le32 (24 );
904928 packet -> data_length = cpu_to_le32 (data_length );
905- packet -> remaining_data_length = cpu_to_le32 (remaining_data_length );
929+ packet -> remaining_data_length = cpu_to_le32 (* _remaining_data_length );
906930 packet -> padding = 0 ;
907931
908932 log_outgoing (INFO , "credits_requested=%d credits_granted=%d data_offset=%d data_length=%d remaining_data_length=%d\n" ,
@@ -918,7 +942,6 @@ static int smbd_post_send_sgl(struct smbd_connection *info,
918942 if (!data_length )
919943 header_length = offsetof(struct smbd_data_transfer , padding );
920944
921- request -> num_sge = 1 ;
922945 request -> sge [0 ].addr = ib_dma_map_single (info -> id -> device ,
923946 (void * )packet ,
924947 header_length ,
@@ -932,23 +955,6 @@ static int smbd_post_send_sgl(struct smbd_connection *info,
932955 request -> sge [0 ].length = header_length ;
933956 request -> sge [0 ].lkey = info -> pd -> local_dma_lkey ;
934957
935- /* Fill in the packet data payload */
936- num_sgs = sgl ? sg_nents (sgl ) : 0 ;
937- for_each_sg (sgl , sg , num_sgs , i ) {
938- request -> sge [i + 1 ].addr =
939- ib_dma_map_page (info -> id -> device , sg_page (sg ),
940- sg -> offset , sg -> length , DMA_TO_DEVICE );
941- if (ib_dma_mapping_error (
942- info -> id -> device , request -> sge [i + 1 ].addr )) {
943- rc = - EIO ;
944- request -> sge [i + 1 ].addr = 0 ;
945- goto err_dma ;
946- }
947- request -> sge [i + 1 ].length = sg -> length ;
948- request -> sge [i + 1 ].lkey = info -> pd -> local_dma_lkey ;
949- request -> num_sge ++ ;
950- }
951-
952958 rc = smbd_post_send (info , request );
953959 if (!rc )
954960 return 0 ;
@@ -987,8 +993,10 @@ static int smbd_post_send_sgl(struct smbd_connection *info,
987993 */
988994static int smbd_post_send_empty (struct smbd_connection * info )
989995{
996+ int remaining_data_length = 0 ;
997+
990998 info -> count_send_empty ++ ;
991- return smbd_post_send_sgl (info , NULL , 0 , 0 );
999+ return smbd_post_send_iter (info , NULL , & remaining_data_length );
9921000}
9931001
9941002/*
@@ -1934,42 +1942,6 @@ int smbd_recv(struct smbd_connection *info, struct msghdr *msg)
19341942 return rc ;
19351943}
19361944
1937- /*
1938- * Send the contents of an iterator
1939- * @iter: The iterator to send
1940- * @_remaining_data_length: remaining data to send in this payload
1941- */
1942- static int smbd_post_send_iter (struct smbd_connection * info ,
1943- struct iov_iter * iter ,
1944- int * _remaining_data_length )
1945- {
1946- struct scatterlist sgl [SMBDIRECT_MAX_SEND_SGE - 1 ];
1947- unsigned int max_payload = info -> max_send_size - sizeof (struct smbd_data_transfer );
1948- ssize_t rc ;
1949-
1950- /* We're not expecting a user-backed iter */
1951- WARN_ON (iov_iter_extract_will_pin (iter ));
1952-
1953- do {
1954- struct sg_table sgtable = { .sgl = sgl };
1955- size_t maxlen = min_t (size_t , * _remaining_data_length , max_payload );
1956-
1957- sg_init_table (sgtable .sgl , ARRAY_SIZE (sgl ));
1958- rc = netfs_extract_iter_to_sg (iter , maxlen ,
1959- & sgtable , ARRAY_SIZE (sgl ), 0 );
1960- if (rc < 0 )
1961- break ;
1962- if (WARN_ON_ONCE (sgtable .nents == 0 ))
1963- return - EIO ;
1964-
1965- sg_mark_end (& sgl [sgtable .nents - 1 ]);
1966- * _remaining_data_length -= rc ;
1967- rc = smbd_post_send_sgl (info , sgl , rc , * _remaining_data_length );
1968- } while (rc == 0 && iov_iter_count (iter ) > 0 );
1969-
1970- return rc ;
1971- }
1972-
19731945/*
19741946 * Send data to transport
19751947 * Each rqst is transported as a SMBDirect payload
@@ -2130,10 +2102,10 @@ static void destroy_mr_list(struct smbd_connection *info)
21302102 cancel_work_sync (& info -> mr_recovery_work );
21312103 list_for_each_entry_safe (mr , tmp , & info -> mr_list , list ) {
21322104 if (mr -> state == MR_INVALIDATED )
2133- ib_dma_unmap_sg (info -> id -> device , mr -> sgl ,
2134- mr -> sgl_count , mr -> dir );
2105+ ib_dma_unmap_sg (info -> id -> device , mr -> sgt . sgl ,
2106+ mr -> sgt . nents , mr -> dir );
21352107 ib_dereg_mr (mr -> mr );
2136- kfree (mr -> sgl );
2108+ kfree (mr -> sgt . sgl );
21372109 kfree (mr );
21382110 }
21392111}
@@ -2169,11 +2141,10 @@ static int allocate_mr_list(struct smbd_connection *info)
21692141 info -> mr_type , info -> max_frmr_depth );
21702142 goto out ;
21712143 }
2172- smbdirect_mr -> sgl = kcalloc (
2173- info -> max_frmr_depth ,
2174- sizeof (struct scatterlist ),
2175- GFP_KERNEL );
2176- if (!smbdirect_mr -> sgl ) {
2144+ smbdirect_mr -> sgt .sgl = kcalloc (info -> max_frmr_depth ,
2145+ sizeof (struct scatterlist ),
2146+ GFP_KERNEL );
2147+ if (!smbdirect_mr -> sgt .sgl ) {
21772148 log_rdma_mr (ERR , "failed to allocate sgl\n" );
21782149 ib_dereg_mr (smbdirect_mr -> mr );
21792150 goto out ;
@@ -2192,7 +2163,7 @@ static int allocate_mr_list(struct smbd_connection *info)
21922163 list_for_each_entry_safe (smbdirect_mr , tmp , & info -> mr_list , list ) {
21932164 list_del (& smbdirect_mr -> list );
21942165 ib_dereg_mr (smbdirect_mr -> mr );
2195- kfree (smbdirect_mr -> sgl );
2166+ kfree (smbdirect_mr -> sgt . sgl );
21962167 kfree (smbdirect_mr );
21972168 }
21982169 return - ENOMEM ;
@@ -2246,22 +2217,20 @@ static struct smbd_mr *get_mr(struct smbd_connection *info)
22462217
22472218/*
22482219 * Transcribe the pages from an iterator into an MR scatterlist.
2249- * @iter: The iterator to transcribe
2250- * @_remaining_data_length: remaining data to send in this payload
22512220 */
22522221static int smbd_iter_to_mr (struct smbd_connection * info ,
22532222 struct iov_iter * iter ,
2254- struct scatterlist * sgl ,
2255- unsigned int num_pages )
2223+ struct sg_table * sgt ,
2224+ unsigned int max_sg )
22562225{
2257- struct sg_table sgtable = { .sgl = sgl };
22582226 int ret ;
22592227
2260- sg_init_table ( sgl , num_pages );
2228+ memset ( sgt -> sgl , 0 , max_sg * sizeof ( struct scatterlist ) );
22612229
2262- ret = netfs_extract_iter_to_sg (iter , iov_iter_count (iter ),
2263- & sgtable , num_pages , 0 );
2230+ ret = netfs_extract_iter_to_sg (iter , iov_iter_count (iter ), sgt , max_sg , 0 );
22642231 WARN_ON (ret < 0 );
2232+ if (sgt -> nents > 0 )
2233+ sg_mark_end (& sgt -> sgl [sgt -> nents - 1 ]);
22652234 return ret ;
22662235}
22672236
@@ -2298,25 +2267,27 @@ struct smbd_mr *smbd_register_mr(struct smbd_connection *info,
22982267 dir = writing ? DMA_FROM_DEVICE : DMA_TO_DEVICE ;
22992268 smbdirect_mr -> dir = dir ;
23002269 smbdirect_mr -> need_invalidate = need_invalidate ;
2301- smbdirect_mr -> sgl_count = num_pages ;
2270+ smbdirect_mr -> sgt .nents = 0 ;
2271+ smbdirect_mr -> sgt .orig_nents = 0 ;
23022272
2303- log_rdma_mr (INFO , "num_pages=0x%x count=0x%zx\n" ,
2304- num_pages , iov_iter_count (iter ));
2305- smbd_iter_to_mr (info , iter , smbdirect_mr -> sgl , num_pages );
2273+ log_rdma_mr (INFO , "num_pages=0x%x count=0x%zx depth=%u \n" ,
2274+ num_pages , iov_iter_count (iter ), info -> max_frmr_depth );
2275+ smbd_iter_to_mr (info , iter , & smbdirect_mr -> sgt , info -> max_frmr_depth );
23062276
2307- rc = ib_dma_map_sg (info -> id -> device , smbdirect_mr -> sgl , num_pages , dir );
2277+ rc = ib_dma_map_sg (info -> id -> device , smbdirect_mr -> sgt .sgl ,
2278+ smbdirect_mr -> sgt .nents , dir );
23082279 if (!rc ) {
23092280 log_rdma_mr (ERR , "ib_dma_map_sg num_pages=%x dir=%x rc=%x\n" ,
23102281 num_pages , dir , rc );
23112282 goto dma_map_error ;
23122283 }
23132284
2314- rc = ib_map_mr_sg (smbdirect_mr -> mr , smbdirect_mr -> sgl , num_pages ,
2315- NULL , PAGE_SIZE );
2316- if (rc != num_pages ) {
2285+ rc = ib_map_mr_sg (smbdirect_mr -> mr , smbdirect_mr -> sgt . sgl ,
2286+ smbdirect_mr -> sgt . nents , NULL , PAGE_SIZE );
2287+ if (rc != smbdirect_mr -> sgt . nents ) {
23172288 log_rdma_mr (ERR ,
2318- "ib_map_mr_sg failed rc = %d num_pages = %x\n" ,
2319- rc , num_pages );
2289+ "ib_map_mr_sg failed rc = %d nents = %x\n" ,
2290+ rc , smbdirect_mr -> sgt . nents );
23202291 goto map_mr_error ;
23212292 }
23222293
@@ -2348,8 +2319,8 @@ struct smbd_mr *smbd_register_mr(struct smbd_connection *info,
23482319
23492320 /* If all failed, attempt to recover this MR by setting it MR_ERROR*/
23502321map_mr_error :
2351- ib_dma_unmap_sg (info -> id -> device , smbdirect_mr -> sgl ,
2352- smbdirect_mr -> sgl_count , smbdirect_mr -> dir );
2322+ ib_dma_unmap_sg (info -> id -> device , smbdirect_mr -> sgt . sgl ,
2323+ smbdirect_mr -> sgt . nents , smbdirect_mr -> dir );
23532324
23542325dma_map_error :
23552326 smbdirect_mr -> state = MR_ERROR ;
@@ -2416,8 +2387,8 @@ int smbd_deregister_mr(struct smbd_mr *smbdirect_mr)
24162387
24172388 if (smbdirect_mr -> state == MR_INVALIDATED ) {
24182389 ib_dma_unmap_sg (
2419- info -> id -> device , smbdirect_mr -> sgl ,
2420- smbdirect_mr -> sgl_count ,
2390+ info -> id -> device , smbdirect_mr -> sgt . sgl ,
2391+ smbdirect_mr -> sgt . nents ,
24212392 smbdirect_mr -> dir );
24222393 smbdirect_mr -> state = MR_READY ;
24232394 if (atomic_inc_return (& info -> mr_ready_count ) == 1 )
0 commit comments