From: Aaron Lewis <aaronlewis@google.com>
To: kvm@vger.kernel.org
Cc: alex@shazbot.org, dmatlack@google.com, jgg@nvidia.com,
Aaron Lewis <aaronlewis@google.com>
Subject: [PATCH 4/4] vfio: selftests: Allow the flag MAP_POPULATE to be set on the cmdline
Date: Wed, 1 Jul 2026 20:33:11 +0000 [thread overview]
Message-ID: <20260701203311.326798-5-aaronlewis@google.com> (raw)
In-Reply-To: <20260701203311.326798-1-aaronlewis@google.com>
Add a command-line option to vfio_dma_mapping_perf_test to set the
MAP_POPULATE flag during mmap(). This ensures consistent and accurate DMA
mapping latency measurements by forcing page prefaulting to occur during
the mmap() phase, rather than during the DMA mapping ioctl.
For example, mapping a 32G region without the -p (MAP_POPULATE) flag
results in:
$ ./vfio_dma_mapping_perf_test -b 32G -a "-v vfio_type1_iommu_memfd_hugetlb_1gb"
Completed mmap() for memfd in 0.00ms
Mapped HVA 0x7f1840000000 (size 32G) at IOVA 0x800000000 in 2887.56ms
Here, the mmap() call completes instantly, but the ioctl to map the DMA
region incurs the ~3s cost of prefaulting the pages.
Running the same test with the -p flag results in:
$ ./vfio_dma_mapping_perf_test -p -b 32G -a "-v vfio_type1_iommu_memfd_hugetlb_1gb"
Completed mmap() for memfd in 2887.41ms
Mapped HVA 0x7f8000000000 (size 32G) at IOVA 0x800000000 in 11.51ms
By shifting the prefaulting overhead to mmap(), the actual DMA mapping
latency is isolated and accurately reported as 11.51ms.
With user-defined mapping sizes and prefaulting in place, this test now
clearly demonstrates the difference in mapping speeds between VFIO's Type 1
IOMMU and IOMMUFD (i.e., IOMMU_IOAS_MAP_FILE).
Running the same configuration with the "iommufd_memfd_hugetlb_1gb" variant
highlights this difference:
$ ./vfio_dma_mapping_perf_test -p -b 32G -a "-v iommufd_memfd_hugetlb_1gb"
Mapped HVA 0x7f4fc0000000 (size 32G) at IOVA 0x800000000 in 0.11ms
The DMA mapping time drops dramatically from 11.51ms to 0.11ms.
Signed-off-by: Aaron Lewis <aaronlewis@google.com>
---
.../vfio/vfio_dma_mapping_perf_test.c | 20 +++++++++++++++----
1 file changed, 16 insertions(+), 4 deletions(-)
diff --git a/tools/testing/selftests/vfio/vfio_dma_mapping_perf_test.c b/tools/testing/selftests/vfio/vfio_dma_mapping_perf_test.c
index 6c025e9c4420..8032f51c1a3e 100644
--- a/tools/testing/selftests/vfio/vfio_dma_mapping_perf_test.c
+++ b/tools/testing/selftests/vfio/vfio_dma_mapping_perf_test.c
@@ -22,6 +22,7 @@ static const char *device_bdf;
struct test_params {
u64 size;
+ int mmap_flags;
};
struct test_params test_params;
@@ -88,7 +89,7 @@ FIXTURE_TEARDOWN(vfio_dma_mapping_perf_test)
TEST_F(vfio_dma_mapping_perf_test, dma_map_unmap)
{
const u64 size = test_params.size;
- const int flags = variant->mmap_flags;
+ const int flags = variant->mmap_flags | test_params.mmap_flags;
struct dma_region region;
struct timespec start;
u64 unmapped;
@@ -217,7 +218,9 @@ TEST_F(vfio_dma_mapping_perf_memfd_test, dma_map_unmap_from_file)
u64 unmapped;
int rc, fd;
- region.vaddr = setup_memfd(&fd, size, variant->mmap_flags, variant->memfd_flags);
+ region.vaddr = setup_memfd(&fd, size,
+ variant->mmap_flags | test_params.mmap_flags,
+ variant->memfd_flags);
ASSERT_NE(region.vaddr, MAP_FAILED);
region.iova = iova_allocator_alloc(self->iova_allocator, size);
@@ -288,11 +291,16 @@ size_t parse_size(const char *size)
static void help(char *name)
{
puts("");
- printf("usage: %s [-h] [-b bytes] [-a \"test harness args\"]\n", name);
+ printf("usage: %s [-h|-p] [-b bytes] [-a \"test harness args\"]\n", name);
puts("");
printf(" -h: Display this help message.\n"
" -b: Specify the size of the DMA region to be mapped\n"
" and unmapped. e.g. 16M or 8G, (default: 1G)\n"
+ " -p: Append 'MAP_POPULATE' to the mmap() flags to avoid\n"
+ " prefaulting while mapping DMA regions. Instead, any\n"
+ " and all prefaulting needed will happen during the\n"
+ " mmap() call. This will make mapping DMA regions\n"
+ " more consistent.\n"
" -a: Args that are forwarded to the test harness,\n"
" e.g. -a \"-t dma_map_unmap_from_file\"\n");
}
@@ -320,9 +328,10 @@ static void setup_test(struct harness_args *args, int argc, char *argv[])
test_params = (struct test_params) {
.size = SZ_1G,
+ .mmap_flags = 0,
};
- while ((opt = getopt(argc, argv, "a:b:h")) != -1) {
+ while ((opt = getopt(argc, argv, "a:b:ph")) != -1) {
switch (opt) {
case 'a':
populate_harness_args(args, argv[0], optarg);
@@ -330,6 +339,9 @@ static void setup_test(struct harness_args *args, int argc, char *argv[])
case 'b':
test_params.size = parse_size(optarg);
break;
+ case 'p':
+ test_params.mmap_flags = MAP_POPULATE;
+ break;
case 'h':
default:
help(argv[0]);
--
2.55.0.rc0.799.gd6f94ed593-goog
prev parent reply other threads:[~2026-07-01 20:33 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-01 20:33 [PATCH 0/4] Introduce vfio_dma_mapping_perf_test Aaron Lewis
2026-07-01 20:33 ` [PATCH 1/4] vfio: selftests: " Aaron Lewis
2026-07-01 20:44 ` sashiko-bot
2026-07-01 20:33 ` [PATCH 2/4] vfio: selftests: Add memfd test to vfio_dma_mapping_perf_test Aaron Lewis
2026-07-01 20:43 ` sashiko-bot
2026-07-01 20:33 ` [PATCH 3/4] vfio: selftests: Allow a size for vfio_dma_mapping_perf_test Aaron Lewis
2026-07-01 20:44 ` sashiko-bot
2026-07-01 20:33 ` Aaron Lewis [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260701203311.326798-5-aaronlewis@google.com \
--to=aaronlewis@google.com \
--cc=alex@shazbot.org \
--cc=dmatlack@google.com \
--cc=jgg@nvidia.com \
--cc=kvm@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.