vm.panic_on_oom = 1일 때 oom_reaper를 사용하는 이유

vm.panic_on_oom = 1일 때 oom_reaper를 사용하는 이유

~에서작가님한테 배웠어요:

OOM 킬러는 현재 작업이 합리적인 시간 내에 종료되고 메모리가 해제되기를 바라는 경우에만 작업 종료를 허용합니다. (…)

위의 핵심 가정을 깨는 워크로드를 구축하는 것이 어렵지 않으며 OOM 피해자가 OOM에서 순환되기를 기다리는 무정전 상태로 차단될 수 있기 때문에 종료하는 데 무한한 시간이 걸릴 수 있음이 나타났습니다(예: 한다 테츠오). 페이지 할당자 다른 작업(예: 잠금)에 의해 차단된 이벤트입니다.

이 패치는 oom 피해자가 소유한 익명 메모리 또는 교체된 메모리를 선제적으로 획득하려고 시도하는 전용 커널 스레드(oom_reaper)를 도입하여 이러한 잠금 가능성을 줄입니다. 단, 소유자가 죽었을 때 추가 메모리가 필요하지 않다고 가정합니다. 사용자 공간에서 쫓겨났습니다.

간단히 말해서, oom_reaper 커널 스레드는 oom_killer가 부적절한 결정을 내릴 가능성을 줄이도록 설계되었습니다.

내가 아는 한RHEL 8 문서:

/proc/sys/vm/panic_on_oom 파일에는 OOM(메모리 부족) 동작을 제어하는 ​​스위치인 값이 포함되어 있습니다. 파일에 1이 포함되면 커널은 OOM으로 인해 패닉이 발생하고 예상대로 작동이 중지됩니다.

기본값은 0이며, 시스템이 OOM 상태에 있을 때 커널이 oom_killer 함수를 호출하도록 지시합니다.

간단히 말해서: vm.panic_on_oom = 1 OOM 상태는 oom_killer 시작을 트리거하지 않습니다.

따라서 논리적으로 oom_reaper 목발이 필요하지 않습니다.

그러나 oom_reaper는 vm.panic_on_oom 값에 관계없이 시스템이 초기화되면(linux-5.4에서) 시작됩니다.

왜? 내가 놓친 것이 있나요? 살인자가 해고되지 않더라도 oom_reaper가 필요한 이유가 있나요? 그렇지 않은 경우 vm.panic_on_oom = 1일 때 oom_reaper가 시작되지 않도록 하는 방법은 무엇입니까?


참고 1: 물론 저는 출신입니다.코드 읽기CONFIG_MMU가 설정되지 않으면 빌드되지 않지만 내 시스템에서는 분명히 옵션이 아닙니다.

답변1

'OOM 킬러' 등 다양한 것들이 있습니다. 커널 통합 최후의 수단 OOM 킬러 기능을 비활성화했습니다. 이는 시작된 데몬과 무관합니다.

수년에 걸쳐 여러 시스템 유틸리티는 시스템이 작동하지 않게 되기 전에 메모리가 폭증하는 프로세스를 종료하는 보다 스마트한 방법을 구현해 왔습니다. 아마도 시스템 OOM 킬러(실제로 작성자를 여러 번 구한)를 다루고 있을 것입니다.

바라보다man oomd.conf구성 방법 알아보기systemd-oomd. 실제로 비활성화하려는 극단적인 경우(왜? 시스템을 복구할 수 없게 만들었습니다!) 다른 systemctl disable xyz.service.

(아, 동일한 프로세스 이름을 가진 COTS NAS 상자를 표적으로 삼는 일부 악성 코드도 있지만 oom_reaper아마도 여러분이 다루고 있는 것은 아닐 것입니다.)

답변2

그 이유는 다음과 같습니다.

어떤 사용자 모드 프로세스가 시스템을 oom할 수 있더라도 첫 번째 사용자 모드 프로그램이 실행되기 전에 oom 상황을 관리하기 위한 기본 프레임워크(oom-killer + oom-reaper)를 준비해야 합니다.
즉, sysV init 또는 systemd로 구성된 시작 프로그램 이전입니다.
즉, sysctl 값이 시스템에 알려지기 전에 이러한 값은 부팅 시 시작되는 sysctl 서비스에 의해 설정되기 때문입니다.

또한 이 설정은 sysctl 또는 /proc/sys/vm/panic_on_oom을 통해 런타임에 변경될 수 있습니다.

이 모든 것이 시작 시 vm.panic_on_oom 설정을 예측할 수 없게 만듭니다.

그것을 제거하는 방법에 관해서는:

코드에 CONFIG_MMU = n이면 빌드되지 않는다고 표시되면 (다행히도) 이는 내 아치에 대한 옵션이 아닙니다. 그러면 oom_reaper가 시작되는 것을 방지하는 가장 직접적인 방법은 이 subsys_initcall(oom_init)줄을 주석 처리하는 것입니다. 하지만 아직까지 부작용에 대해서는 잘 모르겠습니다.

관련 정보