All of lore.kernel.org
 help / color / mirror / Atom feed
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 2/2] iommufd: Periodically reschedule when unmapping
Date: Tue, 14 Jul 2026 21:03:03 +0000	[thread overview]
Message-ID: <20260714210303.3967981-3-aaronlewis@google.com> (raw)
In-Reply-To: <20260714210303.3967981-1-aaronlewis@google.com>

Unmapping large DMA regions can be slow and cause a CPU core to be
unresponsive for a long period of time, leading to kernel scheduler
warnings.

For example:

[ 1389.148910] vfio-pci 0007:01:01.3: resetting
[ 1389.252814] vfio-pci 0007:01:01.3: reset done
[ 1392.943771] sched: CPU 49 need_resched set for > 100000053 ns (100 ticks) without schedule
[ 1392.943776] CPU: 49 UID: 0 PID: 32912 Comm: vfio_dma_mappin Kdump: loaded Not tainted 7.1.0-smp-DEV #1 PREEMPTLAZY
[ 1392.943780] Call trace:
[ 1392.943796]  resched_latency_warn+0x7c/0x88
[ 1392.943800]  sched_tick+0x18c/0x208
[ 1392.943804]  update_process_times+0xa8/0xd8
[ 1392.943808]  tick_nohz_handler+0x120/0x1c8
[ 1392.943810]  __hrtimer_run_queues+0x124/0x3a0
[ 1392.943833]  arm_lpae_iova_to_phys+0x80/0xf0 (P)
[ 1392.943835]  arm_smmu_iova_to_phys+0x24/0x38
[ 1392.943837]  iommu_iova_to_phys+0x38/0x58
[ 1392.943839]  batch_from_domain+0x16c/0x218
[ 1392.943840]  __iopt_area_unfill_domain+0x2f0/0x5d8
[ 1392.943841]  iopt_area_unfill_domains+0x9c/0x1c8
[ 1392.943842]  iopt_unmap_iova_range+0xec/0x218
[ 1392.943844]  iopt_unmap_iova+0x38/0x50
[ 1392.943846]  iommufd_ioas_unmap+0xac/0x1f8
[ 1392.943847]  iommufd_fops_ioctl+0x200/0x348

Note that in order for this warning to fire, the kernel must be built
without preemption, or... for testing, the code in batch_from_domain()
can explicitly disable preemption.

This warning was produced on ARM using the VFIO selftest
vfio_dma_mapping_perf_test:

  ./vfio_dma_mapping_perf_test -p -b 256G -a "-v iommufd_anonymous_hugetlb_1gb"

To profile the unmap flow, bpftrace was used with the tooling
described at:
https://lore.kernel.org/kvm/20260630141152.3757722-2-aaronlewis@google.com/

The results show:

  iommufd_ioas_unmap, thread_time = 1086.52ms, count = 1
    __iopt_area_unfill_domain, thread_time = 1086.51ms, count = 1
      batch_from_domain, thread_time = 1086.48ms, count = 1

This shows that the execution time is spent entirely inside
batch_from_domain(). Furthermore, the function is entered only once.
Therefore, to avoid the scheduler warning and allow the core to remain
responsive, add a cond_resched() call to the loop in
batch_from_domain(). Also, limit the cond_resched() call to once
per 1GB to rate limit it.

Additional context on what consumes time within the inner loop can be
seen in this sample perf profile:

  22.96%  [vfio_dma_mapping_perf_test] ([vfio_dma_mapping_perf_test])
  22.96%  vfs_ioctl (ioctl.c) Inlined
  22.96%  iommufd_fops_ioctl (main.c)
  19.38%  iommufd_ioas_unmap (ioas.c)
  19.38%  iopt_unmap_iova (io_pagetable.c)
  19.38%  iopt_unmap_iova_range (io_pagetable.c)
  19.38%  iopt_area_unfill_domains (pages.c)
  19.38%  iopt_area_unfill_domain (pages.c) Inlined
  19.38%  __iopt_area_unfill_domain (pages.c)
  19.38%  iopt_area_unpin_domain (pages.c) Inlined
  18.84%  batch_from_domain (pages.c)
  15.06%  iommu_iova_to_phys (iommu.c)
  14.27%  arm_smmu_iova_to_phys (arm-smmu-v3.c)
  13.29%  arm_lpae_iova_to_phys (io-pgtable-arm.c)
  10.60%  __arm_lpae_iopte_walk (io-pgtable-arm.c)
   7.70%  io_pgtable_visit (io-pgtable-arm.c) Inlined
   4.71%  __arm_lpae_iopte_walk (io-pgtable-arm.c)
   2.31%  io_pgtable_visit (io-pgtable-arm.c) Inlined

Signed-off-by: Aaron Lewis <aaronlewis@google.com>
---
 drivers/iommu/iommufd/pages.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/iommu/iommufd/pages.c b/drivers/iommu/iommufd/pages.c
index 9bdb2945afe1..e478771c0ccf 100644
--- a/drivers/iommu/iommufd/pages.c
+++ b/drivers/iommu/iommufd/pages.c
@@ -412,6 +412,7 @@ static void batch_from_domain(struct pfn_batch *batch,
 	unsigned int page_offset = 0;
 	unsigned long iova;
 	phys_addr_t phys;
+	int i = 0;
 
 	iova = iopt_area_index_to_iova(area, start_index);
 	if (start_index == iopt_area_index(area))
@@ -428,6 +429,9 @@ static void batch_from_domain(struct pfn_batch *batch,
 		iova += PAGE_SIZE - page_offset;
 		page_offset = 0;
 		start_index++;
+
+		if ((++i % BIT(PUD_ORDER)) == 0)
+			cond_resched();
 	}
 }
 
-- 
2.55.0.141.g00534a21ce-goog


  parent reply	other threads:[~2026-07-14 21:03 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-14 21:03 [PATCH 0/2] vfio/iommufd: Prevent scheduler warnings when unmapping large regions Aaron Lewis
2026-07-14 21:03 ` [PATCH 1/2] vfio/type1: Periodically try rescheduling when unmapping Aaron Lewis
2026-07-14 21:15   ` sashiko-bot
2026-07-14 21:03 ` Aaron Lewis [this message]
2026-07-14 21:34   ` [PATCH 2/2] iommufd: Periodically reschedule " sashiko-bot

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=20260714210303.3967981-3-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.