在 Linux 上,(非透明)大页可以通过写入 sysctlvm.nr_hugepages
或等效地写入/sys/kernel/mm/hugepages/hugepages-<SIZE>kB/nr_hugepages
sysfs 文件来分配:
# to allocate 2 GiB worth of huge pages, assuming a huge page size of 2 MiB (default on x86)
$ sysctl vm.nr_hugepages=1024
# likewise, but explicitly
$ echo 1024 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages; grep . /sys/kernel/mm/hugepages/hugepages-2048kB/*
/sys/kernel/mm/hugepages/hugepages-2048kB/free_hugepages:1024
/sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages:1024
/sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages_mempolicy:1024
/sys/kernel/mm/hugepages/hugepages-2048kB/nr_overcommit_hugepages:0
/sys/kernel/mm/hugepages/hugepages-2048kB/resv_hugepages:0
/sys/kernel/mm/hugepages/hugepages-2048kB/surplus_hugepages:0
但是,如果 Linux 无法分配所需数量的大页,则其余部分将被静默跳过:
$ sysctl vm.nr_hugepages=1024
vm.nr_hugepages = 1024
$ sysctl vm.nr_hugepages
vm.nr_hugepages = 640
通过在循环中分配,并与页面缓存重置请求和内存压缩请求混合,可以在一定程度上提高在长时间运行的系统上分配所请求数量的大页面的机会:
while :; do
sysctl vm.drop_caches=3
sysctl vm.compact_memory=1
sysctl vm.nr_hugepages=1024
nr=$(sysctl -n vm.nr_hugepages)
echo "vm.nr_hugepages = $nr"
if (( nr >= 1024 )); then
break
fi
done
然而,这充其量只是一种肮脏的黑客行为,并且会导致整个页面缓存不必要的失效和抖动。
是否有一种不那么老套的方法来请求分配 N 个大页面,自动触发完成分配所需的任何和所有工作(例如内存压缩,页面缓存回收,...)并同步等待它完成?
换句话说,我如何要求内核“尽一切努力为我获取N个大页面,并且除非分配了N个大页面或者除非已经确定绝对不可能完成这样的分配,否则不要返回” ?