我的内核3.0上mlockall
的手册页说
mlockall()锁定映射到地址空间的所有页面 呼叫过程。这包括代码页面,数据和堆栈 段,以及共享库,用户空间内核数据,共享 内存和内存映射文件。所有映射页面都得到保证 当呼叫成功返回时驻留在RAM中;页面 保证保留在RAM中,直到稍后解锁。
后来说
使用mlockall()来防止延迟的实时进程 页面错误应在进入之前保留足够的锁定堆栈页面 时间关键部分,因此不会导致页面错误 功能 调用。这可以通过调用一个分配足够大的自动变量(数组)的函数来实现 写入此数组占用的内存以触摸这些内存 堆栈页面。这条路, 将为堆栈映射足够的页面,并将其锁定到RAM中。虚拟写入确保甚至不是写入时复制页面 故障可能发生在关键部分。
据我所知,这个系统调用无法猜出将达到的最大堆栈大小,因此无法锁定堆栈的页面。但为什么上面显示的那个人的第一部分说它也是为堆栈做的?这个手册页中是否有错误,或者只是意味着对初始堆栈大小进行了锁定?
答案 0 :(得分:4)
是的,锁定是针对当前堆栈页面完成的,但不是针对所有可能的未来堆栈页面。
答案 1 :(得分:2)
第一句话解释了这一点:
mlockall()
锁定映射到调用进程的地址空间的所有页面。
因此,如果页面被映射,它将被锁定。如果没有,它就不会。
答案 2 :(得分:1)
它只是提到原始句子中的堆栈,因为堆栈内存与堆内存分开映射。对堆栈没有特殊处理,如果映射它将被锁定,否则它不会。因此,正如您引用的第二部分所述,在您调用mlockall
之前,将代码运行时的堆栈增长到最大尺寸非常重要。
答案 3 :(得分:1)
实际上,通过快速阅读mm / mlock.c源代码,我会说它只是锁定所有内容:所有当前映射的页面。
static int do_mlockall(int flags)
{
struct vm_area_struct * vma, * prev = NULL;
unsigned int def_flags = 0;
if (flags & MCL_FUTURE)
def_flags = VM_LOCKED;
current->mm->def_flags = def_flags;
if (flags == MCL_FUTURE)
goto out;
for (vma = current->mm->mmap; vma ; vma = prev->vm_next) {
vm_flags_t newflags;
newflags = vma->vm_flags | VM_LOCKED;
if (!(flags & MCL_CURRENT))
newflags &= ~VM_LOCKED;
/* Ignore errors */
mlock_fixup(vma, &prev, vma->vm_start, vma->vm_end, newflags);
}
out:
return 0;
}
尽管larsmans说过,但如果同时指定了MCL_FUTURE,我认为它也适用于所有未来的页面。 在这种情况下,'current-> mm-> def_flags更新为包含VM_LOCKED。