mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-05-24 10:39:52 +00:00
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.com Signed-off-by: Peter Xu <peterx@redhat.com> Reviewed-by: Axel Rasmussen <axelrasmussen@google.com> Reviewed-by: David Hildenbrand <david@redhat.com> Reviewed-by: Mike 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: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
parent
c7c55fc4e3
commit
af605d26a8
8 changed files with 80 additions and 85 deletions
|
@ -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 @@
|
||||||
#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)
|
||||||
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 @@
|
||||||
|
|
||||||
#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 @@
|
||||||
#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)
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
|
|
||||||
/* 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 @@
|
||||||
#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)
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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);
|
||||||
|
|
|
@ -1,69 +0,0 @@
|
||||||
/* 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 @@
|
||||||
#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)
|
||||||
{
|
{
|
||||||
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;
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,27 @@
|
||||||
/* 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);
|
||||||
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))
|
||||||
|
|
Loading…
Add table
Reference in a new issue