Skip to content

Commit

Permalink
iommufd/selftest: Refactor dirty bitmap tests
Browse files Browse the repository at this point in the history
Rework the functions that test and set the bitmaps to receive a new
parameter (the pte_page_size) that reflects the expected PTE size in the
page tables. The same scheme is still used i.e. even bits are dirty and
odd page indexes aren't dirty. Here it just refactors to consider the size
of the PTE rather than hardcoded to IOMMU mock base page assumptions.

While at it, refactor dirty bitmap tests to use the idev_id created by the
fixture instead of creating a new one.

This is in preparation for doing tests with IOMMU hugepages where multiple
bits set as part of recording a whole hugepage as dirty and thus the
pte_page_size will vary depending on io hugepages or io base pages.

Link: https://lore.kernel.org/r/20240202133415.23819-6-joao.m.martins@oracle.com
Signed-off-by: Joao Martins <joao.m.martins@oracle.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
  • Loading branch information
jpemartins authored and jgunthorpe committed Feb 6, 2024
1 parent 2780025 commit 407fc18
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 31 deletions.
28 changes: 11 additions & 17 deletions tools/testing/selftests/iommu/iommufd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1849,7 +1849,7 @@ TEST_F(iommufd_dirty_tracking, device_dirty_capability)

TEST_F(iommufd_dirty_tracking, get_dirty_bitmap)
{
uint32_t stddev_id;
uint32_t page_size = MOCK_PAGE_SIZE;
uint32_t hwpt_id;
uint32_t ioas_id;

Expand All @@ -1859,34 +1859,31 @@ TEST_F(iommufd_dirty_tracking, get_dirty_bitmap)

test_cmd_hwpt_alloc(self->idev_id, ioas_id,
IOMMU_HWPT_ALLOC_DIRTY_TRACKING, &hwpt_id);
test_cmd_mock_domain(hwpt_id, &stddev_id, NULL, NULL);

test_cmd_set_dirty_tracking(hwpt_id, true);

test_mock_dirty_bitmaps(hwpt_id, variant->buffer_size,
MOCK_APERTURE_START, self->page_size,
MOCK_APERTURE_START, self->page_size, page_size,
self->bitmap, self->bitmap_size, 0, _metadata);

/* PAGE_SIZE unaligned bitmap */
test_mock_dirty_bitmaps(hwpt_id, variant->buffer_size,
MOCK_APERTURE_START, self->page_size,
MOCK_APERTURE_START, self->page_size, page_size,
self->bitmap + MOCK_PAGE_SIZE,
self->bitmap_size, 0, _metadata);

/* u64 unaligned bitmap */
test_mock_dirty_bitmaps(hwpt_id, variant->buffer_size,
MOCK_APERTURE_START, self->page_size,
self->bitmap + 0xff1,
self->bitmap_size, 0, _metadata);

MOCK_APERTURE_START, self->page_size, page_size,
self->bitmap + 0xff1, self->bitmap_size, 0,
_metadata);

test_ioctl_destroy(stddev_id);
test_ioctl_destroy(hwpt_id);
}

TEST_F(iommufd_dirty_tracking, get_dirty_bitmap_no_clear)
{
uint32_t stddev_id;
uint32_t page_size = MOCK_PAGE_SIZE;
uint32_t hwpt_id;
uint32_t ioas_id;

Expand All @@ -1896,33 +1893,30 @@ TEST_F(iommufd_dirty_tracking, get_dirty_bitmap_no_clear)

test_cmd_hwpt_alloc(self->idev_id, ioas_id,
IOMMU_HWPT_ALLOC_DIRTY_TRACKING, &hwpt_id);
test_cmd_mock_domain(hwpt_id, &stddev_id, NULL, NULL);

test_cmd_set_dirty_tracking(hwpt_id, true);

test_mock_dirty_bitmaps(hwpt_id, variant->buffer_size,
MOCK_APERTURE_START, self->page_size,
MOCK_APERTURE_START, self->page_size, page_size,
self->bitmap, self->bitmap_size,
IOMMU_HWPT_GET_DIRTY_BITMAP_NO_CLEAR,
_metadata);

/* Unaligned bitmap */
test_mock_dirty_bitmaps(hwpt_id, variant->buffer_size,
MOCK_APERTURE_START, self->page_size,
MOCK_APERTURE_START, self->page_size, page_size,
self->bitmap + MOCK_PAGE_SIZE,
self->bitmap_size,
IOMMU_HWPT_GET_DIRTY_BITMAP_NO_CLEAR,
_metadata);

/* u64 unaligned bitmap */
test_mock_dirty_bitmaps(hwpt_id, variant->buffer_size,
MOCK_APERTURE_START, self->page_size,
self->bitmap + 0xff1,
self->bitmap_size,
MOCK_APERTURE_START, self->page_size, page_size,
self->bitmap + 0xff1, self->bitmap_size,
IOMMU_HWPT_GET_DIRTY_BITMAP_NO_CLEAR,
_metadata);

test_ioctl_destroy(stddev_id);
test_ioctl_destroy(hwpt_id);
}

Expand Down
39 changes: 25 additions & 14 deletions tools/testing/selftests/iommu/iommufd_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -344,16 +344,19 @@ static int _test_cmd_mock_domain_set_dirty(int fd, __u32 hwpt_id, size_t length,
page_size, bitmap, nr))

static int _test_mock_dirty_bitmaps(int fd, __u32 hwpt_id, size_t length,
__u64 iova, size_t page_size, __u64 *bitmap,
__u64 iova, size_t page_size,
size_t pte_page_size, __u64 *bitmap,
__u64 bitmap_size, __u32 flags,
struct __test_metadata *_metadata)
{
unsigned long i, nbits = bitmap_size * BITS_PER_BYTE;
unsigned long nr = nbits / 2;
unsigned long npte = pte_page_size / page_size, pteset = 2 * npte;
unsigned long nbits = bitmap_size * BITS_PER_BYTE;
unsigned long j, i, nr = nbits / pteset ?: 1;
__u64 out_dirty = 0;

/* Mark all even bits as dirty in the mock domain */
for (i = 0; i < nbits; i += 2)
memset(bitmap, 0, bitmap_size);
for (i = 0; i < nbits; i += pteset)
set_bit(i, (unsigned long *)bitmap);

test_cmd_mock_domain_set_dirty(fd, hwpt_id, length, iova, page_size,
Expand All @@ -365,28 +368,36 @@ static int _test_mock_dirty_bitmaps(int fd, __u32 hwpt_id, size_t length,
test_cmd_get_dirty_bitmap(fd, hwpt_id, length, iova, page_size, bitmap,
flags);
/* Beware ASSERT_EQ() is two statements -- braces are not redundant! */
for (i = 0; i < nbits; i++) {
ASSERT_EQ(!(i % 2), test_bit(i, (unsigned long *)bitmap));
for (i = 0; i < nbits; i += pteset) {
for (j = 0; j < pteset; j++) {
ASSERT_EQ(j < npte,
test_bit(i + j, (unsigned long *)bitmap));
}
ASSERT_EQ(!(i % pteset), test_bit(i, (unsigned long *)bitmap));
}

memset(bitmap, 0, bitmap_size);
test_cmd_get_dirty_bitmap(fd, hwpt_id, length, iova, page_size, bitmap,
flags);

/* It as read already -- expect all zeroes */
for (i = 0; i < nbits; i++) {
ASSERT_EQ(!(i % 2) && (flags &
IOMMU_HWPT_GET_DIRTY_BITMAP_NO_CLEAR),
test_bit(i, (unsigned long *)bitmap));
for (i = 0; i < nbits; i += pteset) {
for (j = 0; j < pteset; j++) {
ASSERT_EQ(
(j < npte) &&
(flags &
IOMMU_HWPT_GET_DIRTY_BITMAP_NO_CLEAR),
test_bit(i + j, (unsigned long *)bitmap));
}
}

return 0;
}
#define test_mock_dirty_bitmaps(hwpt_id, length, iova, page_size, bitmap, \
bitmap_size, flags, _metadata) \
#define test_mock_dirty_bitmaps(hwpt_id, length, iova, page_size, pte_size,\
bitmap, bitmap_size, flags, _metadata) \
ASSERT_EQ(0, _test_mock_dirty_bitmaps(self->fd, hwpt_id, length, iova, \
page_size, bitmap, bitmap_size, \
flags, _metadata))
page_size, pte_size, bitmap, \
bitmap_size, flags, _metadata))

static int _test_cmd_create_access(int fd, unsigned int ioas_id,
__u32 *access_id, unsigned int flags)
Expand Down

0 comments on commit 407fc18

Please sign in to comment.