GNU/Linux >> Tutoriales Linux >  >> Linux

Linux:¿es incorrecto pensar que los "memfd" se atribuyen "al proceso propietario del archivo"?

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

Teóricamente, podría lograr [memfd_create() ] comportamiento sin introducir nuevas llamadas al sistema, como esta:

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

(Nota:para garantizar de forma más portátil un tmpfs aquí, podemos usar “/dev/shm ” en lugar de “/tmp “).

Por lo tanto, la pregunta más importante es ¿por qué diablos necesitamos una tercera vía?

[…]

  • La memoria de respaldo se contabiliza para el proceso propietario del archivo y no está sujeta a cuotas de montaje.

^ ¿Tengo razón al pensar que no se puede confiar en la primera parte de esta oración?

El código memfd_create() se implementa literalmente como un "archivo no vinculado que vive en [a] tmpfs que debe ser interno del kernel". Al rastrear el código, entiendo que difiere en no implementar controles LSM, también se crean memfds para admitir "sellos", como explica la publicación del blog. Sin embargo, soy extremadamente escéptico de que los memfds se contabilicen de manera diferente a un tmpfile en principio.

Específicamente, cuando el asesino de OOM llama a la puerta, no creo que tenga en cuenta la memoria en poder de memfds. Esto podría totalizar hasta el 50 % de la RAM:el valor de la opción size=para tmpfs. El kernel no establece un valor diferente para el tmpfs interno, por lo que usaría el tamaño predeterminado del 50 %.

Por lo tanto, creo que, en general, podemos esperar que los procesos que contienen un gran memfd, pero ninguna otra asignación de memoria significativa, no sean eliminados por OOM. ¿Es eso correcto?

Respuesta aceptada:

Sobre la base de la respuesta de @danblack:

La decisión se basa en oom_kill_process() (limpiado un poco):

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)

Que depende de oom_badness() para encontrar al mejor candidato:

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

oom_badness() hace:

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)

donde:

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)

Entonces parece que cuenta páginas anónimas, que es lo que memfd_create() usos.


Linux
  1. Linux:¿cómo configurar la afinidad del procesador de un proceso en Linux?

  2. Linux:¿es el proceso el que tiene una terminal de control o es la sesión la que tiene una terminal de control?

  3. ¿Cuál es la fuente actual del kernel de Linux?

  4. ¿Qué significa &al final de un comando de Linux?

  5. Encontrar el proceso que está usando un determinado puerto en Linux

Cómo cambiar la prioridad de un proceso en Linux

Cómo matar o terminar un proceso de Linux:la guía definitiva

Los 10 sistemas operativos basados ​​en Unix que no son Linux

Cómo encontrar el PID y PPID de un proceso en Linux

Cómo enviar procesos a segundo plano en Linux

¿Qué es la tabla de procesos de Linux? ¿En qué consiste?