From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pf1-f200.google.com (mail-pf1-f200.google.com [209.85.210.200]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AD8D041D114 for ; Thu, 1 Oct 2026 22:46:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.200 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790894812; cv=none; b=L8umKJxYbSNXVlagKBm4rV05NJGABgVSuQgJ9mTfSE/dKg2ahSO83tlOsC5+TUrOfzUk3CV+H4/DS84OvhjCnI8eHFuFR6K4/uqAqeZO+P1fqToBvw8ZMoxcw05hOE6O9pdm4yo/bmfq+gc4jQ3EKfZISdfHzF7uAPi2PB3T5DY= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790894812; c=relaxed/simple; bh=+ZrMyvypAMHMJwmzcIZVzfzQU/AIsNYo+KFbpNJHSEc=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=hOUdS69AHCWUcRcnaqn2MoBzaZxDnjge41eJXqhsOq+aa52rlrxz1+D0PJjITQG09juHf7aFs1ElWDBDRnbAEC7mJk2No675Rs0Uhquyte+jQl9JwpFORv15aDBMxVGkC1Is6zwExGI9N3U4AVyxVFSuY9afZgHCfx/DIWP061I= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--praan.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=JxUvg7ef; arc=none smtp.client-ip=209.85.210.200 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--praan.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="JxUvg7ef" Received: by mail-pf1-f200.google.com with SMTP id d2e1a72fcca58-88b59692e0dso1229b3a.3 for ; Thu, 01 Oct 2026 15:46:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1790894809; x=1791499609; darn=vger.kernel.org; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:from:to:cc:subject:date:message-id:reply-to :content-type; bh=OkzBth2K8luOc5hRw7dwkQ++Ts6T4OZjlz0I1Txn4EY=; b=JxUvg7efOSdmr3iDHJYrn13xO1zANliVqmp5CXf38vIll6iQqU69LzAnitl+tdcLuT hUEnN6kRRwZFEBanaejvqYEVbdlmWRrj8sfAMvktijO4WsCPaaqJBj+mJDRC5L8PTeU2 pplAtafaugM9ZlYP8e63Ui3iCKUda+TieqhA1lNwKfIhegjN7J2Bi0NExbseeFjSd6xn 29sXM21HzHndGofd/VbtPdo5Djr6mvLGRT65KrLdIc4W0xGpZK9mMuolIttzpWTOlqh7 44A2YIyoOTDiSwC3+/3weiElklQRxx1G5T/Y17cr3BiA5LZdxoVYmz68f0EME5bSABUz i/6g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1790894809; x=1791499609; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=OkzBth2K8luOc5hRw7dwkQ++Ts6T4OZjlz0I1Txn4EY=; b=YJltSiwz8fki80kZq3nr/oaPvdjKbO6eI271nJKd/4Zr0KNEvcXFeiYeXg+xLu+EvZ wSm01Iomw9x8GiK8NeTCzo7eJH//SM8tbt7Z0QvY+uz4fOOgGIGkGWmWuTmAWNTsqOd9 w85f4VhgJIpEpZPMV3o9SBX6IrbUfiXOk5zCy0BMPliSP59L0bJEhNz5nARWa0tF6L5C Z8T0j6YU6gi/keN7GCPo063y5JYCycp7wDJ/wxmlB3mJrCp49ZSGI8CHJNNlPLBXBUi9 DjxZVHcTzkGXt3BnqoyA/sIbZJYVMmOYA8KjyW5SYz6wY1NJPOIwzOsMKlb5Jh+NsXWf KOXw== X-Forwarded-Encrypted: i=1; AKwUvBwhsKJQiAFOK0PIwiLhzcTuPnlQZdGpS9hM4WDWhpWPluPGmzz35EsA3nDK4v0XnS2xAcgq9y5+QZHLrA8=@vger.kernel.org X-Gm-Message-State: AFuF++n8uvxcL1P29Y8ssK7qKYvoCalnyR5cGAy7YlcfMxYrmZdhrlSJ 2iuk7JCPpYIWHY6IIl+Hw3TVbr10CFzpnhga/LXXZCQ3MZlHg8z8nRQHgtWIPPiAp/C+eIvfI8H cKg== X-Received: from pfbhu50.prod.google.com ([2002:a05:6a00:69b2:b0:887:3013:c8e7]) (user=praan job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a00:1888:b0:886:1119:2cbf with SMTP id d2e1a72fcca58-88af2687915mr858560b3a.5.1790894808625; Thu, 01 Oct 2026 15:46:48 -0700 (PDT) Date: Thu, 1 Oct 2026 22:45:31 +0000 In-Reply-To: <20261001224531.765278-1-praan@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20261001224531.765278-1-praan@google.com> X-Mailer: git-send-email 2.56.0.rc1.315.gc6ed9934b7-goog Message-ID: <20261001224531.765278-8-praan@google.com> Subject: [RFC PATCH 7/7] vfio/selftests: Add observability test for IO page table usage From: Pranjal Shrivastava To: Joerg Roedel , Will Deacon , Robin Murphy , Jason Gunthorpe , Kevin Tian , Alex Williamson , David Matlack , Jonathan Corbet , Shuah Khan , Randy Dunlap Cc: Mostafa Saleh , Daniel Mentz , Samiullah Khawaja , iommu@lists.linux.dev, kvm@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-doc@vger.kernel.org, Logan Odell , Pranjal Shrivastava , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Content-Type: text/plain; charset="UTF-8" Add a new selftest, vfio_nr_pages_test, to validate the iommu-nr-pages fdinfo metric across all IOMMU backends (Type 1 and IOMMUFD native/compat). The test performs a sparse mapping to force the underlying IOMMU driver to allocate a deep page table hierarchy. It then asserts that the nr_pages metric increases and proves the 'sticky' reclamation behavior by verifying the page count does not drop immediately upon unmapping. The test is skipped when the IOMMU driver does not account its page table memory, in which case the metric is not reported. Co-developed-by: Logan Odell Signed-off-by: Logan Odell Signed-off-by: Pranjal Shrivastava --- tools/testing/selftests/vfio/Makefile | 1 + .../selftests/vfio/vfio_nr_pages_test.c | 119 ++++++++++++++++++ 2 files changed, 120 insertions(+) create mode 100644 tools/testing/selftests/vfio/vfio_nr_pages_test.c diff --git a/tools/testing/selftests/vfio/Makefile b/tools/testing/selftests/vfio/Makefile index 2c32c48db509..140ef273e36b 100644 --- a/tools/testing/selftests/vfio/Makefile +++ b/tools/testing/selftests/vfio/Makefile @@ -13,6 +13,7 @@ TEST_GEN_PROGS += vfio_pci_device_test TEST_GEN_PROGS += vfio_pci_device_init_perf_test TEST_GEN_PROGS += vfio_pci_driver_test TEST_GEN_PROGS += vfio_pci_sriov_uapi_test +TEST_GEN_PROGS += vfio_nr_pages_test TEST_FILES += scripts/cleanup.sh TEST_FILES += scripts/lib.sh diff --git a/tools/testing/selftests/vfio/vfio_nr_pages_test.c b/tools/testing/selftests/vfio/vfio_nr_pages_test.c new file mode 100644 index 000000000000..aef6b1dd8e19 --- /dev/null +++ b/tools/testing/selftests/vfio/vfio_nr_pages_test.c @@ -0,0 +1,119 @@ +// SPDX-License-Identifier: GPL-2.0-only +#include +#include +#include +#include + +#include + +#include "../kselftest_harness.h" + +static const char *device_bdf; + +static long read_nr_pages(struct iommu *iommu) +{ + char path[256]; + char line[128]; + FILE *f; + long val = -1; + int fd = iommu->container_fd != -1 ? iommu->container_fd : iommu->iommufd; + + snprintf(path, sizeof(path), "/proc/self/fdinfo/%d", fd); + f = fopen(path, "r"); + if (!f) + return -1; + + while (fgets(line, sizeof(line), f)) { + if (sscanf(line, "iommu-nr-pages: %ld", &val) == 1) + break; + } + + fclose(f); + return val; +} + +FIXTURE(vfio_nr_pages_test) { + struct iommu *iommu; + struct vfio_pci_device *device; +}; + +FIXTURE_VARIANT(vfio_nr_pages_test) { + const char *iommu_mode; +}; + +#define FIXTURE_VARIANT_ADD_IOMMU_MODE(_name) \ +FIXTURE_VARIANT_ADD(vfio_nr_pages_test, _name) { \ + .iommu_mode = #_name, \ +} + +FIXTURE_VARIANT_ADD_ALL_IOMMU_MODES(); + +FIXTURE_SETUP(vfio_nr_pages_test) +{ + self->iommu = iommu_init(variant->iommu_mode); + if (!self->iommu) + SKIP(return, "IOMMU mode %s not supported", variant->iommu_mode); + + self->device = vfio_pci_device_init(device_bdf, self->iommu); + if (!self->device) { + iommu_cleanup(self->iommu); + SKIP(return, "Failed to initialize VFIO device"); + } +} + +FIXTURE_TEARDOWN(vfio_nr_pages_test) +{ + if (self->device) + vfio_pci_device_cleanup(self->device); + if (self->iommu) + iommu_cleanup(self->iommu); +} + +TEST_F(vfio_nr_pages_test, sparse_mapping_sticky_reclamation) +{ + long nr_pages_initial, nr_pages_mapped, nr_pages_final; + struct dma_region region1 = {0}; + struct dma_region region2 = {0}; + + if (!self->iommu || !self->device) + SKIP(return, "Fixture setup failed"); + + nr_pages_initial = read_nr_pages(self->iommu); + if (nr_pages_initial < 0) + SKIP(return, "iommu-nr-pages not reported by this IOMMU"); + + /* Map a page at start */ + region1.size = SZ_4K; + region1.vaddr = mmap_reserve(region1.size, region1.size, 0); + ASSERT_NE(MAP_FAILED, region1.vaddr); + region1.iova = 0x100000; + iommu_map(self->iommu, ®ion1); + + /* Map another page far away (1GB stride) to force deep page tables */ + region2.size = SZ_4K; + region2.vaddr = mmap_reserve(region2.size, region2.size, 0); + ASSERT_NE(MAP_FAILED, region2.vaddr); + region2.iova = 0x100000 + SZ_1G; + iommu_map(self->iommu, ®ion2); + + nr_pages_mapped = read_nr_pages(self->iommu); + ASSERT_GT(nr_pages_mapped, nr_pages_initial); + + /* Unmap both regions */ + iommu_unmap(self->iommu, ®ion1); + iommu_unmap(self->iommu, ®ion2); + + nr_pages_final = read_nr_pages(self->iommu); + + /* Page tables should remain allocated */ + ASSERT_EQ(nr_pages_final, nr_pages_mapped); + + munmap(region1.vaddr, region1.size); + munmap(region2.vaddr, region2.size); +} + +int main(int argc, char *argv[]) +{ + device_bdf = vfio_selftests_get_bdf(&argc, argv); + return test_harness_run(argc, argv); +} -- 2.56.0.rc1.315.gc6ed9934b7-goog