From: Xu Yu <xuyu@linux.alibaba.com>
To: linux-mm@kvack.org
Cc: akpm@linux-foundation.org, zokeefe@google.com, song@kernel.org,
shy828301@gmail.com
Subject: [PATCH 0/1] mm/khugepaged: map anonymous pte-mapped THPs by pmds
Date: Mon, 13 Nov 2023 17:05:57 +0800 [thread overview]
Message-ID: <cover.1699865107.git.xuyu@linux.alibaba.com> (raw)
I write a testcase[1] to demonstrate this scenario.
vanilla kernel (v6.6):
# ./test
[mmap rw ] vaddr: 0x0x7f2000000000, pfn: 0x110000, is_thp: 1, is_thp_mapped: 1
[mprotect ro] vaddr: 0x0x7f2000000000, pfn: 0x110000, is_thp: 1, is_thp_mapped: 0
^^ __split_huge_pmd() is called in change_protection()
[mprotect rw] vaddr: 0x0x7f2000000000, pfn: 0x110000, is_thp: 1, is_thp_mapped: 0
^^ vma_merge()
[khugepaged ] vaddr: 0x0x7f2000000000, pfn: 0x110000, is_thp: 1, is_thp_mapped: 0
[khugepaged ] vaddr: 0x0x7f2000000000, pfn: 0x110000, is_thp: 1, is_thp_mapped: 0
[khugepaged ] vaddr: 0x0x7f2000000000, pfn: 0x117a00, is_thp: 1, is_thp_mapped: 1
^^ hpage_collapse_scan_pmd ^^^^^^^^ new hugepage is allocated
[khugepaged ] vaddr: 0x0x7f2000000000, pfn: 0x117a00, is_thp: 1, is_thp_mapped: 1
patched kernel:
# ./test
[mmap rw ] vaddr: 0x0x7f2000000000, pfn: 0x128400, is_thp: 1, is_thp_mapped: 1
[mprotect ro] vaddr: 0x0x7f2000000000, pfn: 0x128400, is_thp: 1, is_thp_mapped: 0
[mprotect rw] vaddr: 0x0x7f2000000000, pfn: 0x128400, is_thp: 1, is_thp_mapped: 0
[khugepaged ] vaddr: 0x0x7f2000000000, pfn: 0x128400, is_thp: 1, is_thp_mapped: 0
[khugepaged ] vaddr: 0x0x7f2000000000, pfn: 0x128400, is_thp: 1, is_thp_mapped: 0
[khugepaged ] vaddr: 0x0x7f2000000000, pfn: 0x128400, is_thp: 1, is_thp_mapped: 1
^^ hpage_collapse_scan_pmd ^^^^^^^^ old hugepage
[khugepaged ] vaddr: 0x0x7f2000000000, pfn: 0x128400, is_thp: 1, is_thp_mapped: 1
[1] testcase source code
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <ctype.h>
#include <fcntl.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>
#include<signal.h>
#define PAGE_SHIFT 12
#define SIZE_2M (2<<20)
#define ADDRESS 0x7f2000000000
#define PAGEMAP_PRESENT 63
#define PAGEMAP_PFN_MASK 0x007FFFFFFFFFFFFFUL /* bits 54:0 */
#define KPF_SIZE 8
#define KPF_THP 22
static bool is_thp(unsigned long pfn)
{
int kpageflags_fd;
unsigned long flag;
int ret;
kpageflags_fd = open("/proc/kpageflags", O_RDONLY);
ret = pread(kpageflags_fd, &flag, KPF_SIZE, KPF_SIZE * pfn);
close(kpageflags_fd);
if (ret != KPF_SIZE)
return false;
return flag & (1 << KPF_THP);
}
static bool is_thp_mapped(void *addr)
{
char path[64], line[128], pattern[64];
int pid;
FILE *fp;
int anon_huge_pages = 0;
snprintf(pattern, 64, "%lx", (unsigned long)addr);
pid = getpid();
snprintf(path, 64, "/proc/%u/smaps", pid);
fp = fopen(path, "r");
while (fgets(line, 64, fp) != NULL) {
if (strstr(line, pattern))
break;
}
while (fgets(line, 64, fp) != NULL) {
if (1 == sscanf(line, "AnonHugePages: %d kB", &anon_huge_pages))
break;
}
fclose(fp);
return anon_huge_pages != 0;
}
static unsigned long get_pfn(unsigned long vaddr)
{
char path[64];
int pid, pagemap_fd;
off64_t offset;
unsigned long pfn = 0;
int ret;
offset = (vaddr >> PAGE_SHIFT) * sizeof(unsigned long);
pid = getpid();
snprintf(path, 64, "/proc/%u/pagemap", pid);
pagemap_fd = open(path, O_RDONLY);
lseek64(pagemap_fd, offset, SEEK_SET);
ret = read(pagemap_fd, &pfn, sizeof(pfn));
close(pagemap_fd);
if (ret < 0)
return -1;
if (!(pfn & (1UL << PAGEMAP_PRESENT)))
return 0;
return (pfn & PAGEMAP_PFN_MASK);
}
static void show_addr_info(void *addr, char *msg)
{
unsigned long pfn;
pfn = get_pfn((unsigned long)addr);
printf("[%s] vaddr: 0x%p, pfn: 0x%lx, is_thp: %d, is_thp_mapped: %d\n",
msg, addr, pfn, is_thp(pfn), is_thp_mapped(addr));
}
int main(int argc, char *argv[])
{
void *addr;
addr = mmap((void *)ADDRESS, SIZE_2M, PROT_READ | PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_POPULATE, -1, 0);
if (addr == MAP_FAILED) {
perror("mmap");
return 1;
}
show_addr_info(addr, "mmap rw ");
mprotect(addr, SIZE_2M / 2, PROT_READ);
show_addr_info(addr, "mprotect ro");
mprotect(addr, SIZE_2M / 2, PROT_READ | PROT_WRITE);
show_addr_info(addr, "mprotect rw");
while (1) {
show_addr_info(addr, "khugepaged ");
sleep(5);
}
return 0;
}
Xu Yu (1):
mm/khugepaged: map anonymous pte-mapped THPs by pmds
mm/khugepaged.c | 187 ++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 180 insertions(+), 7 deletions(-)
--
2.37.1
next reply other threads:[~2023-11-13 9:06 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-11-13 9:05 Xu Yu [this message]
2023-11-13 9:05 ` [PATCH 1/1] mm/khugepaged: map anonymous pte-mapped THPs by pmds Xu Yu
2023-11-13 9:26 ` David Hildenbrand
2023-11-13 9:33 ` Xu Yu
2023-11-13 10:10 ` David Hildenbrand
2023-12-07 3:09 ` [PATCH v2 0/2] attempt to " Xu Yu
2023-12-07 3:09 ` [PATCH v2 1/2] mm/khugepaged: " Xu Yu
2023-12-07 7:47 ` Xu Yu
2023-12-07 10:37 ` David Hildenbrand
2023-12-18 2:45 ` Xu Yu
2023-12-07 3:09 ` [PATCH v2 2/2] mm/khugepaged: add case for mapping " Xu Yu
2023-12-18 7:06 ` [PATCH v3 0/2] attempt to map " Xu Yu
2023-12-18 7:06 ` [PATCH v3 1/2] mm/khugepaged: map RO non-exclusive pte-mapped anon " Xu Yu
2023-12-18 7:06 ` [PATCH v3 2/2] mm/khugepaged: map exclusive anonymous pte-mapped " Xu Yu
2023-12-21 20:40 ` [PATCH v3 0/2] attempt to map " Zach O'Keefe
2023-12-21 20:54 ` David Hildenbrand
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=cover.1699865107.git.xuyu@linux.alibaba.com \
--to=xuyu@linux.alibaba.com \
--cc=akpm@linux-foundation.org \
--cc=linux-mm@kvack.org \
--cc=shy828301@gmail.com \
--cc=song@kernel.org \
--cc=zokeefe@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.