Files
linux/include/linux
Thomas Hellström a69d1ab971 mm: Fix a hmm_range_fault() livelock / starvation problem
If hmm_range_fault() fails a folio_trylock() in do_swap_page,
trying to acquire the lock of a device-private folio for migration,
to ram, the function will spin until it succeeds grabbing the lock.

However, if the process holding the lock is depending on a work
item to be completed, which is scheduled on the same CPU as the
spinning hmm_range_fault(), that work item might be starved and
we end up in a livelock / starvation situation which is never
resolved.

This can happen, for example if the process holding the
device-private folio lock is stuck in
   migrate_device_unmap()->lru_add_drain_all()
sinc lru_add_drain_all() requires a short work-item
to be run on all online cpus to complete.

A prerequisite for this to happen is:
a) Both zone device and system memory folios are considered in
   migrate_device_unmap(), so that there is a reason to call
   lru_add_drain_all() for a system memory folio while a
   folio lock is held on a zone device folio.
b) The zone device folio has an initial mapcount > 1 which causes
   at least one migration PTE entry insertion to be deferred to
   try_to_migrate(), which can happen after the call to
   lru_add_drain_all().
c) No or voluntary only preemption.

This all seems pretty unlikely to happen, but indeed is hit by
the "xe_exec_system_allocator" igt test.

Resolve this by waiting for the folio to be unlocked if the
folio_trylock() fails in do_swap_page().

Rename migration_entry_wait_on_locked() to
softleaf_entry_wait_unlock() and update its documentation to
indicate the new use-case.

Future code improvements might consider moving
the lru_add_drain_all() call in migrate_device_unmap() to be
called *after* all pages have migration entries inserted.
That would eliminate also b) above.

v2:
- Instead of a cond_resched() in hmm_range_fault(),
  eliminate the problem by waiting for the folio to be unlocked
  in do_swap_page() (Alistair Popple, Andrew Morton)
v3:
- Add a stub migration_entry_wait_on_locked() for the
  !CONFIG_MIGRATION case. (Kernel Test Robot)
v4:
- Rename migrate_entry_wait_on_locked() to
  softleaf_entry_wait_on_locked() and update docs (Alistair Popple)
v5:
- Add a WARN_ON_ONCE() for the !CONFIG_MIGRATION
  version of softleaf_entry_wait_on_locked().
- Modify wording around function names in the commit message
  (Andrew Morton)

Suggested-by: Alistair Popple <apopple@nvidia.com>
Fixes: 1afaeb8293 ("mm/migrate: Trylock device page in do_swap_page")
Cc: Ralph Campbell <rcampbell@nvidia.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Jason Gunthorpe <jgg@mellanox.com>
Cc: Jason Gunthorpe <jgg@ziepe.ca>
Cc: Leon Romanovsky <leon@kernel.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: John Hubbard <jhubbard@nvidia.com>
Cc: Alistair Popple <apopple@nvidia.com>
Cc: linux-mm@kvack.org
Cc: <dri-devel@lists.freedesktop.org>
Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Cc: <stable@vger.kernel.org> # v6.15+
Reviewed-by: John Hubbard <jhubbard@nvidia.com> #v3
Reviewed-by: Alistair Popple <apopple@nvidia.com>
Link: https://patch.msgid.link/20260210115653.92413-1-thomas.hellstrom@linux.intel.com
2026-02-11 11:03:01 +01:00
..
2025-10-22 07:54:33 +02:00
2025-11-11 10:01:30 +01:00
2025-11-18 22:26:02 +05:30
2025-10-13 11:27:52 +01:00
2025-09-05 15:06:03 +02:00
2025-07-21 18:18:51 +01:00
2025-04-21 10:27:59 +02:00
2025-12-12 12:36:44 -07:00
2025-04-29 15:58:38 -04:00
2025-07-31 11:28:03 -04:00
2025-12-04 07:19:26 -07:00
2025-12-09 23:29:42 -08:00
2025-09-24 02:48:05 -07:00
2025-11-21 11:21:31 +01:00
2025-10-27 09:56:27 -07:00
2025-05-21 13:39:45 +02:00
2025-08-14 10:37:33 -07:00
2025-11-04 12:36:57 +01:00
2025-04-11 18:58:10 -07:00
2025-09-23 11:13:22 +02:00
2025-10-22 07:55:00 +02:00
2025-11-01 12:44:49 -05:00
2025-12-13 20:04:32 +12:00
2025-12-16 00:57:29 -05:00
2025-08-21 13:58:07 +02:00
2025-07-16 14:28:21 +02:00
2025-05-22 11:07:05 +02:00
2025-10-29 18:28:29 -07:00
2025-09-13 17:32:44 -07:00
2025-08-29 13:39:53 -07:00
2025-11-04 12:36:02 +01:00
2025-08-02 12:06:10 -07:00
2025-10-22 07:53:15 +02:00
2025-09-23 11:13:22 +02:00
2025-06-11 11:57:14 -07:00
2025-07-02 17:18:01 +01:00
2025-10-24 21:39:27 +02:00
2025-07-17 06:01:16 -06:00
2025-11-23 12:30:40 +01:00
2025-11-20 13:43:59 -08:00
2025-07-09 22:41:56 -07:00
2025-09-17 15:58:29 -04:00
2025-06-17 18:18:46 -07:00
2025-11-04 19:10:33 -08:00
2025-09-23 13:28:20 -04:00
2025-11-05 23:58:20 +01:00
2025-11-03 17:41:17 +01:00
2025-11-11 10:01:30 +01:00
2025-05-21 16:46:37 +02:00
2025-09-13 16:55:07 -07:00
2025-06-19 14:28:24 +02:00
2025-06-19 14:28:24 +02:00
2025-08-24 11:41:11 -06:00
2025-07-01 12:29:29 +02:00
2025-10-30 18:35:26 +01:00
2025-10-24 21:39:27 +02:00
2025-10-31 10:16:23 +01:00
2025-11-27 14:24:30 -08:00
2025-05-03 12:02:04 +02:00
2025-11-18 17:52:54 +01:00
2025-05-11 17:54:09 -07:00
2025-05-06 11:11:45 -06:00
2025-11-11 13:18:56 +01:00
2025-11-28 09:21:18 -07:00
2025-08-28 13:14:50 +02:00
2025-11-27 14:22:31 +01:00
2025-11-20 17:57:40 -08:00
2025-11-03 17:41:18 +01:00
2025-11-03 19:27:41 -08:00
2025-08-17 12:46:25 +02:00
2025-11-25 10:07:42 +01:00
2025-09-09 10:27:01 -06:00
2025-11-03 17:41:18 +01:00
2025-10-01 07:24:55 -04:00
2025-11-24 15:08:54 -08:00
2025-07-17 11:26:56 +02:00
2025-11-12 09:38:34 +01:00