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()
This commit is contained in:
@@ -881,8 +881,9 @@ TEST_F(hmm, migrate)
|
||||
}
|
||||
|
||||
/*
|
||||
* Migrate anonymous memory to device private memory and fault it back to system
|
||||
* memory.
|
||||
* Migrate anonymous memory to device private memory and fault some of it back
|
||||
* to system memory, then try migrating the resulting mix of system and device
|
||||
* private memory to the device.
|
||||
*/
|
||||
TEST_F(hmm, migrate_fault)
|
||||
{
|
||||
@@ -924,8 +925,17 @@ TEST_F(hmm, migrate_fault)
|
||||
for (i = 0, ptr = buffer->mirror; i < size / sizeof(*ptr); ++i)
|
||||
ASSERT_EQ(ptr[i], i);
|
||||
|
||||
/* Fault pages back to system memory and check them. */
|
||||
for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
|
||||
/* Fault half the pages back to system memory and check them. */
|
||||
for (i = 0, ptr = buffer->ptr; i < size / (2 * sizeof(*ptr)); ++i)
|
||||
ASSERT_EQ(ptr[i], i);
|
||||
|
||||
/* Migrate memory to the device again. */
|
||||
ret = hmm_dmirror_cmd(self->fd, HMM_DMIRROR_MIGRATE, buffer, npages);
|
||||
ASSERT_EQ(ret, 0);
|
||||
ASSERT_EQ(buffer->cpages, npages);
|
||||
|
||||
/* Check what the device read. */
|
||||
for (i = 0, ptr = buffer->mirror; i < size / sizeof(*ptr); ++i)
|
||||
ASSERT_EQ(ptr[i], i);
|
||||
|
||||
hmm_buffer_free(buffer);
|
||||
@@ -1291,6 +1301,82 @@ TEST_F(hmm2, snapshot)
|
||||
hmm_buffer_free(buffer);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test the hmm_range_fault() HMM_PFN_PMD flag for large pages that
|
||||
* should be mapped by a large page table entry.
|
||||
*/
|
||||
TEST_F(hmm, compound)
|
||||
{
|
||||
struct hmm_buffer *buffer;
|
||||
unsigned long npages;
|
||||
unsigned long size;
|
||||
int *ptr;
|
||||
unsigned char *m;
|
||||
int ret;
|
||||
long pagesizes[4];
|
||||
int n, idx;
|
||||
unsigned long i;
|
||||
|
||||
/* Skip test if we can't allocate a hugetlbfs page. */
|
||||
|
||||
n = gethugepagesizes(pagesizes, 4);
|
||||
if (n <= 0)
|
||||
return;
|
||||
for (idx = 0; --n > 0; ) {
|
||||
if (pagesizes[n] < pagesizes[idx])
|
||||
idx = n;
|
||||
}
|
||||
size = ALIGN(TWOMEG, pagesizes[idx]);
|
||||
npages = size >> self->page_shift;
|
||||
|
||||
buffer = malloc(sizeof(*buffer));
|
||||
ASSERT_NE(buffer, NULL);
|
||||
|
||||
buffer->ptr = get_hugepage_region(size, GHR_STRICT);
|
||||
if (buffer->ptr == NULL) {
|
||||
free(buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
buffer->size = size;
|
||||
buffer->mirror = malloc(npages);
|
||||
ASSERT_NE(buffer->mirror, NULL);
|
||||
|
||||
/* Initialize the pages the device will snapshot in buffer->ptr. */
|
||||
for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
|
||||
ptr[i] = i;
|
||||
|
||||
/* Simulate a device snapshotting CPU pagetables. */
|
||||
ret = hmm_dmirror_cmd(self->fd, HMM_DMIRROR_SNAPSHOT, buffer, npages);
|
||||
ASSERT_EQ(ret, 0);
|
||||
ASSERT_EQ(buffer->cpages, npages);
|
||||
|
||||
/* Check what the device saw. */
|
||||
m = buffer->mirror;
|
||||
for (i = 0; i < npages; ++i)
|
||||
ASSERT_EQ(m[i], HMM_DMIRROR_PROT_WRITE |
|
||||
HMM_DMIRROR_PROT_PMD);
|
||||
|
||||
/* Make the region read-only. */
|
||||
ret = mprotect(buffer->ptr, size, PROT_READ);
|
||||
ASSERT_EQ(ret, 0);
|
||||
|
||||
/* Simulate a device snapshotting CPU pagetables. */
|
||||
ret = hmm_dmirror_cmd(self->fd, HMM_DMIRROR_SNAPSHOT, buffer, npages);
|
||||
ASSERT_EQ(ret, 0);
|
||||
ASSERT_EQ(buffer->cpages, npages);
|
||||
|
||||
/* Check what the device saw. */
|
||||
m = buffer->mirror;
|
||||
for (i = 0; i < npages; ++i)
|
||||
ASSERT_EQ(m[i], HMM_DMIRROR_PROT_READ |
|
||||
HMM_DMIRROR_PROT_PMD);
|
||||
|
||||
free_hugepage_region(buffer->ptr);
|
||||
buffer->ptr = NULL;
|
||||
hmm_buffer_free(buffer);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test two devices reading the same memory (double mapped).
|
||||
*/
|
||||
|
Reference in New Issue
Block a user