É errado pensar em “memfd” como contabilizado “para o processo que possui o arquivo”?

13

link

Theoretically, you could achieve [memfd_create()] behavior without introducing new syscalls, like this:

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

(Nota: para garantir mais portualmente um tmpfs aqui, podemos usar "/ dev / shm" em vez de "/ tmp").

Therefore, the most important question is why the hell do we need a third way?

[...]

  • The backing-memory is accounted to the process that owns the file and is not subject to mount-quotas.

^ Estou certo em pensar que a primeira parte desta frase não pode ser invocada?

O código memfd_create () é literalmente implementado como " arquivo desvinculado que vive em [a] tmpfs que deve ser kernel interno ". Rastreando o código, eu entendo que difere em não implementar verificações de LSM, também memfds são criados para suportar "selos", como o post do blog continua explicando. No entanto, eu sou extremamente cético que os memfds são contabilizados diferentemente para um tmpfile em princípio.

Especificamente, quando o OOM-killer vem à tona, não acho ele será responsável pela memória mantida pelos memfds. Isso pode totalizar até 50% da RAM - o valor da opção size = para o tmpfs . O kernel não define um valor diferente para o tmpfs interno, então usaria o tamanho padrão de 50%.

Portanto, acho que geralmente podemos esperar que processos que contêm um memfd grande, mas nenhuma outra alocação de memória significativa, não sejam mortos por OOM. Isso está correto?

    
por sourcejedi 02.05.2018 / 21:22

1 resposta

0

Criando a resposta do @ danblack:

A decisão é baseada em oom_kill_process() (limpo um pouco):

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

( link )

Qual depende de oom_badness() para encontrar o melhor candidato:

child_points = oom_badness(child,
        oc->memcg, oc->nodemask, oc->totalpages);

oom_badness() faz:

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

( link )

Onde:

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

( link )

Portanto, parece que conta as páginas anônimas, que é o que usa memfd_create() .

    
por 16.10.2018 / 02:21