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 %까지 가능합니다 . tmpfs 의 size = 옵션 값입니다 . 커널은 내부 tmpfs에 다른 값을 설정하지 않으므로 기본 크기 인 50 %를 사용합니다.
따라서 일반적으로 큰 memfd를 보유하지만 다른 중요한 메모리 할당이없는 프로세스는 OOM으로 죽지 않을 것으로 예상 할 수 있다고 생각합니다. 그 맞습니까?
답변
@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()
하여 사용 하는 것으로 보입니다 .