Runtime: CoreCLR no se ejecuta cuando mlock no está disponible

Creado en 25 jun. 2018  ·  3Comentarios  ·  Fuente: dotnet/runtime

CoreCLR usa mlock durante el inicio y falla si mlock falla con EPERM . Generalmente, eso no es un problema.

Sin embargo, muchas distribuciones de Linux están comenzando a usar systemd-nspawn para crear código. Esto crea un chroot donde los programas tienen capacidades restringidas. Específicamente, no tienen CAP_IPC_LOCK , lo que significa que no pueden usar mlock .

Cuando mlock no funciona, coreclr no se inicia. Esto aparece en un strace como algo como:

mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fbd542bb000
mlock(0x7fbd542bb000, 4096)       = -1 EPERM (Operation not permitted)
write(2, "Failed to initialize CoreCLR, HR"..., 49) = 49

Como resultado, esto hace que sea básicamente imposible compilar coreclr en algunos sistemas de compilación de distribución de Linux.

area-PAL-coreclr os-linux

Comentario más útil

El mlock es necesario para el correcto funcionamiento de la función PAL FlushProcessWriteBuffers que es crucial para garantizar una suspensión confiable del tiempo de ejecución para GC. Consulte https://github.com/dotnet/coreclr/blob/e6ebea25bea93eb4ec07cbd5003545c4805886a8/src/pal/src/thread/process.cpp#L3095 -L3098 para obtener una descripción del motivo.
En Linux 4.3 y versiones posteriores, hay una llamada al sistema sys_membarrier que podríamos usar como mecanismo alternativo para implementar FlushProcessWriteBuffers. El problema dotnet/runtime#4501 está rastreando eso. @sdmaclea intentó implementarlo y lo probó en ARM64. Descubrió que el rendimiento era realmente malo y que el tiempo de ejecución de nuestras pruebas de ~11000 coreclr era aproximadamente un 50 % más largo. Sin embargo, no se realizaron pruebas en otro hardware, por lo que no quedó claro si el problema de rendimiento es específico de ARM64 o es un problema general.
Curiosamente, acabo de descubrir el siguiente artículo que describe problemas de rendimiento con sys_membarrier: https://lttng.org/blog/2018/01/15/membarrier-system-call-performance-and-userspace-rcu/. La razón es que la llamada al sistema espera internamente hasta que todos los subprocesos en ejecución en el sistema hayan pasado por un cambio de contexto, lo que podría demorar decenas de milisegundos. Pero la buena noticia mencionada en este artículo es que, a partir de Linux 4.14, hay un nuevo indicador que se puede pasar a la llamada al sistema sys_membarrier y que hace que use IPI para implementar la semántica de barrera de memoria. Y eso es mucho más rápido. Así que deberíamos darle una oportunidad.

Todos 3 comentarios

cc @tmds @alucryd

Consulte https://github.com/dotnet/source-build/issues/285#issuecomment -399949984 y https://github.com/rpm-software-management/mock/issues/186 para ver algunos ejemplos en los que esto afecta a algunos construye

El mlock es necesario para el correcto funcionamiento de la función PAL FlushProcessWriteBuffers que es crucial para garantizar una suspensión confiable del tiempo de ejecución para GC. Consulte https://github.com/dotnet/coreclr/blob/e6ebea25bea93eb4ec07cbd5003545c4805886a8/src/pal/src/thread/process.cpp#L3095 -L3098 para obtener una descripción del motivo.
En Linux 4.3 y versiones posteriores, hay una llamada al sistema sys_membarrier que podríamos usar como mecanismo alternativo para implementar FlushProcessWriteBuffers. El problema dotnet/runtime#4501 está rastreando eso. @sdmaclea intentó implementarlo y lo probó en ARM64. Descubrió que el rendimiento era realmente malo y que el tiempo de ejecución de nuestras pruebas de ~11000 coreclr era aproximadamente un 50 % más largo. Sin embargo, no se realizaron pruebas en otro hardware, por lo que no quedó claro si el problema de rendimiento es específico de ARM64 o es un problema general.
Curiosamente, acabo de descubrir el siguiente artículo que describe problemas de rendimiento con sys_membarrier: https://lttng.org/blog/2018/01/15/membarrier-system-call-performance-and-userspace-rcu/. La razón es que la llamada al sistema espera internamente hasta que todos los subprocesos en ejecución en el sistema hayan pasado por un cambio de contexto, lo que podría demorar decenas de milisegundos. Pero la buena noticia mencionada en este artículo es que, a partir de Linux 4.14, hay un nuevo indicador que se puede pasar a la llamada al sistema sys_membarrier y que hace que use IPI para implementar la semántica de barrera de memoria. Y eso es mucho más rápido. Así que deberíamos darle una oportunidad.

¿Fue útil esta página
0 / 5 - 0 calificaciones