将“memfd”视为“拥有文件的进程”是错误的吗?

sou*_*edi 15 shared-memory resources linux-kernel out-of-memory

https://dvdhrm.wordpress.com/2014/06/10/memfd_create2/

从理论上讲,您可以在memfd_create()不引入新系统调用的情况下实现 [ ] 行为,如下所示:

int fd = open("/tmp", O_RDWR | O_TMPFILE | O_EXCL, S_IRWXU);

(注意,为了更方便地保证这里的 tmpfs,我们可以使用“ /dev/shm”代替“ /tmp”)。

因此,最重要的问题是为什么我们需要第三条路?

[...]

  • 后备内存属于拥有文件的进程,不受挂载配额的限制。

^ 我认为这句话的第一部分不能依赖是正确的吗?

所述memfd_create()的代码被作为“的字面实施链接的文件居住在[α] TMPFS必须是内核内部”。跟踪代码,我理解它的不同之处在于不实施 LSM 检查,还创建了 memfds 来支持“密封”,正如博客文章继续解释的那样。但是,我非常怀疑memfds正在考虑不同的,以原则上TMPFILE。

具体来说,当OOM 杀手来敲门时,我认为它不会解释 memfds 持有的内存。这可能总计高达 50% 的 RAM - tmpfssize= 选项的值。内核不会为内部 tmpfs 设置不同的值,因此它将使用默认大小 50%。

所以我认为我们通常可以预期拥有大型 memfd 但没有其他重要内存分配的进程不会被 OOM 杀死。那是对的吗?

V13*_*V13 0

基于@danblack 的回答:

该决定基于oom_kill_process()(稍微清理一下):

for_each_thread(p, t) {
        list_for_each_entry(child, &t->children, sibling) {
                unsigned int child_points;

                child_points = oom_badness(child,
                        oc->memcg, oc->nodemask, oc->totalpages);
                if (child_points > victim_points) {
                        put_task_struct(victim);
                        victim = child;
                        victim_points = child_points;
                        get_task_struct(victim);
                }
        }
}
Run Code Online (Sandbox Code Playgroud)

https://github.com/torvalds/linux/blob/master/mm/oom_kill.c#L974

这取决于oom_badness()找到最佳候选人:

child_points = oom_badness(child,
        oc->memcg, oc->nodemask, oc->totalpages);
Run Code Online (Sandbox Code Playgroud)

oom_badness()做:

points = get_mm_rss(p->mm) + get_mm_counter(p->mm, MM_SWAPENTS) +
        mm_pgtables_bytes(p->mm) / PAGE_SIZE;
Run Code Online (Sandbox Code Playgroud)

https://github.com/torvalds/linux/blob/master/mm/oom_kill.c#L233

在哪里:

static inline unsigned long get_mm_rss(struct mm_struct *mm)
{
        return get_mm_counter(mm, MM_FILEPAGES) +
                get_mm_counter(mm, MM_ANONPAGES) +
                get_mm_counter(mm, MM_SHMEMPAGES);
}
Run Code Online (Sandbox Code Playgroud)

https://github.com/torvalds/linux/blob/master/mm/oom_kill.c#L966

所以看起来它计算的是匿名页面,这就是用途memfd_create()