CoreCLR использует mlock
во время запуска и дает сбой, если mlock
завершается сбоем с EPERM
. Как правило, это не проблема.
Однако многие дистрибутивы Linux начинают использовать systemd-nspawn
для сборки кода. Это создает chroot, в котором программы имеют ограниченные возможности. В частности, у них нет CAP_IPC_LOCK
, что означает, что они не могут использовать mlock
.
Когда mlock
не работает, coreclr не запускается. Это отображается в strace
как что-то вроде:
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
В результате это делает практически невозможным сборку coreclr в некоторых системах сборки дистрибутива Linux.
копия @tmds @alucryd
См. https://github.com/dotnet/source-build/issues/285#issuecomment -399949984 и https://github.com/rpm-software-management/mock/issues/186 для некоторых примеров, когда это поражает некоторые строит
mlock
необходим для правильного поведения функции FlushProcessWriteBuffers PAL, которая имеет решающее значение для обеспечения надежной приостановки выполнения сборщика мусора. См. https://github.com/dotnet/coreclr/blob/e6ebea25bea93eb4ec07cbd5003545c4805886a8/src/pal/src/thread/process.cpp#L3095 -L3098 для описания причины.
В Linux 4.3 и выше есть системный вызов sys_membarrier
, который мы могли бы использовать в качестве альтернативного механизма для реализации FlushProcessWriteBuffers. Проблема dotnet/runtime#4501 отслеживает это. @sdmaclea попытался реализовать это и протестировал на ARM64. Он обнаружил, что производительность была очень плохой, а время выполнения наших ~11000 тестов coreclr было примерно на 50% больше. Однако тестирование на другом оборудовании не проводилось, поэтому неясно, связана ли проблема с производительностью с ARM64 или с общей проблемой.
Интересно, что я только что обнаружил следующую статью, описывающую проблемы производительности с sys_membarrier: https://lttng.org/blog/2018/01/15/membarrier-system-call-performance-and-userspace-rcu/. Причина в том, что системный вызов внутренне ожидает, пока все запущенные потоки в системе не пройдут через переключение контекста, что может занять десятки миллисекунд. Но хорошая новость, упомянутая в этой статье, заключается в том, что, начиная с Linux 4.14, появился новый флаг, который можно передать системному вызову sys_membarrier и который позволяет использовать IPI для реализации семантики барьера памяти. А это гораздо быстрее. Так что мы должны попробовать.
Самый полезный комментарий
mlock
необходим для правильного поведения функции FlushProcessWriteBuffers PAL, которая имеет решающее значение для обеспечения надежной приостановки выполнения сборщика мусора. См. https://github.com/dotnet/coreclr/blob/e6ebea25bea93eb4ec07cbd5003545c4805886a8/src/pal/src/thread/process.cpp#L3095 -L3098 для описания причины.В Linux 4.3 и выше есть системный вызов
sys_membarrier
, который мы могли бы использовать в качестве альтернативного механизма для реализации FlushProcessWriteBuffers. Проблема dotnet/runtime#4501 отслеживает это. @sdmaclea попытался реализовать это и протестировал на ARM64. Он обнаружил, что производительность была очень плохой, а время выполнения наших ~11000 тестов coreclr было примерно на 50% больше. Однако тестирование на другом оборудовании не проводилось, поэтому неясно, связана ли проблема с производительностью с ARM64 или с общей проблемой.Интересно, что я только что обнаружил следующую статью, описывающую проблемы производительности с sys_membarrier: https://lttng.org/blog/2018/01/15/membarrier-system-call-performance-and-userspace-rcu/. Причина в том, что системный вызов внутренне ожидает, пока все запущенные потоки в системе не пройдут через переключение контекста, что может занять десятки миллисекунд. Но хорошая новость, упомянутая в этой статье, заключается в том, что, начиная с Linux 4.14, появился новый флаг, который можно передать системному вызову sys_membarrier и который позволяет использовать IPI для реализации семантики барьера памяти. А это гораздо быстрее. Так что мы должны попробовать.