GNU/Linux >> Linux Esercitazione >  >> Linux

Linux:è sbagliato pensare a "memfd" come contabilizzato "al processo che possiede il file"?

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

In teoria, potresti ottenere [memfd_create() ] comportamento senza introdurre nuove 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 backup viene contabilizzata nel processo che possiede il file e non è soggetta a quote di montaggio.

^ Ho ragione nel pensare che la prima parte di questa frase non sia affidabile?

Il codice memfd_create() è letteralmente implementato come un "file non collegato che vive in [a] tmpfs che deve essere interno al kernel". Tracciando il codice, capisco che differisca nel non implementare i controlli LSM, inoltre i memfd sono creati per supportare i "sigilli", come spiega il post del blog. Tuttavia, sono estremamente scettico sul fatto che i memfd siano contabili in linea di principio diversamente da un tmpfile.

In particolare, quando l'OOM-killer bussa, non penso che spiegherà la memoria detenuta da memfds. Questo potrebbe ammontare fino al 50% della RAM - il valore dell'opzione size=per tmpfs. Il kernel non imposta un valore diverso per il tmpfs interno, quindi utilizzerà la dimensione predefinita del 50%.

Quindi penso che in genere possiamo aspettarci che i processi che contengono un grande memfd, ma nessun'altra allocazione di memoria significativa, non vengano uccisi dall'OOM. È corretto?

Risposta accettata:

Basandosi sulla 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 da oom_badness() per 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 conteggi le pagine anonime, che è ciò che è memfd_create() utilizza.


Linux
  1. Trova il tempo di esecuzione di un comando o di un processo in Linux

  2. Come trovare il pacchetto che fornisce un file specifico in Linux

  3. Linux:come impostare l'affinità del processore di un processo su Linux?

  4. Cosa significa &alla fine di un comando Linux?

  5. Qual è la definizione di una sessione in Linux?

Come modificare la priorità di un processo in Linux

Come uccidere o terminare un processo Linux:la guida definitiva

I 10 sistemi operativi basati su Unix che non sono Linux

Come trovare il PID e il PPID di un processo in Linux

Come inviare processi in background su Linux

Qual è la tabella dei processi Linux? In cosa consiste?