Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

/dev/zero: try to align PMD_SIZE for private mapping

Attempt to map aligned to huge page size for private mapping which could
achieve performance gains, the mprot_tw4m in libMicro average execution
time on arm64:

- Test case: mprot_tw4m
- Before the patch: 22 us
- After the patch: 17 us

If THP config is not set, we fall back to system page size mappings.

Link: https://lkml.kernel.org/r/20250731122305.2669090-1-zhangqilong3@huawei.com
Signed-off-by: Zhang Qilong <zhangqilong3@huawei.com>
Reviewed-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Tested-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Acked-by: David Hildenbrand <david@redhat.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Kefeng Wang <wangkefeng.wang@huawei.com>
Cc: Nanyong Sun <sunnanyong@huawei.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Zhang Qilong and committed by
Andrew Morton
849d5cff 337135e6

+17 -4
+17 -4
drivers/char/mem.c
··· 512 512 return 0; 513 513 } 514 514 515 + #ifndef CONFIG_MMU 515 516 static unsigned long get_unmapped_area_zero(struct file *file, 516 517 unsigned long addr, unsigned long len, 517 518 unsigned long pgoff, unsigned long flags) 518 519 { 519 - #ifdef CONFIG_MMU 520 + return -ENOSYS; 521 + } 522 + #else 523 + static unsigned long get_unmapped_area_zero(struct file *file, 524 + unsigned long addr, unsigned long len, 525 + unsigned long pgoff, unsigned long flags) 526 + { 520 527 if (flags & MAP_SHARED) { 521 528 /* 522 529 * mmap_zero() will call shmem_zero_setup() to create a file, ··· 534 527 return shmem_get_unmapped_area(NULL, addr, len, pgoff, flags); 535 528 } 536 529 537 - /* Otherwise flags & MAP_PRIVATE: with no shmem object beneath it */ 538 - return mm_get_unmapped_area(current->mm, file, addr, len, pgoff, flags); 530 + /* 531 + * Otherwise flags & MAP_PRIVATE: with no shmem object beneath it, 532 + * attempt to map aligned to huge page size if possible, otherwise we 533 + * fall back to system page size mappings. 534 + */ 535 + #ifdef CONFIG_TRANSPARENT_HUGEPAGE 536 + return thp_get_unmapped_area(file, addr, len, pgoff, flags); 539 537 #else 540 - return -ENOSYS; 538 + return mm_get_unmapped_area(current->mm, file, addr, len, pgoff, flags); 541 539 #endif 542 540 } 541 + #endif /* CONFIG_MMU */ 543 542 544 543 static ssize_t write_full(struct file *file, const char __user *buf, 545 544 size_t count, loff_t *ppos)