"memfd"를 "파일을 소유 한 프로세스"에 설명 된 것으로 잘못 생각합니까?


15

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가 생성됩니다. 그러나 memfds가 원칙적으로 tmpfile과 다르게 설명 된다는 것에 회의적입니다 .

특히, OOM-killer 가 두드리면 memfds가 보유한 메모리를 설명하지는 않습니다. 이것은 RAM의 50 %까지 가능합니다 . tmpfssize = 옵션 값입니다 . 커널은 내부 tmpfs에 다른 값을 설정하지 않으므로 기본 크기 인 50 %를 사용합니다.

따라서 일반적으로 큰 memfd를 보유하지만 다른 중요한 메모리 할당이없는 프로세스는 OOM으로 죽지 않을 것으로 예상 할 수 있다고 생각합니다. 그 맞습니까?


2
OOM 점수가 올라가면 커널 oom_badness 함수 로 내려가는 것 같습니다 . 따라서 memfd_create가 / proc / {pid} / map에 나타나지 않으면 계산되지 않는 것 같습니다. 따라서 일반적인 대답은 죽일 수 있지만 memfd_create 사용으로 인해 큰 점수를 얻지 못할 것입니다. 여러 프로세스가 동일한 fd를 상속 / 전송할 수 있으므로 fd의 메모리를 프로세스간에 공유 할 수 있습니다.
danblack

답변:


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()하여 사용 하는 것으로 보입니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.