Runtime: CoreCLR kann nicht ausgeführt werden, wenn mlock nicht verfügbar ist

Erstellt am 25. Juni 2018  ·  3Kommentare  ·  Quelle: dotnet/runtime

CoreCLR verwendet mlock während des Starts und schlägt fehl, wenn mlock mit EPERM fehlschlägt. Im Allgemeinen ist das kein Problem.

Viele Linux-Distributionen beginnen jedoch, systemd-nspawn zum Erstellen von Code zu verwenden. Dadurch wird eine Chroot erstellt, in der Programme eingeschränkte Fähigkeiten haben. Insbesondere haben sie kein CAP_IPC_LOCK , was bedeutet, dass sie mlock nicht verwenden können.

Wenn mlock nicht funktioniert, kann coreclr nicht gestartet werden. Dies zeigt sich in einem strace wie folgt:

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

Infolgedessen ist es im Grunde unmöglich, coreclr in einigen Linux-Distributions-Build-Systemen zu erstellen.

area-PAL-coreclr os-linux

Hilfreichster Kommentar

Das mlock ist für das ordnungsgemäße Verhalten der FlushProcessWriteBuffers PAL-Funktion erforderlich, die für die Sicherstellung einer zuverlässigen Laufzeitunterbrechung für GC von entscheidender Bedeutung ist. Siehe https://github.com/dotnet/coreclr/blob/e6ebea25bea93eb4ec07cbd5003545c4805886a8/src/pal/src/thread/process.cpp#L3095 -L3098 für eine Beschreibung des Grundes.
Unter Linux 4.3 und höher gibt es einen sys_membarrier Systemaufruf, den wir als alternativen Mechanismus zum Implementieren von FlushProcessWriteBuffers verwenden könnten. Issue dotnet/runtime#4501 verfolgt dies. @sdmalea hat versucht, es zu implementieren und auf ARM64 getestet. Er hat festgestellt, dass die Leistung wirklich schlecht war und dass die Laufzeit unserer ~11000 Coreclr-Tests etwa 50 % länger war. Es wurden jedoch keine Tests auf anderer Hardware durchgeführt, sodass nicht klar war, ob das Leistungsproblem ARM64-spezifisch oder ein allgemeines Problem ist.
Interessanterweise habe ich gerade den folgenden Artikel entdeckt, der Leistungsprobleme mit sys_membarrier beschreibt: https://lttng.org/blog/2018/01/15/membarrier-system-call-performance-and-userspace-rcu/. Der Grund dafür ist, dass der Systemaufruf intern wartet, bis alle laufenden Threads auf dem System einen Kontextwechsel durchlaufen haben, was mehrere zehn Millisekunden dauern kann. Aber die gute Nachricht, die in diesem Artikel erwähnt wird, ist, dass es ab Linux 4.14 ein neues Flag gibt, das an den sys_membarrier-Systemaufruf übergeben werden kann und das IPI zur Implementierung der Speicherbarrieren-Semantik verwendet. Und das geht viel schneller. Also sollten wir es versuchen.

Alle 3 Kommentare

cc @tmds @alucryd

Das mlock ist für das ordnungsgemäße Verhalten der FlushProcessWriteBuffers PAL-Funktion erforderlich, die für die Sicherstellung einer zuverlässigen Laufzeitunterbrechung für GC von entscheidender Bedeutung ist. Siehe https://github.com/dotnet/coreclr/blob/e6ebea25bea93eb4ec07cbd5003545c4805886a8/src/pal/src/thread/process.cpp#L3095 -L3098 für eine Beschreibung des Grundes.
Unter Linux 4.3 und höher gibt es einen sys_membarrier Systemaufruf, den wir als alternativen Mechanismus zum Implementieren von FlushProcessWriteBuffers verwenden könnten. Issue dotnet/runtime#4501 verfolgt dies. @sdmalea hat versucht, es zu implementieren und auf ARM64 getestet. Er hat festgestellt, dass die Leistung wirklich schlecht war und dass die Laufzeit unserer ~11000 Coreclr-Tests etwa 50 % länger war. Es wurden jedoch keine Tests auf anderer Hardware durchgeführt, sodass nicht klar war, ob das Leistungsproblem ARM64-spezifisch oder ein allgemeines Problem ist.
Interessanterweise habe ich gerade den folgenden Artikel entdeckt, der Leistungsprobleme mit sys_membarrier beschreibt: https://lttng.org/blog/2018/01/15/membarrier-system-call-performance-and-userspace-rcu/. Der Grund dafür ist, dass der Systemaufruf intern wartet, bis alle laufenden Threads auf dem System einen Kontextwechsel durchlaufen haben, was mehrere zehn Millisekunden dauern kann. Aber die gute Nachricht, die in diesem Artikel erwähnt wird, ist, dass es ab Linux 4.14 ein neues Flag gibt, das an den sys_membarrier-Systemaufruf übergeben werden kann und das IPI zur Implementierung der Speicherbarrieren-Semantik verwendet. Und das geht viel schneller. Also sollten wir es versuchen.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen