mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 14:11:52 +00:00
selftests: add a MREMAP_DONTUNMAP selftest for shmem
This test extends the current mremap tests to validate that the MREMAP_DONTUNMAP operation can be performed on shmem mappings. Link: https://lkml.kernel.org/r/20210323182520.2712101-3-bgeffon@google.com Signed-off-by: Brian Geffon <bgeffon@google.com> Cc: Axel Rasmussen <axelrasmussen@google.com> Cc: Lokesh Gidra <lokeshgidra@google.com> Cc: Mike Rapoport <rppt@linux.vnet.ibm.com> Cc: Peter Xu <peterx@redhat.com> Cc: Hugh Dickins <hughd@google.com> Cc: "Michael S . Tsirkin" <mst@redhat.com> Cc: Brian Geffon <bgeffon@google.com> Cc: Andy Lutomirski <luto@amacapital.net> Cc: Vlastimil Babka <vbabka@suse.cz> Cc: Andrea Arcangeli <aarcange@redhat.com> Cc: Sonny Rao <sonnyrao@google.com> Cc: Minchan Kim <minchan@kernel.org> Cc: "Kirill A . Shutemov" <kirill@shutemov.name> Cc: Dmitry Safonov <dima@arista.com> Cc: Michael Kerrisk <mtk.manpages@gmail.com> Cc: Alejandro Colomar <alx.manpages@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
14d071134c
commit
8593100444
@ -127,6 +127,57 @@ static void mremap_dontunmap_simple()
|
||||
"unable to unmap source mapping");
|
||||
}
|
||||
|
||||
// This test validates that MREMAP_DONTUNMAP on a shared mapping works as expected.
|
||||
static void mremap_dontunmap_simple_shmem()
|
||||
{
|
||||
unsigned long num_pages = 5;
|
||||
|
||||
int mem_fd = memfd_create("memfd", MFD_CLOEXEC);
|
||||
BUG_ON(mem_fd < 0, "memfd_create");
|
||||
|
||||
BUG_ON(ftruncate(mem_fd, num_pages * page_size) < 0,
|
||||
"ftruncate");
|
||||
|
||||
void *source_mapping =
|
||||
mmap(NULL, num_pages * page_size, PROT_READ | PROT_WRITE,
|
||||
MAP_FILE | MAP_SHARED, mem_fd, 0);
|
||||
BUG_ON(source_mapping == MAP_FAILED, "mmap");
|
||||
|
||||
BUG_ON(close(mem_fd) < 0, "close");
|
||||
|
||||
memset(source_mapping, 'a', num_pages * page_size);
|
||||
|
||||
// Try to just move the whole mapping anywhere (not fixed).
|
||||
void *dest_mapping =
|
||||
mremap(source_mapping, num_pages * page_size, num_pages * page_size,
|
||||
MREMAP_DONTUNMAP | MREMAP_MAYMOVE, NULL);
|
||||
if (dest_mapping == MAP_FAILED && errno == EINVAL) {
|
||||
// Old kernel which doesn't support MREMAP_DONTUNMAP on shmem.
|
||||
BUG_ON(munmap(source_mapping, num_pages * page_size) == -1,
|
||||
"unable to unmap source mapping");
|
||||
return;
|
||||
}
|
||||
|
||||
BUG_ON(dest_mapping == MAP_FAILED, "mremap");
|
||||
|
||||
// Validate that the pages have been moved, we know they were moved if
|
||||
// the dest_mapping contains a's.
|
||||
BUG_ON(check_region_contains_byte
|
||||
(dest_mapping, num_pages * page_size, 'a') != 0,
|
||||
"pages did not migrate");
|
||||
|
||||
// Because the region is backed by shmem, we will actually see the same
|
||||
// memory at the source location still.
|
||||
BUG_ON(check_region_contains_byte
|
||||
(source_mapping, num_pages * page_size, 'a') != 0,
|
||||
"source should have no ptes");
|
||||
|
||||
BUG_ON(munmap(dest_mapping, num_pages * page_size) == -1,
|
||||
"unable to unmap destination mapping");
|
||||
BUG_ON(munmap(source_mapping, num_pages * page_size) == -1,
|
||||
"unable to unmap source mapping");
|
||||
}
|
||||
|
||||
// This test validates MREMAP_DONTUNMAP will move page tables to a specific
|
||||
// destination using MREMAP_FIXED, also while validating that the source
|
||||
// remains intact.
|
||||
@ -300,6 +351,7 @@ int main(void)
|
||||
BUG_ON(page_buffer == MAP_FAILED, "unable to mmap a page.");
|
||||
|
||||
mremap_dontunmap_simple();
|
||||
mremap_dontunmap_simple_shmem();
|
||||
mremap_dontunmap_simple_fixed();
|
||||
mremap_dontunmap_partial_mapping();
|
||||
mremap_dontunmap_partial_mapping_overwrite();
|
||||
|
Loading…
Reference in New Issue
Block a user