History

Merge tag 'for-linus-hmm' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma

Pull hmm updates from Jason Gunthorpe: "Ralph has been working on nouveau's use of hmm_range_fault() and migrate_vma() which resulted in this small series. It adds reporting of the page table order from hmm_range_fault() and some optimization of migrate_vma(): - Report the size of the page table mapping out of hmm_range_fault(). This makes it easier to establish a large/huge/etc mapping in the device's page table. - Allow devices to ignore the invalidations during migration in cases where the migration is not going to change pages. For instance migrating pages to a device does not require the device to invalidate pages already in the device. - Update nouveau and hmm_tests to use the above" * tag 'for-linus-hmm' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma: mm/hmm/test: use the new migration invalidation nouveau/svm: use the new migration invalidation mm/notifier: add migration invalidation type mm/migrate: add a flags parameter to migrate_vma nouveau: fix storing invalid ptes nouveau/hmm: support mapping large sysmem pages nouveau: fix mapping 2MB sysmem pages nouveau/hmm: fault one page at a time mm/hmm: add tests for hmm_pfn_to_map_order() mm/hmm: provide the page mapping order in hmm_range_fault()

Linus Torvalds committed 6 years ago

Commit fffe3ae2 parents 8f7be62 7d17e8314 files · +410 −200Browse files

Showing the changes to include/linux (3 of 14 files). Show all

Unified · Split

3 files
  1. include/linux/hmm.h +22 −2
  2. include/linux/migrate.h +12 −4
  3. include/linux/mmu_notifier.h +6 −0
include/linux/hmm.h+22−2
@@ -37,16 +37,17 @@ · 36 unmodified lines
3737 * will fail. Must be combined with HMM_PFN_REQ_FAULT.
3838 */
3939 enum hmm_pfn_flags {
40− /* Output flags */
40+ /* Output fields and flags */
4141 HMM_PFN_VALID = 1UL << (BITS_PER_LONG - 1),
4242 HMM_PFN_WRITE = 1UL << (BITS_PER_LONG - 2),
4343 HMM_PFN_ERROR = 1UL << (BITS_PER_LONG - 3),
44+ HMM_PFN_ORDER_SHIFT = (BITS_PER_LONG - 8),
4445
4546 /* Input flags */
4647 HMM_PFN_REQ_FAULT = HMM_PFN_VALID,
4748 HMM_PFN_REQ_WRITE = HMM_PFN_WRITE,
4849
49− HMM_PFN_FLAGS = HMM_PFN_VALID | HMM_PFN_WRITE | HMM_PFN_ERROR,
50+ HMM_PFN_FLAGS = 0xFFUL << HMM_PFN_ORDER_SHIFT,
5051 };
5152
5253 /*
@@ -61,6 +62,25 @@ static inline struct page *hmm_pfn_to_page(unsigned long hmm_pfn) · 8 unmodified lines
6162 return pfn_to_page(hmm_pfn & ~HMM_PFN_FLAGS);
6263 }
6364
65+/*
66+ * hmm_pfn_to_map_order() - return the CPU mapping size order
67+ *
68+ * This is optionally useful to optimize processing of the pfn result
69+ * array. It indicates that the page starts at the order aligned VA and is
70+ * 1<<order bytes long. Every pfn within an high order page will have the
71+ * same pfn flags, both access protections and the map_order. The caller must
72+ * be careful with edge cases as the start and end VA of the given page may
73+ * extend past the range used with hmm_range_fault().
74+ *
75+ * This must be called under the caller 'user_lock' after a successful
76+ * mmu_interval_read_begin(). The caller must have tested for HMM_PFN_VALID
77+ * already.
78+ */
79+static inline unsigned int hmm_pfn_to_map_order(unsigned long hmm_pfn)
80+{
81+ return (hmm_pfn >> HMM_PFN_ORDER_SHIFT) & 0x1F;
82+}
83+
6484 /*
6585 * struct hmm_range - track invalidation lock on virtual address range
6686 *
include/linux/migrate.h+12−4
@@ -180,6 +180,11 @@ static inline unsigned long migrate_pfn(unsigned long pfn) · 179 unmodified lines
180180 return (pfn << MIGRATE_PFN_SHIFT) | MIGRATE_PFN_VALID;
181181 }
182182
183+enum migrate_vma_direction {
184+ MIGRATE_VMA_SELECT_SYSTEM = 1 << 0,
185+ MIGRATE_VMA_SELECT_DEVICE_PRIVATE = 1 << 1,
186+};
187+
183188 struct migrate_vma {
184189 struct vm_area_struct *vma;
185190 /*
@@ -199,11 +204,14 @@ struct migrate_vma { · 13 unmodified lines
199204
200205 /*
201206 * Set to the owner value also stored in page->pgmap->owner for
202− * migrating out of device private memory. If set only device
203− * private pages with this owner are migrated. If not set
204− * device private pages are not migrated at all.
207+ * migrating out of device private memory. The flags also need to
208+ * 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.
205212 */
206− void *src_owner;
213+ void *pgmap_owner;
214+ unsigned long flags;
207215 };
208216
209217 int migrate_vma_setup(struct migrate_vma *args);
include/linux/mmu_notifier.h+6−0
@@ -38,6 +38,10 @@ struct mmu_interval_notifier; · 37 unmodified lines
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 { · 2 unmodified lines
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 { · 212 unmodified lines
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)