È sbagliato pensare a "memfd" come al "processo che possiede il file"?


15

https://dvdhrm.wordpress.com/2014/06/10/memfd_create2/

Teoricamente, potresti ottenere un memfd_create()comportamento [ ] senza introdurre nuovi syscall, come questo:

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

(Nota, per garantire in modo più portabile un tmpfs qui, possiamo usare " /dev/shm" invece di " /tmp").

Pertanto, la domanda più importante è: perché diavolo abbiamo bisogno di una terza via?

[...]

  • La memoria di supporto viene contabilizzata nel processo proprietario del file e non è soggetta a quote di montaggio.

^ Ho ragione nel pensare che la prima parte di questa frase non possa essere invocata?

Il codice memfd_create () è letteralmente implementato come " file non collegato che vive in [a] tmpfs che deve essere interno al kernel ". Tracciando il codice, capisco che differisce nel non implementare i controlli LSM, anche i memfds sono creati per supportare i "sigilli", come spiega il post sul blog. Tuttavia, sono estremamente scettico sul fatto che i memfds siano considerati in modo diverso rispetto a un tmpfile in linea di principio.

In particolare, quando il killer OOM viene a bussare, non penso che spiegherà la memoria trattenuta dai memfds. Questo potrebbe raggiungere il 50% della RAM, ovvero il valore dell'opzione size = per tmpfs . Il kernel non imposta un valore diverso per i tmpfs interni, quindi userebbe la dimensione predefinita del 50%.

Quindi penso che generalmente possiamo aspettarci che processi che contengono un memfd di grandi dimensioni, ma nessun'altra allocazione significativa di memoria, non vengano uccisi da OOM. È corretto?


2
Per quanto riguarda i punteggi OOM, sembra arrivare alla funzione oom_badness del kernel . Quindi sospetto che memfd_create non venga visualizzato in una mappa / proc / {pid} / quindi non viene conteggiato. Quindi la risposta generale è che potrebbero essere uccisi, ma non avranno un punteggio elevato a causa dell'uso di memfd_create. La memoria per il fd può essere condivisa tra più processi poiché più processi possono ereditare / essere inviati, lo stesso fd.
danblack

Risposte:


1

Sulla base della risposta di @ danblack:

La decisione si basa su oom_kill_process()(ripulito un po '):

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 )

Che dipende oom_badness()da trovare il miglior candidato:

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

oom_badness() fa:

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 )

Dove:

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 )

Quindi sembra che conti pagine anonime, che è ciò che memfd_create()utilizza.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.