Commit af605d26 authored by Peter Xu's avatar Peter Xu Committed by Andrew Morton

selftests/mm: merge util.h into vm_util.h

There're two util headers under mm/ kselftest.  Merge one with another. 
It turns out util.h is the easy one to move.

When merging, drop PAGE_SIZE / PAGE_SHIFT because they're unnecessary
wrappers to page_size() / page_shift(), meanwhile rename them to psize()
and pshift() so as to not conflict with some existing definitions in some
test files that includes vm_util.h.

Link: https://lkml.kernel.org/r/20230412164120.327731-1-peterx@redhat.comSigned-off-by: default avatarPeter Xu <peterx@redhat.com>
Reviewed-by: default avatarAxel Rasmussen <axelrasmussen@google.com>
Reviewed-by: default avatarDavid Hildenbrand <david@redhat.com>
Reviewed-by: default avatarMike Rapoport (IBM) <rppt@kernel.org>
Cc: Dmitry Safonov <0x7f454c46@gmail.com>
Cc: Mike Kravetz <mike.kravetz@oracle.com>
Cc: Zach O'Keefe <zokeefe@google.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
parent c7c55fc4
...@@ -113,6 +113,10 @@ $(OUTPUT)/mkdirty: vm_util.c ...@@ -113,6 +113,10 @@ $(OUTPUT)/mkdirty: vm_util.c
$(OUTPUT)/soft-dirty: vm_util.c $(OUTPUT)/soft-dirty: vm_util.c
$(OUTPUT)/split_huge_page_test: vm_util.c $(OUTPUT)/split_huge_page_test: vm_util.c
$(OUTPUT)/userfaultfd: vm_util.c $(OUTPUT)/userfaultfd: vm_util.c
$(OUTPUT)/gup_test: vm_util.c
$(OUTPUT)/mrelease_test: vm_util.c
$(OUTPUT)/transhuge-stress: vm_util.c
$(OUTPUT)/ksm_tests: vm_util.c
ifeq ($(MACHINE),x86_64) ifeq ($(MACHINE),x86_64)
BINARIES_32 := $(patsubst %,$(OUTPUT)/%,$(BINARIES_32)) BINARIES_32 := $(patsubst %,$(OUTPUT)/%,$(BINARIES_32))
......
...@@ -12,8 +12,7 @@ ...@@ -12,8 +12,7 @@
#include <assert.h> #include <assert.h>
#include <mm/gup_test.h> #include <mm/gup_test.h>
#include "../kselftest.h" #include "../kselftest.h"
#include "vm_util.h"
#include "util.h"
#define MB (1UL << 20) #define MB (1UL << 20)
...@@ -251,7 +250,7 @@ int main(int argc, char **argv) ...@@ -251,7 +250,7 @@ int main(int argc, char **argv)
if (touch) { if (touch) {
gup.gup_flags |= FOLL_TOUCH; gup.gup_flags |= FOLL_TOUCH;
} else { } else {
for (; (unsigned long)p < gup.addr + size; p += PAGE_SIZE) for (; (unsigned long)p < gup.addr + size; p += psize())
p[0] = 0; p[0] = 0;
} }
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
#include "../kselftest.h" #include "../kselftest.h"
#include <include/vdso/time64.h> #include <include/vdso/time64.h>
#include "util.h" #include "vm_util.h"
#define KSM_SYSFS_PATH "/sys/kernel/mm/ksm/" #define KSM_SYSFS_PATH "/sys/kernel/mm/ksm/"
#define KSM_FP(s) (KSM_SYSFS_PATH s) #define KSM_FP(s) (KSM_SYSFS_PATH s)
......
...@@ -9,8 +9,7 @@ ...@@ -9,8 +9,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <unistd.h> #include <unistd.h>
#include "vm_util.h"
#include "util.h"
#include "../kselftest.h" #include "../kselftest.h"
...@@ -32,7 +31,7 @@ static int alloc_noexit(unsigned long nr_pages, int pipefd) ...@@ -32,7 +31,7 @@ static int alloc_noexit(unsigned long nr_pages, int pipefd)
unsigned long i; unsigned long i;
char *buf; char *buf;
buf = (char *)mmap(NULL, nr_pages * PAGE_SIZE, PROT_READ | PROT_WRITE, buf = (char *)mmap(NULL, nr_pages * psize(), PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANON, 0, 0); MAP_PRIVATE | MAP_ANON, 0, 0);
if (buf == MAP_FAILED) { if (buf == MAP_FAILED) {
perror("mmap failed, halting the test"); perror("mmap failed, halting the test");
...@@ -40,7 +39,7 @@ static int alloc_noexit(unsigned long nr_pages, int pipefd) ...@@ -40,7 +39,7 @@ static int alloc_noexit(unsigned long nr_pages, int pipefd)
} }
for (i = 0; i < nr_pages; i++) for (i = 0; i < nr_pages; i++)
*((unsigned long *)(buf + (i * PAGE_SIZE))) = i; *((unsigned long *)(buf + (i * psize()))) = i;
/* Signal the parent that the child is ready */ /* Signal the parent that the child is ready */
if (write(pipefd, "", 1) < 0) { if (write(pipefd, "", 1) < 0) {
...@@ -54,7 +53,7 @@ static int alloc_noexit(unsigned long nr_pages, int pipefd) ...@@ -54,7 +53,7 @@ static int alloc_noexit(unsigned long nr_pages, int pipefd)
timeout--; timeout--;
} }
munmap(buf, nr_pages * PAGE_SIZE); munmap(buf, nr_pages * psize());
return (timeout > 0) ? KSFT_PASS : KSFT_FAIL; return (timeout > 0) ? KSFT_PASS : KSFT_FAIL;
} }
...@@ -87,7 +86,7 @@ static int child_main(int pipefd[], size_t size) ...@@ -87,7 +86,7 @@ static int child_main(int pipefd[], size_t size)
/* Allocate and fault-in memory and wait to be killed */ /* Allocate and fault-in memory and wait to be killed */
close(pipefd[0]); close(pipefd[0]);
res = alloc_noexit(MB(size) / PAGE_SIZE, pipefd[1]); res = alloc_noexit(MB(size) / psize(), pipefd[1]);
close(pipefd[1]); close(pipefd[1]);
return res; return res;
} }
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
#include <fcntl.h> #include <fcntl.h>
#include <string.h> #include <string.h>
#include <sys/mman.h> #include <sys/mman.h>
#include "util.h" #include "vm_util.h"
int backing_fd = -1; int backing_fd = -1;
int mmap_flags = MAP_ANONYMOUS | MAP_NORESERVE | MAP_PRIVATE; int mmap_flags = MAP_ANONYMOUS | MAP_NORESERVE | MAP_PRIVATE;
...@@ -34,10 +34,10 @@ int main(int argc, char **argv) ...@@ -34,10 +34,10 @@ int main(int argc, char **argv)
int pagemap_fd; int pagemap_fd;
ram = sysconf(_SC_PHYS_PAGES); ram = sysconf(_SC_PHYS_PAGES);
if (ram > SIZE_MAX / sysconf(_SC_PAGESIZE) / 4) if (ram > SIZE_MAX / psize() / 4)
ram = SIZE_MAX / 4; ram = SIZE_MAX / 4;
else else
ram *= sysconf(_SC_PAGESIZE); ram *= psize();
len = ram; len = ram;
while (++i < argc) { while (++i < argc) {
...@@ -58,7 +58,7 @@ int main(int argc, char **argv) ...@@ -58,7 +58,7 @@ int main(int argc, char **argv)
warnx("allocate %zd transhuge pages, using %zd MiB virtual memory" warnx("allocate %zd transhuge pages, using %zd MiB virtual memory"
" and %zd MiB of ram", len >> HPAGE_SHIFT, len >> 20, " and %zd MiB of ram", len >> HPAGE_SHIFT, len >> 20,
ram >> (20 + HPAGE_SHIFT - PAGE_SHIFT - 1)); ram >> (20 + HPAGE_SHIFT - pshift() - 1));
pagemap_fd = open("/proc/self/pagemap", O_RDONLY); pagemap_fd = open("/proc/self/pagemap", O_RDONLY);
if (pagemap_fd < 0) if (pagemap_fd < 0)
...@@ -92,7 +92,7 @@ int main(int argc, char **argv) ...@@ -92,7 +92,7 @@ int main(int argc, char **argv)
if (pfn < 0) { if (pfn < 0) {
nr_failed++; nr_failed++;
} else { } else {
size_t idx = pfn >> (HPAGE_SHIFT - PAGE_SHIFT); size_t idx = pfn >> (HPAGE_SHIFT - pshift());
nr_succeed++; nr_succeed++;
if (idx >= map_len) { if (idx >= map_len) {
...@@ -108,7 +108,7 @@ int main(int argc, char **argv) ...@@ -108,7 +108,7 @@ int main(int argc, char **argv)
} }
/* split transhuge page, keep last page */ /* split transhuge page, keep last page */
if (madvise(p, HPAGE_SIZE - PAGE_SIZE, MADV_DONTNEED)) if (madvise(p, HPAGE_SIZE - psize(), MADV_DONTNEED))
err(2, "MADV_DONTNEED"); err(2, "MADV_DONTNEED");
} }
clock_gettime(CLOCK_MONOTONIC, &b); clock_gettime(CLOCK_MONOTONIC, &b);
......
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __KSELFTEST_VM_UTIL_H
#define __KSELFTEST_VM_UTIL_H
#include <stdint.h>
#include <sys/mman.h>
#include <err.h>
#include <string.h> /* ffsl() */
#include <unistd.h> /* _SC_PAGESIZE */
static unsigned int __page_size;
static unsigned int __page_shift;
static inline unsigned int page_size(void)
{
if (!__page_size)
__page_size = sysconf(_SC_PAGESIZE);
return __page_size;
}
static inline unsigned int page_shift(void)
{
if (!__page_shift)
__page_shift = (ffsl(page_size()) - 1);
return __page_shift;
}
#define PAGE_SHIFT (page_shift())
#define PAGE_SIZE (page_size())
/*
* On ppc64 this will only work with radix 2M hugepage size
*/
#define HPAGE_SHIFT 21
#define HPAGE_SIZE (1 << HPAGE_SHIFT)
#define PAGEMAP_PRESENT(ent) (((ent) & (1ull << 63)) != 0)
#define PAGEMAP_PFN(ent) ((ent) & ((1ull << 55) - 1))
static inline int64_t allocate_transhuge(void *ptr, int pagemap_fd)
{
uint64_t ent[2];
/* drop pmd */
if (mmap(ptr, HPAGE_SIZE, PROT_READ | PROT_WRITE,
MAP_FIXED | MAP_ANONYMOUS |
MAP_NORESERVE | MAP_PRIVATE, -1, 0) != ptr)
errx(2, "mmap transhuge");
if (madvise(ptr, HPAGE_SIZE, MADV_HUGEPAGE))
err(2, "MADV_HUGEPAGE");
/* allocate transparent huge page */
*(volatile void **)ptr = ptr;
if (pread(pagemap_fd, ent, sizeof(ent),
(uintptr_t)ptr >> (PAGE_SHIFT - 3)) != sizeof(ent))
err(2, "read pagemap");
if (PAGEMAP_PRESENT(ent[0]) && PAGEMAP_PRESENT(ent[1]) &&
PAGEMAP_PFN(ent[0]) + 1 == PAGEMAP_PFN(ent[1]) &&
!(PAGEMAP_PFN(ent[0]) & ((1 << (HPAGE_SHIFT - PAGE_SHIFT)) - 1)))
return PAGEMAP_PFN(ent[0]);
return -1;
}
#endif
...@@ -8,6 +8,9 @@ ...@@ -8,6 +8,9 @@
#define SMAP_FILE_PATH "/proc/self/smaps" #define SMAP_FILE_PATH "/proc/self/smaps"
#define MAX_LINE_LENGTH 500 #define MAX_LINE_LENGTH 500
unsigned int __page_size;
unsigned int __page_shift;
uint64_t pagemap_get_entry(int fd, char *start) uint64_t pagemap_get_entry(int fd, char *start)
{ {
const unsigned long pfn = (unsigned long)start / getpagesize(); const unsigned long pfn = (unsigned long)start / getpagesize();
...@@ -149,3 +152,31 @@ bool check_huge_shmem(void *addr, int nr_hpages, uint64_t hpage_size) ...@@ -149,3 +152,31 @@ bool check_huge_shmem(void *addr, int nr_hpages, uint64_t hpage_size)
{ {
return __check_huge(addr, "ShmemPmdMapped:", nr_hpages, hpage_size); return __check_huge(addr, "ShmemPmdMapped:", nr_hpages, hpage_size);
} }
int64_t allocate_transhuge(void *ptr, int pagemap_fd)
{
uint64_t ent[2];
/* drop pmd */
if (mmap(ptr, HPAGE_SIZE, PROT_READ | PROT_WRITE,
MAP_FIXED | MAP_ANONYMOUS |
MAP_NORESERVE | MAP_PRIVATE, -1, 0) != ptr)
errx(2, "mmap transhuge");
if (madvise(ptr, HPAGE_SIZE, MADV_HUGEPAGE))
err(2, "MADV_HUGEPAGE");
/* allocate transparent huge page */
*(volatile void **)ptr = ptr;
if (pread(pagemap_fd, ent, sizeof(ent),
(uintptr_t)ptr >> (pshift() - 3)) != sizeof(ent))
err(2, "read pagemap");
if (PAGEMAP_PRESENT(ent[0]) && PAGEMAP_PRESENT(ent[1]) &&
PAGEMAP_PFN(ent[0]) + 1 == PAGEMAP_PFN(ent[1]) &&
!(PAGEMAP_PFN(ent[0]) & ((1 << (HPAGE_SHIFT - pshift())) - 1)))
return PAGEMAP_PFN(ent[0]);
return -1;
}
/* SPDX-License-Identifier: GPL-2.0 */ /* SPDX-License-Identifier: GPL-2.0 */
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include <sys/mman.h>
#include <err.h>
#include <string.h> /* ffsl() */
#include <unistd.h> /* _SC_PAGESIZE */
extern unsigned int __page_size;
extern unsigned int __page_shift;
static inline unsigned int psize(void)
{
if (!__page_size)
__page_size = sysconf(_SC_PAGESIZE);
return __page_size;
}
static inline unsigned int pshift(void)
{
if (!__page_shift)
__page_shift = (ffsl(psize()) - 1);
return __page_shift;
}
uint64_t pagemap_get_entry(int fd, char *start); uint64_t pagemap_get_entry(int fd, char *start);
bool pagemap_is_softdirty(int fd, char *start); bool pagemap_is_softdirty(int fd, char *start);
...@@ -13,3 +34,13 @@ uint64_t read_pmd_pagesize(void); ...@@ -13,3 +34,13 @@ uint64_t read_pmd_pagesize(void);
bool check_huge_anon(void *addr, int nr_hpages, uint64_t hpage_size); bool check_huge_anon(void *addr, int nr_hpages, uint64_t hpage_size);
bool check_huge_file(void *addr, int nr_hpages, uint64_t hpage_size); bool check_huge_file(void *addr, int nr_hpages, uint64_t hpage_size);
bool check_huge_shmem(void *addr, int nr_hpages, uint64_t hpage_size); bool check_huge_shmem(void *addr, int nr_hpages, uint64_t hpage_size);
int64_t allocate_transhuge(void *ptr, int pagemap_fd);
/*
* On ppc64 this will only work with radix 2M hugepage size
*/
#define HPAGE_SHIFT 21
#define HPAGE_SIZE (1 << HPAGE_SHIFT)
#define PAGEMAP_PRESENT(ent) (((ent) & (1ull << 63)) != 0)
#define PAGEMAP_PFN(ent) ((ent) & ((1ull << 55) - 1))
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment