Skip to content

Commit 998427b

Browse files
Ralph Campbelljgunthorpe
authored andcommitted
mm/notifier: add migration invalidation type
Currently migrate_vma_setup() calls mmu_notifier_invalidate_range_start() which flushes all device private page mappings whether or not a page is being migrated to/from device private memory. In order to not disrupt device mappings that are not being migrated, shift the responsibility for clearing device private mappings to the device driver and leave CPU page table unmapping handled by migrate_vma_setup(). To support this, the caller of migrate_vma_setup() should always set struct migrate_vma::pgmap_owner to a non NULL value that matches the device private page->pgmap->owner. This value is then passed to the struct mmu_notifier_range with a new event type which the driver's invalidation function can use to avoid device MMU invalidations. Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Ralph Campbell <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]>
1 parent 5143192 commit 998427b

File tree

3 files changed

+16
-1
lines changed

3 files changed

+16
-1
lines changed

include/linux/migrate.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,9 @@ struct migrate_vma {
206206
* Set to the owner value also stored in page->pgmap->owner for
207207
* migrating out of device private memory. The flags also need to
208208
* be set to MIGRATE_VMA_SELECT_DEVICE_PRIVATE.
209+
* The caller should always set this field when using mmu notifier
210+
* callbacks to avoid device MMU invalidations for device private
211+
* pages that are not being migrated.
209212
*/
210213
void *pgmap_owner;
211214
unsigned long flags;

include/linux/mmu_notifier.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ struct mmu_interval_notifier;
3838
*
3939
* @MMU_NOTIFY_RELEASE: used during mmu_interval_notifier invalidate to signal
4040
* that the mm refcount is zero and the range is no longer accessible.
41+
*
42+
* @MMU_NOTIFY_MIGRATE: used during migrate_vma_collect() invalidate to signal
43+
* a device driver to possibly ignore the invalidation if the
44+
* migrate_pgmap_owner field matches the driver's device private pgmap owner.
4145
*/
4246
enum mmu_notifier_event {
4347
MMU_NOTIFY_UNMAP = 0,
@@ -46,6 +50,7 @@ enum mmu_notifier_event {
4650
MMU_NOTIFY_PROTECTION_PAGE,
4751
MMU_NOTIFY_SOFT_DIRTY,
4852
MMU_NOTIFY_RELEASE,
53+
MMU_NOTIFY_MIGRATE,
4954
};
5055

5156
#define MMU_NOTIFIER_RANGE_BLOCKABLE (1 << 0)
@@ -264,6 +269,7 @@ struct mmu_notifier_range {
264269
unsigned long end;
265270
unsigned flags;
266271
enum mmu_notifier_event event;
272+
void *migrate_pgmap_owner;
267273
};
268274

269275
static inline int mm_has_notifiers(struct mm_struct *mm)

mm/migrate.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2392,8 +2392,14 @@ static void migrate_vma_collect(struct migrate_vma *migrate)
23922392
{
23932393
struct mmu_notifier_range range;
23942394

2395-
mmu_notifier_range_init(&range, MMU_NOTIFY_CLEAR, 0, NULL,
2395+
/*
2396+
* Note that the pgmap_owner is passed to the mmu notifier callback so
2397+
* that the registered device driver can skip invalidating device
2398+
* private page mappings that won't be migrated.
2399+
*/
2400+
mmu_notifier_range_init(&range, MMU_NOTIFY_MIGRATE, 0, migrate->vma,
23962401
migrate->vma->vm_mm, migrate->start, migrate->end);
2402+
range.migrate_pgmap_owner = migrate->pgmap_owner;
23972403
mmu_notifier_invalidate_range_start(&range);
23982404

23992405
walk_page_range(migrate->vma->vm_mm, migrate->start, migrate->end,

0 commit comments

Comments
 (0)