decrement_hugepage_resv_vma 函数对 resv_huge_pages 尝试 -1,但无符号运算导致它改为 ULONG_MAX(无符号长 resv_huge_pages),在 64 位系统上为 18446744073709551615。
alloc_huge_page()
page = dequeue_huge_page_vma(h, vma, addr, avoid_reserve)
decrement_hugepage_resv_vma() {
h->resv_huge_pages--;
}
static void return_unused_surplus_pages(struct hstate *h,
unsigned long unused_resv_pages)
{
h->resv_huge_pages -= unused_resv_pages;
}
其他不太可能的原因是gather_surplus_pages() 函数可以溢出resv_huge_pages。
在测试期间尝试下一步:
while [ 1 ] ; do date | awk '{print $4}' >> HugePages_Rsvd.log; cat /proc/meminfo | grep HugePages_Rsvd >> HugePages_Rsvd.log; sleep 1; done
我猜 resv_huge_pages 是否会缓慢增加,所以问题在 h->resv_huge_pages += delta;
但是如果 resv_huge_pages 突然变成 -1 (unsigned long == 18446744073709551615 ) 那么问题在 h->resv_huge_pages--; (resv_huge_pages 为 0 并且减量后 == -1)
取决于您的内核,您可以检查补丁 mm:numa: disable change protection for vma(VM_HUGETLB) 6b79c57b92cdd90853002980609af516d14c4f9c 和HugePages_Rsvd 的 BUG 大值