web-dev-qa-db-ja.com

"memfd"を "ファイルを所有するプロセス"と見なすのは間違っていますか?

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()コード は、文字通り " [a] tmpfsに存在するリンクされていないファイルであり、カーネル内部である必要があります "として実装されます。コードを追跡すると、LSMチェックを実装しない点が異なることを理解しています。また、ブログポストで説明されているように、「シール」をサポートするためにmemfdsが作成されます。ただし、me​​mfdsがaccountedで、原則としてtmpfileとは異なっていることに非常に懐疑的です。

具体的には、 OOM-killer がノックする場合、memfdsが保持するメモリの原因とはなりません。これは、RAM-tmpfsの size =オプションの値 の最大50%になります。カーネルは内部tmpfsに別の値を設定しません。したがって、デフォルトサイズの50%を使用します。

したがって、大規模なmemfdを保持しているが、他の重要なメモリ割り当てが存在しないプロセスは、OOMで強制終了されないことが一般的に期待できると思います。あれは正しいですか?

15
sourcejedi

@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);
                }
        }
}
_

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);
_

oom_badness()は:

_points = get_mm_rss(p->mm) + get_mm_counter(p->mm, MM_SWAPENTS) +
        mm_pgtables_bytes(p->mm) / PAGE_SIZE;
_

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

どこ:

_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);
}
_

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

したがって、memfd_create()が使用する匿名ページをカウントしているように見えます。

1
V13