"memfd"를 "파일을 소유하는 프로세스"로 생각하는 것은 잘못된 것입니까?

"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"를 사용할 수 있습니다.)

그렇다면 가장 중요한 질문은 왜 제3의 방법이 필요한가 하는 것입니다.

[...]

  • 메모리 백업은 파일을 소유한 프로세스의 책임이며 설치 할당량의 적용을 받지 않습니다.

^ 이 문장의 첫 부분은 믿을 수 없을 것 같은데요?

이것memfd_create() 코드실제로 "링크되지 않은 파일은 커널 내부에 있어야 하는 [a] tmpfs에 있습니다.". 코드를 추적해 보면 LSM 검사를 구현하지 않는 것과 같지 않다는 점과 블로그 게시물에서 계속 설명하는 것처럼 memfd가 "봉인"을 지원하기 위해 만들어졌다는 사실을 알게 되었습니다. 그러나 memfd가 매우 의심스럽습니다.회계원칙적으로 tmpfile과 다릅니다.

구체적으로 언제OOM 킬러노크해 보세요. memfds가 보유한 메모리를 설명할 수는 없을 것 같습니다. 이는 RAM의 최대 50%까지 차지할 수 있습니다. 즉,size= tmpfs 옵션. 커널은 내부 tmpfs에 대해 다른 값을 설정하지 않으므로 기본 크기인 50%를 사용합니다.

따라서 일반적으로 큰 memfd를 보유하고 있지만 다른 중요한 메모리 할당이 없는 프로세스는 OOM에 의해 종료되지 않을 것이라고 예상할 수 있습니다. 그렇죠?

답변1

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

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

따라서 익명 페이지를 세는 것처럼 보입니다 memfd_create(). 이것이 목적입니다.

답변2

예, 귀하의 이해는 일반적으로 정확합니다.memfd_create()익명 파일을 생성하기 위한 시스템 호출입니다. 파일은 일반 파일처럼 동작하지만 RAM에 남아 있으며 특정 파일 시스템에 연결되지 않습니다.[1]. 이는 다른 익명 메모리 할당과 마찬가지로 메모리 사용량이 소유 프로세스에 직접적으로 영향을 미친다는 것을 의미합니다.malloc() [2]. 따라서 할당이 파일 시스템이나 마운트 지점에 바인딩되지 않은 경우 해당 수준에서 적용되는 할당량에 포함되지 않습니다.

이것OOM 킬러대상 프로세스는 출처에 관계없이 주로 전체 메모리 소비와 전체 시스템 메모리 압력에 미치는 영향을 기반으로 합니다(예:임시 파일 시스템,익명의 기억)[삼]. 그러나 OOM Killer는 메모리 매핑된 파일과 익명 메모리를 포함한 총 메모리 사용량을 고려합니다.

memfd_create()총 메모리 사용 공간의 비율로 사용되는 메모리로 측정할 때 프로세스가 많은 수의 할당을 보유 memfd_create()하고 다른 메모리 할당이 최소화된 경우 다른 프로세스에 비해 단순히 OOM 킬러의 대상이 될 가능성이 적습니다. 사용량은 여전히 ​​낮은 것으로 간주될 수 있습니다. 프로세스.

memfd_create()OOM 킬러의 할당에 대한 태도는 다른 할당과 크게 다르며 tmpfiles이는 다양한 할당 유형에 대한 OOM 킬러의 특정 메커니즘보다는 Linux가 전체적으로 메모리를 해석하고 관리하는 방식의 결과입니다.[4].

관련 정보