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
37 * will fail. Must be combined with HMM_PFN_REQ_FAULT.37 * will fail. Must be combined with HMM_PFN_REQ_FAULT.
38 */38 */
39enum hmm_pfn_flags {39enum hmm_pfn_flags {
40 /* Output flags */40 /* Output fields and flags */
41 HMM_PFN_VALID = 1UL << (BITS_PER_LONG - 1),41 HMM_PFN_VALID = 1UL << (BITS_PER_LONG - 1),
42 HMM_PFN_WRITE = 1UL << (BITS_PER_LONG - 2),42 HMM_PFN_WRITE = 1UL << (BITS_PER_LONG - 2),
43 HMM_PFN_ERROR = 1UL << (BITS_PER_LONG - 3),43 HMM_PFN_ERROR = 1UL << (BITS_PER_LONG - 3),
44 HMM_PFN_ORDER_SHIFT = (BITS_PER_LONG - 8),
44 45
45 /* Input flags */46 /* Input flags */
46 HMM_PFN_REQ_FAULT = HMM_PFN_VALID,47 HMM_PFN_REQ_FAULT = HMM_PFN_VALID,
47 HMM_PFN_REQ_WRITE = HMM_PFN_WRITE,48 HMM_PFN_REQ_WRITE = HMM_PFN_WRITE,
48 49
49 HMM_PFN_FLAGS = HMM_PFN_VALID | HMM_PFN_WRITE | HMM_PFN_ERROR,50 HMM_PFN_FLAGS = 0xFFUL << HMM_PFN_ORDER_SHIFT,
50};51};
51 52
52/*53/*
@@ -61,6 +62,25 @@ static inline struct page *hmm_pfn_to_page(unsigned long hmm_pfn) · 8 unmodified lines
61 return pfn_to_page(hmm_pfn & ~HMM_PFN_FLAGS);62 return pfn_to_page(hmm_pfn & ~HMM_PFN_FLAGS);
62}63}
63 64
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 */
79static inline unsigned int hmm_pfn_to_map_order(unsigned long hmm_pfn)
80{
81 return (hmm_pfn >> HMM_PFN_ORDER_SHIFT) & 0x1F;
82}
83
64/*84/*
65 * struct hmm_range - track invalidation lock on virtual address range85 * struct hmm_range - track invalidation lock on virtual address range
66 *86 *
include/linux/migrate.h+12−4
@@ -180,6 +180,11 @@ static inline unsigned long migrate_pfn(unsigned long pfn) · 179 unmodified lines
180 return (pfn << MIGRATE_PFN_SHIFT) | MIGRATE_PFN_VALID;180 return (pfn << MIGRATE_PFN_SHIFT) | MIGRATE_PFN_VALID;
181}181}
182 182
183enum migrate_vma_direction {
184 MIGRATE_VMA_SELECT_SYSTEM = 1 << 0,
185 MIGRATE_VMA_SELECT_DEVICE_PRIVATE = 1 << 1,
186};
187
183struct migrate_vma {188struct migrate_vma {
184 struct vm_area_struct *vma;189 struct vm_area_struct *vma;
185 /*190 /*
@@ -199,11 +204,14 @@ struct migrate_vma { · 13 unmodified lines
199 204
200 /*205 /*
201 * Set to the owner value also stored in page->pgmap->owner for206 * Set to the owner value also stored in page->pgmap->owner for
202 * migrating out of device private memory. If set only device207 * migrating out of device private memory. The flags also need to
203 * private pages with this owner are migrated. If not set208 * be set to MIGRATE_VMA_SELECT_DEVICE_PRIVATE.
204 * device private pages are not migrated at all.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.
205 */212 */
206 void *src_owner;213 void *pgmap_owner;
214 unsigned long flags;
207};215};
208 216
209int migrate_vma_setup(struct migrate_vma *args);217int 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
38 *38 *
39 * @MMU_NOTIFY_RELEASE: used during mmu_interval_notifier invalidate to signal39 * @MMU_NOTIFY_RELEASE: used during mmu_interval_notifier invalidate to signal
40 * that the mm refcount is zero and the range is no longer accessible.40 * 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.
41 */45 */
42enum mmu_notifier_event {46enum mmu_notifier_event {
43 MMU_NOTIFY_UNMAP = 0,47 MMU_NOTIFY_UNMAP = 0,
@@ -46,6 +50,7 @@ enum mmu_notifier_event { · 2 unmodified lines
46 MMU_NOTIFY_PROTECTION_PAGE,50 MMU_NOTIFY_PROTECTION_PAGE,
47 MMU_NOTIFY_SOFT_DIRTY,51 MMU_NOTIFY_SOFT_DIRTY,
48 MMU_NOTIFY_RELEASE,52 MMU_NOTIFY_RELEASE,
53 MMU_NOTIFY_MIGRATE,
49};54};
50 55
51#define MMU_NOTIFIER_RANGE_BLOCKABLE (1 << 0)56#define MMU_NOTIFIER_RANGE_BLOCKABLE (1 << 0)
@@ -264,6 +269,7 @@ struct mmu_notifier_range { · 212 unmodified lines
264 unsigned long end;269 unsigned long end;
265 unsigned flags;270 unsigned flags;
266 enum mmu_notifier_event event;271 enum mmu_notifier_event event;
272 void *migrate_pgmap_owner;
267};273};
268 274
269static inline int mm_has_notifiers(struct mm_struct *mm)275static inline int mm_has_notifiers(struct mm_struct *mm)