在 mmap 之后获得 SIGBUS 对于大页面,即使HugePages_Free是积极的

Getting SIGBUS after mmap for Huge Pages, even though HugePages_Free is positive

本文关键字:HugePages 即使 Free 之后 mmap SIGBUS 于大页      更新时间:2023-10-16

我正在使用mmap来分配巨大的页面。这工作正常,但有时我接近可用大页面的限制,并且在访问内存时出现 SIGBUS 错误。但是我不明白,如果没有记忆,为什么mmap首先成功,我不明白为什么/proc/meminfo似乎表明有足够的记忆?

如果你想知道有多少大页面可用,你需要做

grep Huge /proc/meminfo

然后减去

availablePages = HugePages_Free - HugePages_Rsvd  

这是因为"免费"实际上并不意味着免费。这只是意味着内存还没有被触及。如果availablePages为 0,则无法成功分配更多大页面。 所以很有可能,你已经用完了内存,但你对/proc/meminfo的可怕输出感到困惑。

但是,mmap不会失败!所以也读下一段。

在打开MAP_NORESERVE标志的情况下,使用mmap分配大页面存在一个不幸的缺陷。这意味着不要保留交换空间。但是,即使系统无法"分配"巨大的页面内存,mmap也会成功。 处理它。为了测试mmap是否成功地进行物理分配 内存并立即可用是调用 mincore() 以评估是否成功分配了每个页面。我做了这样的事情:

ptr = mmap( ... );
...
uint32_t inMemoryPages = 0;
for(int j=0;j<numDesiredPages;j++)
{
uint8_t flag;
int s = mincore((uint8_t*)ptr + j * HugePageSize(), 1,&flag);
// flag is 1 if the page was successfully allocated and in memory
inMemoryPages += flag;
}
if (numDesiredPages != inMemoryPages)
{
std::stringstream ss;
ss << "Unable to fulfill huge page allocation request."
<< " numDesiredPages:" << numDesiredPages
<< " successfulPages:" << inMemoryPages;
throw std::runtime_error(ss.str());
}

否则,您的mmap调用可能会成功,然后当您发现实际上没有足够的巨大页面内存时,您会SIGBUS

相关文章: