Skip to content

Commit ec8e2d3

Browse files
committed
Merge tag 'vfio-v6.13-rc3' of https://github.com/awilliam/linux-vfio
Pull vfio fix from Alex Williamson: - Fix migration dirty page tracking support in the mlx5-vfio-pci variant driver in configurations where the system page size exceeds the device maximum message size, and anticipate device updates where the opposite may also be required (Yishai Hadas) * tag 'vfio-v6.13-rc3' of https://github.com/awilliam/linux-vfio: vfio/mlx5: Align the page tracking max message size with the device capability
2 parents becb337 + 9c7c543 commit ec8e2d3

File tree

1 file changed

+35
-12
lines changed
  • drivers/vfio/pci/mlx5

1 file changed

+35
-12
lines changed

drivers/vfio/pci/mlx5/cmd.c

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1517,7 +1517,8 @@ int mlx5vf_start_page_tracker(struct vfio_device *vdev,
15171517
struct mlx5_vhca_qp *host_qp;
15181518
struct mlx5_vhca_qp *fw_qp;
15191519
struct mlx5_core_dev *mdev;
1520-
u32 max_msg_size = PAGE_SIZE;
1520+
u32 log_max_msg_size;
1521+
u32 max_msg_size;
15211522
u64 rq_size = SZ_2M;
15221523
u32 max_recv_wr;
15231524
int err;
@@ -1534,6 +1535,12 @@ int mlx5vf_start_page_tracker(struct vfio_device *vdev,
15341535
}
15351536

15361537
mdev = mvdev->mdev;
1538+
log_max_msg_size = MLX5_CAP_ADV_VIRTUALIZATION(mdev, pg_track_log_max_msg_size);
1539+
max_msg_size = (1ULL << log_max_msg_size);
1540+
/* The RQ must hold at least 4 WQEs/messages for successful QP creation */
1541+
if (rq_size < 4 * max_msg_size)
1542+
rq_size = 4 * max_msg_size;
1543+
15371544
memset(tracker, 0, sizeof(*tracker));
15381545
tracker->uar = mlx5_get_uars_page(mdev);
15391546
if (IS_ERR(tracker->uar)) {
@@ -1623,25 +1630,41 @@ set_report_output(u32 size, int index, struct mlx5_vhca_qp *qp,
16231630
{
16241631
u32 entry_size = MLX5_ST_SZ_BYTES(page_track_report_entry);
16251632
u32 nent = size / entry_size;
1633+
u32 nent_in_page;
1634+
u32 nent_to_set;
16261635
struct page *page;
1636+
u32 page_offset;
1637+
u32 page_index;
1638+
u32 buf_offset;
1639+
void *kaddr;
16271640
u64 addr;
16281641
u64 *buf;
16291642
int i;
16301643

1631-
if (WARN_ON(index >= qp->recv_buf.npages ||
1644+
buf_offset = index * qp->max_msg_size;
1645+
if (WARN_ON(buf_offset + size >= qp->recv_buf.npages * PAGE_SIZE ||
16321646
(nent > qp->max_msg_size / entry_size)))
16331647
return;
16341648

1635-
page = qp->recv_buf.page_list[index];
1636-
buf = kmap_local_page(page);
1637-
for (i = 0; i < nent; i++) {
1638-
addr = MLX5_GET(page_track_report_entry, buf + i,
1639-
dirty_address_low);
1640-
addr |= (u64)MLX5_GET(page_track_report_entry, buf + i,
1641-
dirty_address_high) << 32;
1642-
iova_bitmap_set(dirty, addr, qp->tracked_page_size);
1643-
}
1644-
kunmap_local(buf);
1649+
do {
1650+
page_index = buf_offset / PAGE_SIZE;
1651+
page_offset = buf_offset % PAGE_SIZE;
1652+
nent_in_page = (PAGE_SIZE - page_offset) / entry_size;
1653+
page = qp->recv_buf.page_list[page_index];
1654+
kaddr = kmap_local_page(page);
1655+
buf = kaddr + page_offset;
1656+
nent_to_set = min(nent, nent_in_page);
1657+
for (i = 0; i < nent_to_set; i++) {
1658+
addr = MLX5_GET(page_track_report_entry, buf + i,
1659+
dirty_address_low);
1660+
addr |= (u64)MLX5_GET(page_track_report_entry, buf + i,
1661+
dirty_address_high) << 32;
1662+
iova_bitmap_set(dirty, addr, qp->tracked_page_size);
1663+
}
1664+
kunmap_local(kaddr);
1665+
buf_offset += (nent_to_set * entry_size);
1666+
nent -= nent_to_set;
1667+
} while (nent);
16451668
}
16461669

16471670
static void

0 commit comments

Comments
 (0)