Skip to content

Commit ac6c973

Browse files
rleonawilliam
authored andcommitted
vfio/mlx5: Rewrite create mkey flow to allow better code reuse
Change the creation of mkey to be performed in multiple steps: data allocation, DMA setup and actual call to HW to create that mkey. In this new flow, the whole input to MKEY command is saved to eliminate the need to keep array of pointers for DMA addresses for receive list and in the future patches for send list too. In addition to memory size reduce and elimination of unnecessary data movements to set MKEY input, the code is prepared for future reuse. Tested-by: Jens Axboe <axboe@kernel.dk> Reviewed-by: Jason Gunthorpe <jgg@nvidia.com> Signed-off-by: Leon Romanovsky <leonro@nvidia.com> Acked-by: Yishai Hadas <yishaih@nvidia.com> Link: https://lore.kernel.org/r/d4ad0384fbd1e23a607cbbe9e5756748f3a761d9.1747747694.git.leon@kernel.org Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
1 parent 674ebb6 commit ac6c973

File tree

2 files changed

+91
-70
lines changed

2 files changed

+91
-70
lines changed

drivers/vfio/pci/mlx5/cmd.c

Lines changed: 89 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -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

367370
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)
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;
391402
err:
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

14091434
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);
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-
14301439
static 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

14621480
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;
14641485
end:
14651486
free_recv_pages(recv_buf);
14661487
return err;

drivers/vfio/pci/mlx5/cmd.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ struct mlx5_vhca_data_buffer {
5858
u64 length;
5959
u32 npages;
6060
u32 mkey;
61+
u32 *mkey_in;
6162
enum dma_data_direction dma_dir;
62-
u8 dmaed:1;
6363
u8 stop_copy_chunk_num;
6464
struct list_head buf_elm;
6565
struct mlx5_vf_migration_file *migf;
@@ -133,8 +133,8 @@ struct mlx5_vhca_cq {
133133
struct mlx5_vhca_recv_buf {
134134
u32 npages;
135135
struct page **page_list;
136-
dma_addr_t *dma_addrs;
137136
u32 next_rq_offset;
137+
u32 *mkey_in;
138138
u32 mkey;
139139
};
140140

0 commit comments

Comments
 (0)