你怎么理解mlockall手册页?

时间:2012-04-04 19:26:29

标签: c linux

我的内核3.0上mlockall的手册页说

  

mlockall()锁定映射到地址空间的所有页面   呼叫过程。这包括代码页面,数据和堆栈   段,以及共享库,用户空间内核数据,共享   内存和内存映射文件。所有映射页面都得到保证   当呼叫成功返回时驻留在RAM中;页面   保证保留在RAM中,直到稍后解锁。

后来说

  

使用mlockall()来防止延迟的实时进程   页面错误应在进入之前保留足够的锁定堆栈页面   时间关键部分,因此不会导致页面错误   功能          调用。这可以通过调用一个分配足够大的自动变量(数组)的函数来实现   写入此数组占用的内存以触摸这些内存   堆栈页面。这条路,          将为堆栈映射足够的页面,并将其锁定到RAM中。虚拟写入确保甚至不是写入时复制页面   故障可能发生在关键部分。

据我所知,这个系统调用无法猜出将达到的最大堆栈大小,因此无法锁定堆栈的页面。但为什么上面显示的那个人的第一部分说它也是为堆栈做的?这个手册页中是否有错误,或者只是意味着对初始堆栈大小进行了锁定?

4 个答案:

答案 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。