@@ -313,39 +313,21 @@ static int mlx5vf_cmd_get_vhca_id(struct mlx5_core_dev *mdev, u16 function_id,
313
313
return ret ;
314
314
}
315
315
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 )
320
317
{
321
- size_t npages = buf ? buf -> npages : recv_buf -> npages ;
322
- int err = 0 , inlen ;
323
- __be64 * mtt ;
318
+ int inlen ;
324
319
void * mkc ;
325
320
u32 * in ;
326
321
327
322
inlen = MLX5_ST_SZ_BYTES (create_mkey_in ) +
328
- sizeof (* mtt ) * round_up (npages , 2 );
323
+ sizeof (__be64 ) * round_up (npages , 2 );
329
324
330
- in = kvzalloc (inlen , GFP_KERNEL );
325
+ in = kvzalloc (inlen , GFP_KERNEL_ACCOUNT );
331
326
if (!in )
332
- return - ENOMEM ;
327
+ return NULL ;
333
328
334
329
MLX5_SET (create_mkey_in , in , translations_octword_actual_size ,
335
330
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
- }
349
331
350
332
mkc = MLX5_ADDR_OF (create_mkey_in , in , memory_key_mkey_entry );
351
333
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,
359
341
MLX5_SET (mkc , mkc , log_page_size , PAGE_SHIFT );
360
342
MLX5_SET (mkc , mkc , translations_octword_size , DIV_ROUND_UP (npages , 2 ));
361
343
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 );
365
368
}
366
369
367
370
static 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)
374
377
if (mvdev -> mdev_detach )
375
378
return - ENOTCONN ;
376
379
377
- if (buf -> dmaed || !buf -> npages )
380
+ if (buf -> mkey_in || !buf -> npages )
378
381
return - EINVAL ;
379
382
380
383
ret = dma_map_sgtable (mdev -> device , & buf -> table .sgt , buf -> dma_dir , 0 );
381
384
if (ret )
382
385
return ret ;
383
386
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 ;
386
390
goto err ;
391
+ }
387
392
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 ;
389
396
390
397
return 0 ;
398
+
399
+ err_create_mkey :
400
+ kvfree (buf -> mkey_in );
401
+ buf -> mkey_in = NULL ;
391
402
err :
392
403
dma_unmap_sgtable (mdev -> device , & buf -> table .sgt , buf -> dma_dir , 0 );
393
404
return ret ;
@@ -401,8 +412,9 @@ void mlx5vf_free_data_buffer(struct mlx5_vhca_data_buffer *buf)
401
412
lockdep_assert_held (& migf -> mvdev -> state_mutex );
402
413
WARN_ON (migf -> mvdev -> mdev_detach );
403
414
404
- if (buf -> dmaed ) {
415
+ if (buf -> mkey_in ) {
405
416
mlx5_core_destroy_mkey (migf -> mvdev -> mdev , buf -> mkey );
417
+ kvfree (buf -> mkey_in );
406
418
dma_unmap_sgtable (migf -> mvdev -> mdev -> device , & buf -> table .sgt ,
407
419
buf -> dma_dir , 0 );
408
420
}
@@ -783,7 +795,7 @@ int mlx5vf_cmd_load_vhca_state(struct mlx5vf_pci_core_device *mvdev,
783
795
if (mvdev -> mdev_detach )
784
796
return - ENOTCONN ;
785
797
786
- if (!buf -> dmaed ) {
798
+ if (!buf -> mkey_in ) {
787
799
err = mlx5vf_dma_data_buffer (buf );
788
800
if (err )
789
801
return err ;
@@ -1384,56 +1396,54 @@ static int alloc_recv_pages(struct mlx5_vhca_recv_buf *recv_buf,
1384
1396
kvfree (recv_buf -> page_list );
1385
1397
return - ENOMEM ;
1386
1398
}
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
+ }
1387
1413
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 )
1390
1416
{
1391
- int i , j ;
1417
+ dma_addr_t addr ;
1418
+ __be64 * mtt ;
1419
+ int i ;
1392
1420
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 );
1398
1422
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 ))
1405
1427
goto error ;
1428
+
1429
+ * mtt ++ = cpu_to_be64 (addr );
1406
1430
}
1431
+
1407
1432
return 0 ;
1408
1433
1409
1434
error :
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 );
1415
1436
return - ENOMEM ;
1416
1437
}
1417
1438
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
-
1430
1439
static void mlx5vf_free_qp_recv_resources (struct mlx5_core_dev * mdev ,
1431
1440
struct mlx5_vhca_qp * qp )
1432
1441
{
1433
1442
struct mlx5_vhca_recv_buf * recv_buf = & qp -> recv_buf ;
1434
1443
1435
1444
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 );
1437
1447
free_recv_pages (& qp -> recv_buf );
1438
1448
}
1439
1449
@@ -1449,18 +1459,29 @@ static int mlx5vf_alloc_qp_recv_resources(struct mlx5_core_dev *mdev,
1449
1459
if (err < 0 )
1450
1460
return err ;
1451
1461
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 ;
1454
1465
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 ;
1455
1472
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 );
1457
1475
if (err )
1458
1476
goto err_create_mkey ;
1459
1477
1460
1478
return 0 ;
1461
1479
1462
1480
err_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 ;
1464
1485
end :
1465
1486
free_recv_pages (recv_buf );
1466
1487
return err ;
0 commit comments