@@ -313,39 +313,21 @@ static int mlx5vf_cmd_get_vhca_id(struct mlx5_core_dev *mdev, u16 function_id,
313313 return ret ;
314314}
315315
316- static int _create_mkey (struct mlx5_core_dev * mdev , u32 pdn ,
317- struct mlx5_vhca_data_buffer * buf ,
318- struct mlx5_vhca_recv_buf * recv_buf ,
319- u32 * mkey )
316+ static u32 * alloc_mkey_in (u32 npages , u32 pdn )
320317{
321- size_t npages = buf ? buf -> npages : recv_buf -> npages ;
322- int err = 0 , inlen ;
323- __be64 * mtt ;
318+ int inlen ;
324319 void * mkc ;
325320 u32 * in ;
326321
327322 inlen = MLX5_ST_SZ_BYTES (create_mkey_in ) +
328- sizeof (* mtt ) * round_up (npages , 2 );
323+ sizeof (__be64 ) * round_up (npages , 2 );
329324
330- in = kvzalloc (inlen , GFP_KERNEL );
325+ in = kvzalloc (inlen , GFP_KERNEL_ACCOUNT );
331326 if (!in )
332- return - ENOMEM ;
327+ return NULL ;
333328
334329 MLX5_SET (create_mkey_in , in , translations_octword_actual_size ,
335330 DIV_ROUND_UP (npages , 2 ));
336- mtt = (__be64 * )MLX5_ADDR_OF (create_mkey_in , in , klm_pas_mtt );
337-
338- if (buf ) {
339- struct sg_dma_page_iter dma_iter ;
340-
341- for_each_sgtable_dma_page (& buf -> table .sgt , & dma_iter , 0 )
342- * mtt ++ = cpu_to_be64 (sg_page_iter_dma_address (& dma_iter ));
343- } else {
344- int i ;
345-
346- for (i = 0 ; i < npages ; i ++ )
347- * mtt ++ = cpu_to_be64 (recv_buf -> dma_addrs [i ]);
348- }
349331
350332 mkc = MLX5_ADDR_OF (create_mkey_in , in , memory_key_mkey_entry );
351333 MLX5_SET (mkc , mkc , access_mode_1_0 , MLX5_MKC_ACCESS_MODE_MTT );
@@ -359,9 +341,30 @@ static int _create_mkey(struct mlx5_core_dev *mdev, u32 pdn,
359341 MLX5_SET (mkc , mkc , log_page_size , PAGE_SHIFT );
360342 MLX5_SET (mkc , mkc , translations_octword_size , DIV_ROUND_UP (npages , 2 ));
361343 MLX5_SET64 (mkc , mkc , len , npages * PAGE_SIZE );
362- err = mlx5_core_create_mkey (mdev , mkey , in , inlen );
363- kvfree (in );
364- return err ;
344+
345+ return in ;
346+ }
347+
348+ static int create_mkey (struct mlx5_core_dev * mdev , u32 npages ,
349+ struct mlx5_vhca_data_buffer * buf , u32 * mkey_in ,
350+ u32 * mkey )
351+ {
352+ __be64 * mtt ;
353+ int inlen ;
354+
355+ mtt = (__be64 * )MLX5_ADDR_OF (create_mkey_in , mkey_in , klm_pas_mtt );
356+ if (buf ) {
357+ struct sg_dma_page_iter dma_iter ;
358+
359+ for_each_sgtable_dma_page (& buf -> table .sgt , & dma_iter , 0 )
360+ * mtt ++ = cpu_to_be64 (
361+ sg_page_iter_dma_address (& dma_iter ));
362+ }
363+
364+ inlen = MLX5_ST_SZ_BYTES (create_mkey_in ) +
365+ sizeof (__be64 ) * round_up (npages , 2 );
366+
367+ return mlx5_core_create_mkey (mdev , mkey , mkey_in , inlen );
365368}
366369
367370static int mlx5vf_dma_data_buffer (struct mlx5_vhca_data_buffer * buf )
@@ -374,20 +377,28 @@ static int mlx5vf_dma_data_buffer(struct mlx5_vhca_data_buffer *buf)
374377 if (mvdev -> mdev_detach )
375378 return - ENOTCONN ;
376379
377- if (buf -> dmaed || !buf -> npages )
380+ if (buf -> mkey_in || !buf -> npages )
378381 return - EINVAL ;
379382
380383 ret = dma_map_sgtable (mdev -> device , & buf -> table .sgt , buf -> dma_dir , 0 );
381384 if (ret )
382385 return ret ;
383386
384- ret = _create_mkey (mdev , buf -> migf -> pdn , buf , NULL , & buf -> mkey );
385- if (ret )
387+ buf -> mkey_in = alloc_mkey_in (buf -> npages , buf -> migf -> pdn );
388+ if (!buf -> mkey_in ) {
389+ ret = - ENOMEM ;
386390 goto err ;
391+ }
387392
388- buf -> dmaed = true;
393+ ret = create_mkey (mdev , buf -> npages , buf , buf -> mkey_in , & buf -> mkey );
394+ if (ret )
395+ goto err_create_mkey ;
389396
390397 return 0 ;
398+
399+ err_create_mkey :
400+ kvfree (buf -> mkey_in );
401+ buf -> mkey_in = NULL ;
391402err :
392403 dma_unmap_sgtable (mdev -> device , & buf -> table .sgt , buf -> dma_dir , 0 );
393404 return ret ;
@@ -401,8 +412,9 @@ void mlx5vf_free_data_buffer(struct mlx5_vhca_data_buffer *buf)
401412 lockdep_assert_held (& migf -> mvdev -> state_mutex );
402413 WARN_ON (migf -> mvdev -> mdev_detach );
403414
404- if (buf -> dmaed ) {
415+ if (buf -> mkey_in ) {
405416 mlx5_core_destroy_mkey (migf -> mvdev -> mdev , buf -> mkey );
417+ kvfree (buf -> mkey_in );
406418 dma_unmap_sgtable (migf -> mvdev -> mdev -> device , & buf -> table .sgt ,
407419 buf -> dma_dir , 0 );
408420 }
@@ -783,7 +795,7 @@ int mlx5vf_cmd_load_vhca_state(struct mlx5vf_pci_core_device *mvdev,
783795 if (mvdev -> mdev_detach )
784796 return - ENOTCONN ;
785797
786- if (!buf -> dmaed ) {
798+ if (!buf -> mkey_in ) {
787799 err = mlx5vf_dma_data_buffer (buf );
788800 if (err )
789801 return err ;
@@ -1384,56 +1396,54 @@ static int alloc_recv_pages(struct mlx5_vhca_recv_buf *recv_buf,
13841396 kvfree (recv_buf -> page_list );
13851397 return - ENOMEM ;
13861398}
1399+ static void unregister_dma_pages (struct mlx5_core_dev * mdev , u32 npages ,
1400+ u32 * mkey_in )
1401+ {
1402+ dma_addr_t addr ;
1403+ __be64 * mtt ;
1404+ int i ;
1405+
1406+ mtt = (__be64 * )MLX5_ADDR_OF (create_mkey_in , mkey_in , klm_pas_mtt );
1407+ for (i = npages - 1 ; i >= 0 ; i -- ) {
1408+ addr = be64_to_cpu (mtt [i ]);
1409+ dma_unmap_single (mdev -> device , addr , PAGE_SIZE ,
1410+ DMA_FROM_DEVICE );
1411+ }
1412+ }
13871413
1388- static int register_dma_recv_pages (struct mlx5_core_dev * mdev ,
1389- struct mlx5_vhca_recv_buf * recv_buf )
1414+ static int register_dma_pages (struct mlx5_core_dev * mdev , u32 npages ,
1415+ struct page * * page_list , u32 * mkey_in )
13901416{
1391- int i , j ;
1417+ dma_addr_t addr ;
1418+ __be64 * mtt ;
1419+ int i ;
13921420
1393- recv_buf -> dma_addrs = kvcalloc (recv_buf -> npages ,
1394- sizeof (* recv_buf -> dma_addrs ),
1395- GFP_KERNEL_ACCOUNT );
1396- if (!recv_buf -> dma_addrs )
1397- return - ENOMEM ;
1421+ mtt = (__be64 * )MLX5_ADDR_OF (create_mkey_in , mkey_in , klm_pas_mtt );
13981422
1399- for (i = 0 ; i < recv_buf -> npages ; i ++ ) {
1400- recv_buf -> dma_addrs [i ] = dma_map_page (mdev -> device ,
1401- recv_buf -> page_list [i ],
1402- 0 , PAGE_SIZE ,
1403- DMA_FROM_DEVICE );
1404- if (dma_mapping_error (mdev -> device , recv_buf -> dma_addrs [i ]))
1423+ for (i = 0 ; i < npages ; i ++ ) {
1424+ addr = dma_map_page (mdev -> device , page_list [i ], 0 , PAGE_SIZE ,
1425+ DMA_FROM_DEVICE );
1426+ if (dma_mapping_error (mdev -> device , addr ))
14051427 goto error ;
1428+
1429+ * mtt ++ = cpu_to_be64 (addr );
14061430 }
1431+
14071432 return 0 ;
14081433
14091434error :
1410- for (j = 0 ; j < i ; j ++ )
1411- dma_unmap_single (mdev -> device , recv_buf -> dma_addrs [j ],
1412- PAGE_SIZE , DMA_FROM_DEVICE );
1413-
1414- kvfree (recv_buf -> dma_addrs );
1435+ unregister_dma_pages (mdev , i , mkey_in );
14151436 return - ENOMEM ;
14161437}
14171438
1418- static void unregister_dma_recv_pages (struct mlx5_core_dev * mdev ,
1419- struct mlx5_vhca_recv_buf * recv_buf )
1420- {
1421- int i ;
1422-
1423- for (i = 0 ; i < recv_buf -> npages ; i ++ )
1424- dma_unmap_single (mdev -> device , recv_buf -> dma_addrs [i ],
1425- PAGE_SIZE , DMA_FROM_DEVICE );
1426-
1427- kvfree (recv_buf -> dma_addrs );
1428- }
1429-
14301439static void mlx5vf_free_qp_recv_resources (struct mlx5_core_dev * mdev ,
14311440 struct mlx5_vhca_qp * qp )
14321441{
14331442 struct mlx5_vhca_recv_buf * recv_buf = & qp -> recv_buf ;
14341443
14351444 mlx5_core_destroy_mkey (mdev , recv_buf -> mkey );
1436- unregister_dma_recv_pages (mdev , recv_buf );
1445+ unregister_dma_pages (mdev , recv_buf -> npages , recv_buf -> mkey_in );
1446+ kvfree (recv_buf -> mkey_in );
14371447 free_recv_pages (& qp -> recv_buf );
14381448}
14391449
@@ -1449,18 +1459,29 @@ static int mlx5vf_alloc_qp_recv_resources(struct mlx5_core_dev *mdev,
14491459 if (err < 0 )
14501460 return err ;
14511461
1452- err = register_dma_recv_pages (mdev , recv_buf );
1453- if (err )
1462+ recv_buf -> mkey_in = alloc_mkey_in (npages , pdn );
1463+ if (!recv_buf -> mkey_in ) {
1464+ err = - ENOMEM ;
14541465 goto end ;
1466+ }
1467+
1468+ err = register_dma_pages (mdev , npages , recv_buf -> page_list ,
1469+ recv_buf -> mkey_in );
1470+ if (err )
1471+ goto err_register_dma ;
14551472
1456- err = _create_mkey (mdev , pdn , NULL , recv_buf , & recv_buf -> mkey );
1473+ err = create_mkey (mdev , npages , NULL , recv_buf -> mkey_in ,
1474+ & recv_buf -> mkey );
14571475 if (err )
14581476 goto err_create_mkey ;
14591477
14601478 return 0 ;
14611479
14621480err_create_mkey :
1463- unregister_dma_recv_pages (mdev , recv_buf );
1481+ unregister_dma_pages (mdev , npages , recv_buf -> mkey_in );
1482+ err_register_dma :
1483+ kvfree (recv_buf -> mkey_in );
1484+ recv_buf -> mkey_in = NULL ;
14641485end :
14651486 free_recv_pages (recv_buf );
14661487 return err ;
0 commit comments