Skip to content

Commit d284201

Browse files
committed
Merge: Fix failure to migrate a vm with mlx5_vfio_pci VF
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-10/-/merge_requests/110 JIRA: https://issues.redhat.com/browse/RHEL-69932 ``` vfio/mlx5: Align the page tracking max message size with the device capability Align the page tracking maximum message size with the device's capability instead of relying on PAGE_SIZE. This adjustment resolves a mismatch on systems where PAGE_SIZE is 64K, but the firmware only supports a maximum message size of 4K. Now that we rely on the device's capability for max_message_size, we must account for potential future increases in its value. Key considerations include: - Supporting message sizes that exceed a single system page (e.g., an 8K message on a 4K system). - Ensuring the RQ size is adjusted to accommodate at least 4 WQEs/messages, in line with the device specification. The above has been addressed as part of the patch. Fixes: 79c3cf2 ("vfio/mlx5: Init QP based resources for dirty tracking") Reviewed-by: Cédric Le Goater <clg@redhat.com> Tested-by: Yingshun Cui <yicui@redhat.com> Signed-off-by: Yishai Hadas <yishaih@nvidia.com> Link: https://lore.kernel.org/r/20241205122654.235619-1-yishaih@nvidia.com Signed-off-by: Alex Williamson <alex.williamson@redhat.com> (cherry picked from commit 9c7c543) ``` Signed-off-by: CKI Backport Bot <cki-ci-bot+cki-gitlab-backport-bot@redhat.com> --- Approved-by: Cédric Le Goater <clg@redhat.com> Approved-by: Donald Dutile <ddutile@redhat.com> Approved-by: Eric Auger <eric.auger@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Merged-by: Jan Stancek <jstancek@redhat.com>
2 parents a2ba547 + 663ea2a commit d284201

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
@@ -1513,7 +1513,8 @@ int mlx5vf_start_page_tracker(struct vfio_device *vdev,
15131513
struct mlx5_vhca_qp *host_qp;
15141514
struct mlx5_vhca_qp *fw_qp;
15151515
struct mlx5_core_dev *mdev;
1516-
u32 max_msg_size = PAGE_SIZE;
1516+
u32 log_max_msg_size;
1517+
u32 max_msg_size;
15171518
u64 rq_size = SZ_2M;
15181519
u32 max_recv_wr;
15191520
int err;
@@ -1530,6 +1531,12 @@ int mlx5vf_start_page_tracker(struct vfio_device *vdev,
15301531
}
15311532

15321533
mdev = mvdev->mdev;
1534+
log_max_msg_size = MLX5_CAP_ADV_VIRTUALIZATION(mdev, pg_track_log_max_msg_size);
1535+
max_msg_size = (1ULL << log_max_msg_size);
1536+
/* The RQ must hold at least 4 WQEs/messages for successful QP creation */
1537+
if (rq_size < 4 * max_msg_size)
1538+
rq_size = 4 * max_msg_size;
1539+
15331540
memset(tracker, 0, sizeof(*tracker));
15341541
tracker->uar = mlx5_get_uars_page(mdev);
15351542
if (IS_ERR(tracker->uar)) {
@@ -1619,25 +1626,41 @@ set_report_output(u32 size, int index, struct mlx5_vhca_qp *qp,
16191626
{
16201627
u32 entry_size = MLX5_ST_SZ_BYTES(page_track_report_entry);
16211628
u32 nent = size / entry_size;
1629+
u32 nent_in_page;
1630+
u32 nent_to_set;
16221631
struct page *page;
1632+
u32 page_offset;
1633+
u32 page_index;
1634+
u32 buf_offset;
1635+
void *kaddr;
16231636
u64 addr;
16241637
u64 *buf;
16251638
int i;
16261639

1627-
if (WARN_ON(index >= qp->recv_buf.npages ||
1640+
buf_offset = index * qp->max_msg_size;
1641+
if (WARN_ON(buf_offset + size >= qp->recv_buf.npages * PAGE_SIZE ||
16281642
(nent > qp->max_msg_size / entry_size)))
16291643
return;
16301644

1631-
page = qp->recv_buf.page_list[index];
1632-
buf = kmap_local_page(page);
1633-
for (i = 0; i < nent; i++) {
1634-
addr = MLX5_GET(page_track_report_entry, buf + i,
1635-
dirty_address_low);
1636-
addr |= (u64)MLX5_GET(page_track_report_entry, buf + i,
1637-
dirty_address_high) << 32;
1638-
iova_bitmap_set(dirty, addr, qp->tracked_page_size);
1639-
}
1640-
kunmap_local(buf);
1645+
do {
1646+
page_index = buf_offset / PAGE_SIZE;
1647+
page_offset = buf_offset % PAGE_SIZE;
1648+
nent_in_page = (PAGE_SIZE - page_offset) / entry_size;
1649+
page = qp->recv_buf.page_list[page_index];
1650+
kaddr = kmap_local_page(page);
1651+
buf = kaddr + page_offset;
1652+
nent_to_set = min(nent, nent_in_page);
1653+
for (i = 0; i < nent_to_set; i++) {
1654+
addr = MLX5_GET(page_track_report_entry, buf + i,
1655+
dirty_address_low);
1656+
addr |= (u64)MLX5_GET(page_track_report_entry, buf + i,
1657+
dirty_address_high) << 32;
1658+
iova_bitmap_set(dirty, addr, qp->tracked_page_size);
1659+
}
1660+
kunmap_local(kaddr);
1661+
buf_offset += (nent_to_set * entry_size);
1662+
nent -= nent_to_set;
1663+
} while (nent);
16411664
}
16421665

16431666
static void

0 commit comments

Comments
 (0)