1P by GN⁺ | ★ favorite | 댓글 1개
  • AMD RX 570 기반 Linux 데스크톱에서 RAM 사용량이 높은 상태로 절전하면 복귀 후 검은 화면이나 입력 불능 상태가 반복되어, 단순 화면 문제를 넘어 커널 전원 관리 흐름까지 추적해야 했음
  • 핵심 원인은 S3 절전 전에 VRAM을 시스템 RAM으로 백업해야 하는 amdgpu가 여유 RAM 부족 상황에서 디스크 swap을 제대로 활용하지 못하고 OOM으로 무너지는 흐름에 있었음
  • VRAM eviction을 dpm_suspend()에서 dpm_prepare()로 앞당기는 첫 패치는 SSD 전원 차단과의 경합을 줄였지만, pm_restrict_gfp_mask()가 이미 swap을 비활성화해 연속 메모리 부족이 계속 발생할 수 있었음
  • 이후 register_pm_notifier()PM_SUSPEND_PREPARE 시점에 amdgpu_device_evict_resources()를 호출하도록 바꾸자, swap과 디스크가 살아 있는 동안 VRAM을 백업할 수 있어 테스트 환경에서는 고 RAM·VRAM 사용량에서도 절전이 성공함
  • 이 변경은 amdgpu 트리에 병합됐지만 데드락 가능성 때문에 2025-06에 되돌려졌고, 사용자 프로세스를 먼저 freeze하지 않는 절전 경로에서는 3D 앱이 VRAM을 다시 GPU로 끌어오며 eviction을 막을 수 있음

반복된 절전 실패와 초기 오진

  • 데스크톱은 Windows와 Linux를 듀얼부팅하는 구성으로, Linux에서 RAM 사용량이 높을 때 절전을 시도하면 시스템이 자주 깨짐
    • 복귀 후 검은 화면과 움직이는 커서만 보이거나, 화면 출력 없이 magic SysRq 또는 하드 리셋에만 반응함
    • 일부 경우 KDE 잠금 화면 시계는 실시간으로 갱신되지만 로그인이나 상호작용 시 멈춤
  • 테스트 환경은 Gigabyte B550M DS3H, AMD RX 570 GPU, Kingston A2000 1TB NVMe SSD, Arch Linux, systemd-boot, Linux 6.4였음
  • journalctl --system -b -1로 이전 부팅 로그를 확인하자, 일부 절전 시도에서 amdgpu_device_suspend 아래 커널 코드의 OOM 오류가 나타남
  • 많은 실패 사례는 다음 로그에서 끝났고, 깨진 시스템이 다시 깨어난 기록은 남지 않음
    • systemd-sleep: Entering sleep state 'suspend'...
    • kernel: PM: suspend entry (deep)
  • 처음에는 NVMe APST 절전 모드를 의심해 nvme_core.default_ps_max_latency_us=0, iommu=soft, SSD 펌웨어 업그레이드, 2TB 부팅 SSD 교체를 시도했지만 문제가 해결되지 않음

실패 위치를 좁힌 디버깅 도구들

  • systemd가 여러 절전 모드를 연속 시도하는 동작이 로그 노이즈와 커널 상태 악화를 만들 수 있어 /etc/systemd/sleep.confSuspendState=mem을 추가함
    • 디버깅은 단순해졌지만 근본 원인은 그대로 남아 있었음
  • echo 1 > /sys/power/pm_trace로 절전 실패 위치를 추적함
    • pm_trace는 절전-복귀 진행 상태를 시스템 시간에 저장함
    • 비동기 절전이 비활성화되는 부작용 덕분에, amdgpu suspend 실패 후 전체 시스템 hang 대신 복구되는 양상도 확인됨
  • systemd.debug_shell 커널 파라미터를 추가해 KDE나 TTY 로그인 없이도 Ctrl-Alt-F9에서 root shell을 띄울 수 있게 함
  • USB 컨트롤러와 키보드가 깨지는 경우에 대비해 PS/2 키보드를 사용했고, 이후에는 시리얼 콘솔을 구성함
    • 커널 파라미터: no_console_suspend console=tty0 console=ttyS0,115200 loglevel=8
    • 노트북에서 sudo minicom --device /dev/ttyUSB0 --baudrate 115200로 로그를 지속 캡처함
    • 시리얼 콘솔은 디스플레이와 네트워크가 깨진 뒤에도 명령 실행과 로그 수집을 가능하게 했지만, 전송 속도와 색상·화면 크기 처리에는 제약이 있었음

amdgpu VRAM eviction과 OOM의 연결

  • 크래시 로그는 대체로 amdgpu의 TTM 버퍼 eviction 경로에서 발생함
    • amdgpu_device_evict_resources()
    • amdgpu_ttm_evict_resources()
  • 관련 버그 리포트에서 “evict”는 VRAM을 시스템 RAM으로 복사하거나, 시스템 RAM을 swap으로 옮기는 동작과 관련된 것으로 확인됨
  • 데스크톱이 S3 절전에 들어가면 PCIe GPU 전원이 끊기고 VRAM 칩 데이터가 사라짐
    • GPU 드라이버는 절전 전에 사용 중인 VRAM을 시스템 RAM으로 복사해야 함
    • 복귀 후에는 RAM에 저장한 데이터를 다시 복원해야 함
  • Linux amdgpu 드라이버에는 사용 중인 VRAM 전체를 담을 여유 RAM이 없을 때, 시스템 RAM을 디스크 기반 swap으로 옮기는 대신 메모리 부족으로 충돌하는 문제가 있었음
  • Linux가 suspend 중 OOM을 만나면 절전을 취소하고 장치를 다시 시작하려 하지만, 이미 중단된 절전 때문에 일부 드라이버가 깨지거나 suspend/resume 중 다시 OOM이 날 수 있음
    • 비동기 절전이 켜져 있으면 위험이 더 커짐
    • 절전 자체는 성공했지만 resume 중 장치 시작 과정에서 OOM이 발생할 수도 있음

첫 번째 해결 시도: VRAM 백업 시점 앞당기기

  • Mario Limonciello는 /sys/power/pm_print_times/sys/power/pm_debug_messages를 켜고 절전 로그를 확인하라고 제안함
  • 로그에서는 NVMe와 amdgpu 드라이버가 절전 중 pci_pm_suspend병렬 진입하는 것으로 나타남
  • 처음에는 GPU suspend를 SSD suspend보다 앞당기는 방법을 찾았고, Linux의 device suspend ordering 메커니즘도 확인함
    • 이 메커니즘은 모든 GPU를 모든 시스템 디스크보다 먼저 suspend하는 용도보다는 밀접하게 연결된 주변장치 동기화에 더 가까워 보였음
  • Mario는 Linux suspend의 prepare 단계에서 VRAM을 evict하는 방식을 제안했고, VRAM eviction을 dpm_suspend()에서 dpm_prepare()로 옮기는 커널 패치를 작성함
  • 변경 전후 흐름은 다음과 같음
    • 기존: dpm_suspend() 시점에 VRAM 백업이 실행되어 SSD가 꺼지는 흐름과 겹칠 수 있음
    • 변경: dpm_prepare()에서 VRAM 백업을 먼저 시도하고, 실패하면 다른 장치 suspend 전에 절전을 중단함
  • 이 변경은 이전보다 나았지만, pm_restrict_gfp_mask()dpm_prepare()보다 먼저 swap을 비활성화한다는 점 때문에 고 RAM 사용량에서 여전히 실패함
    • amdgpu_ttm_evict_resources()는 연속 메모리 부족으로 실패할 수 있음
    • VRAM을 RAM에 모두 넣더라도 이후 드라이버 할당을 처리할 여유가 부족하면 sleep 또는 wake 중 OOM이 날 수 있음

Ghidra로 찾은 별도 amdgpu 크래시

  • 테스트 중 BUG: unable to handle page fault for address: fffffffffffffffc 오류가 발생했고, 거의 null에 가까운 포인터 역참조처럼 보였음
  • 크래시 로그는 dm_resume+0x200 위치를 가리켰지만 소스 코드의 줄 번호는 제공하지 않음
  • amdgpu.ko 커널 모듈을 저장·추출한 뒤 Ghidra로 디컴파일해 dm_resume 안의 크래시 위치를 커널 소스 라인과 매핑함
  • for_each_new_crtc_in_state(dm->cached_state, crtc, new_crtc_state, i) 매크로에서 문제가 발생함
    • dm->cached_state가 유효한 포인터가 아니라 fffffffffffffff4였음
    • 이후 [RSI + 0x8] 필드를 읽으며 fffffffffffffffc 주소에서 page fault가 발생함
  • 원인은 dm_suspend()drm_atomic_helper_suspend() 반환값을 바로 포인터에 저장한 흐름에 있었음
    • drm_atomic_helper_suspend()는 유효 포인터 또는 ERR_PTR(err)를 반환할 수 있음
    • OOM으로 -ENOMEM (-12)가 반환됐고, amdgpu suspend 코드가 이를 포인터처럼 역참조한 것으로 판단됨
  • Mario는 실패 반환값을 검사하고 suspend를 중단하는 코드를 추가해 이 문제를 수정함

포기한 방향: prepare() 중 swap 허용

  • 고 RAM 사용량에서 절전 실패가 계속된 이유는 amdgpu가 dpm_prepare()에서 VRAM을 백업하지만, 이 시점에는 이미 pm_restrict_gfp_mask()가 디스크 swap을 비활성화했기 때문임
  • 한 가지 시도는 dpm_prepare()에서는 swap을 허용하고, dpm_suspend()가 디스크를 끄기 직전에 swap을 비활성화하는 구조였음
  • 이를 위해 pm_restrict_gfp_mask() 호출을 enter_state()에서 더 깊은 dpm_suspend_start() 내부로 옮기는 실험을 함
  • 실무적 제약이 컸음
    • pm_restrict_gfp_mask()kernel/power/power.h에 선언되어 있고 kernel/power/suspend.c에서 호출됨
    • 호출하려던 위치는 drivers/base/power/main.c였고, 이 파일은 일반적으로 kernel/power/ 헤더를 포함하지 않음
    • 임시 해킹으로 #include <../kernel/power/power.h>를 추가했지만 upstream에는 설득이 필요한 구조였음
  • 하이브리드 절전에서도 정확성 문제가 있었음
    • 하이브리드 절전은 시스템 이미지를 저장하며 pm_restrict_gfp_mask()를 호출한 뒤 swap이 비활성화된 상태로 suspend_devices_and_enter()를 호출함
    • 같은 함수를 다시 호출하면 경고가 발생하고 pm_restore_gfp_mask()가 swap을 다시 켜지 못할 수 있음
  • 테스트에서는 실패 또는 크래시 빈도가 줄었지만 완전히 해결되지는 않았고, core power management를 건드리는 취약한 변경이라 upstream 시도는 하지 않음

사용자 공간 우회책: amdgpu-sleep

  • 2024-10에 SuperTuxKart를 종료한 뒤 절전했다가 복귀 시 검은 화면이 발생함
    • 로그상 첫 절전 시도는 dpm_prepare()에서 OOM이 났고, 다음 시도는 resume 중 amdgpu의 bw_calcs() 메모리 할당 크래시로 이어짐
  • NVIDIA의 사용자 공간 VRAM 백업 방식을 참고함
    • NVIDIA는 systemd가 kernel suspend를 호출하기 전후로 실행되는 서비스에서 /proc/driver/nvidia/suspend에 기록해 VRAM 백업·복원을 수행함
  • 이를 바탕으로 Arch Linux용 amdgpu-sleep 패키지를 만듦
    • 절전 전에 /sys/kernel/debug/dri/1/amdgpu_evict_vram을 읽음
    • 이 debug endpoint는 amdgpu에 모든 VRAM을 시스템 RAM으로 저장하라고 지시함
    • systemd는 GPU VRAM eviction이 끝날 때까지 기다린 뒤 kernel suspend를 시작함
  • 데스크톱에서 절전할 때는 빠르게 VRAM을 메모리로 복사하고, 필요한 경우 RAM을 swap으로 밀어내며 성공함
  • 여러 3D 앱이 실행 중일 때는 앱들이 계속 프레임을 렌더링하며 VRAM을 다시 GPU로 가져와 amdgpu_evict_vram줄다리기 라이브락이 발생함
    • 이 상태는 70초 넘게 지속된 뒤 amdgpu_evict_vram이 포기함
    • 이후 systemd가 kernel suspend를 시작해 userspace를 freeze하면 kernel 단계에서는 VRAM eviction이 성공함
  • 이 스크립트는 livelock이 생기는 빈도보다 스크립트를 끈 상태에서 kernel-level crash가 나는 빈도가 낮지 않아 계속 사용됨

최종 패치: power management notifier

  • 2024-11 Mario는 swap이 아직 활성화된 동안 eviction을 허용하는 패치 테스트를 요청함
  • 패치는 register_pm_notifier()를 호출하는 구조였고, Linux의 power management notifier API를 사용함
  • 콜백은 PM_HIBERNATION_PREPAREPM_SUSPEND_PREPARE 메시지를 받아 amdgpu_device_evict_resources()를 호출함
  • PM_SUSPEND_PREPAREenter_state() → suspend_prepare()에서 pm_notifier_call_chain_robust(PM_SUSPEND_PREPARE, PM_POST_SUSPEND)를 통해 발행됨
    • notifier 콜백이 있는 드라이버에 PM_SUSPEND_PREPARE가 전달됨
    • 실패가 발생하면 이미 준비한 드라이버에 PM_POST_SUSPEND가 전달되고 절전은 중단됨
  • 이 위치에서 VRAM을 evict하면 pm_restrict_gfp_mask()가 swap을 비활성화하기 전이고, 디스크도 아직 freeze되지 않은 상태임
  • 수정된 흐름은 다음과 같음
    • suspend_prepare()
    • PM_SUSPEND_PREPARE
    • amdgpu_device_pm_notifier() → amdgpu_device_evict_resources()
    • pm_restrict_gfp_mask()
    • dpm_prepare()
    • dpm_suspend()
  • 수정된 amdgpu 드라이버를 포함한 커스텀 커널을 빌드해 테스트한 결과, 고 RAM·VRAM 사용량에서 여러 차례 절전해도 오류가 발생하지 않음
  • 다만 amdgpu가 PipeWire나 kernel이 스피커를 음소거하기 전에 VRAM을 백업하면서 몇 초간 오디오가 반복 재생되는 현상이 나타남
  • 몇 차례 코드 리뷰 후 이 변경은 amdgpu tree에 병합됐고, 1년 넘는 시도 끝에 해당 버그를 해결하는 단계로 이어짐

2025-06 업데이트와 되돌림

  • 처음에는 변경이 stable Linux kernel 6.14에 포함될 것으로 예상됐지만, 이후 가능한 데드락 때문에 revert됨
  • 새로 도입된 문제는 systemd가 모든 사용자 공간 프로세스를 먼저 freeze하지 않고 system suspend를 호출하는 경우에 발생함
    • kernel이 자체적으로 프로세스를 freeze하기 전에 VRAM을 시스템 RAM으로 evict하려고 함
    • 동시에 3D 프로그램이 VRAM을 다시 GPU로 가져오면 suspend eviction 과정이 deadlock될 수 있음
  • 이는 사용자 공간 amdgpu_evict_vram 우회책에서 겪은 라이브락과 유사함
  • Linux PM maintainer는 pm_restrict_gfp_mask() 호출을 suspend_devices_and_enter() 안쪽으로 옮기는 방안을 제안함
    • 이는 앞서 실험했던 prepare() 중 swap 허용 방향과 맞닿아 있음
  • 직접 구현·제출할 계획은 없음
    • AMD GPU를 더 느린 CPU와 8GB 메모리를 가진 오래된 컴퓨터로 옮겼고, 그 환경에서 커널 빌드를 돌리고 싶지 않기 때문임
  • 메인 컴퓨터는 Intel Arc B570으로 업그레이드했지만, 10GB VRAM에서도 같은 유형의 문제가 발생함
    • 해당 문제는 drm/xe kernel bug tracker에 보고됨

댓글과 토론

Hacker News 의견들
  • 데스크톱이 S3 절전에 들어가면 PCIe GPU 전원이 끊긴다는 가정은 확실치 않음
    S3는 RAM을 제외한 모든 전원을 끊는 게 맞지만, 예를 들어 Gigabyte Aorus 메인보드는 NVMe SSD 절전 버그로 시스템이 제대로 잠들거나 깨어나지 못하는 일이 악명 높음
    보통 모든 PCIe 포트의 깨우기를 막는 udev 규칙으로 우회 가능함: ACTION=="offline", SUBSYSTEM=="pci", DRIVER=="pcieport", ATTR{power/wakeup}="disabled"
    더 좁게는 문제 PCIe 포트만 ATTR{vendor}=="0x8086", ATTR{device}=="0x43bc"처럼 지정할 수 있고, /proc/acpi/wakeup, /sys/class/pci_bus/*/*/yourWakeupDevicePci/uevent | grep PCI_ID, udevadm info --attribute-walk /dev/whatever로 원인을 찾을 수 있음
    udev 대신 systemd 서비스나 자동화 스크립트에서 /proc/acpi/wakeup을 토글할 수도 있지만 덜 안정적이고, 이런 Linux 절전 문제는 정말 지긋지긋함

    • 내 메인보드에서는 /etc/udev/rules.d/ACTION=="add", KERNELS=="0000:00:01.1", ATTR{power/wakeup}="disabled"를 넣어 자발적 깨우기를 막아야 했음
      Logitech Bolt 수신기도 여러 Linux 컴퓨터를 즉시 깨우는데 Windows에서는 그렇지 않은 이유를 모르겠고, USB 캡처를 해보려면 로직 애널라이저나 Glasgow 같은 장비가 필요한지도 애매함
      임시로 ACTION=="add", SUBSYSTEM=="usb", DRIVERS=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c548", ATTR{power/wakeup}="disabled" 규칙을 추가해 막아둠
    • Aorus 메인보드에서 이 문제로 몇 kWh는 날린 것 같아서 해결책을 기대했지만, 내 경우에는 효과가 없었음
    • X570 Aorus Master에서도 절전 문제를 겪고 있었는데, 부팅 시 systemd 유닛에서 echo GPP0 >> /proc/acpi/wakeup을 실행하면 해결됐음
      다만 부팅 후 첫 절전은 항상 즉시 깨어났는데, 위의 udev 규칙을 적용하니 그 문제도 해결된 듯함
    • 하드웨어가 실제로 잠들었는지 탐지할 수 있거나, 잠들지 않았던 하드웨어를 다시 깨워도 문제가 없게 되어 있기를 기대하게 됨
      PCIe 장치에 절전 명령을 보낸 뒤 버스 자체를 잠재우고, 깨울 때는 버스를 먼저 되살린 다음 장치를 깨우는 식이 가능해야 할 것 같음
    • 이 문제로 한동안 고생했지만 이 방법도 통하지 않았고, 정리한 내용은 https://bbs.archlinux.org/viewtopic.php?id=302440에 있음
      내 경우 깨우기 원인이 .../devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:45/wakeup/wakeup6에서 오는 듯한데, 이 경로가 뭘 의미하는지 잘 모르겠음
  • 언급된 사용자 공간 우회책 중 하나인 memreserver 작성자로서, 몇 년 전 이 문제를 디버깅했음
    빠르게 찾을 수 있는 공개 코멘트는 https://gitlab.freedesktop.org/drm/amd/-/issues/2125#note_17...이고, 메일링 리스트 논의도 있었던 걸로 기억함
    핵심은 Linux에 디스크와 메모리 하위 시스템 일부가 얼기 전에 안정적으로 실행되는 단계적 suspend 훅이 없었다는 점이었고, 이제는 가능한 듯함
    안타깝게도 Freedesktop Gitlab은 색인이 잘 안 되는 것 같아 이 지식이 묻힌 듯함

  • 정말 훌륭한 작업임
    왜 Linux에서 절전 전환을 제대로 동작시키기 어렵고 디버깅도 어려운지 궁금했다면, 이 글 하나만으로도 망가질 수 있는 지점이 얼마나 많은지 잘 보여줌
    지금도 ThinkPad P1G4에서 절전 전에 팬을 직접 끄지 않으면 자동으로 꺼지지 않고, 최근에는 절전 복귀 후 Bluetooth 헤드폰에서 잡음이 생겨 PipeWire의 노드 절전도 꺼야 했음: https://wiki.archlinux.org/title/PipeWire#Noticeable_audio_d...

    • 2025년인데도 Linux 노트북의 sleep/suspend가 여전히 제대로 안 된다는 게 놀라움
      처음 이런 문제를 겪은 게 아마 15년 전쯤이었음
    • 절전은 정말 복불복이고, 글에 나온 것 같은 오류는 디버깅도 매우 어려움
      여러 문제에 제안되는 우회책 중에는 전력 절약 모드를 끄는 것들이 있는데, 절전을 쓰는 목적이 보통 배터리 사용 시간을 늘리는 것이므로 이런 방식은 실사용 시간이 크게 줄어들 수 있어 별로 현실적이지 않음
      그래도 S0ix 절전을 동작시키는 게 불가능한 건 아님
      AMD 7840U와 AMD 8840U 기반 휴대용 기기들, 즉 GPD Win Max 2, GPD Win Mini, GPD Win 4, Minisforum V3, OneXPlayer X1 Ryzen에 Arch Linux를 설치했는데, 이 회사들이 Linux 지원을 염두에 두고 설계하거나 테스트했을 가능성은 낮아 보임
      그런데 /proc/acpi/wakeup/sys/devices/*/*/*/power/wakeup에서 가짜 깨우기 소스를 조금 조정하는 정도만으로 최신 OneXPlayer X1 Ryzen을 제외하면 거의 완벽한 S0ix 지원을 얻었음
      기본 Linux 커널 지원도 훌륭해서 터치스크린, 펜 입력, Wi-Fi, Bluetooth가 잘 되고, 본 유일한 빈틈은 지문 인식기 지원임
      이런 소규모 제조사는 부품의 극단적 맞춤화나 치밀한 통합이 덜하고, 실제로 기기들이 몇 mm씩 더 두꺼운 형태로 드러남
      그래서 더 보수적인 부품 선택을 하게 되고, 그 결과 Linux 지원이 의외로 좋은 것일 수 있음
    • 최종 사용자가 절전을 쉽게 잘 쓰려면 검증된 호환 하드웨어를 사는 게 답임
      내 경험상 비즈니스 ThinkPad에서는 오래전부터 매우 안정적이었고, 같은 모델의 Windows 사용자들이 오히려 절전 문제를 더 자주 겪는 것처럼 보임
  • 개인적으로 정말 고마움
    주 노트북이 Linux를 돌리는 Ryzen 기반 ThinkPad이고 절전과 최대 절전을 자주 쓰는데, 이 문제를 간헐적으로 겪어왔음
    Linux 6.14가 기대됨

  • dm->cached_state가 포인터 대신 -12를 저장한 이유는 아마 suspend 중 dm_suspend()dm.cached_state = drm_atomic_helper_suspend(adev_to_drm(adev))를 그대로 대입했기 때문일 가능성이 큼
    호출된 drm_atomic_helper_suspend()는 유효한 포인터나 음수 포인터로 오류를 인코딩한 ERR_PTR(err)를 반환할 수 있는데, 호출자가 오류를 검사하지 않고 포인터에 바로 넣었다가 resume 때 역참조한 것임
    커널에 Rust를 넣어야 할 이유가 하나 더 늘었고, Result 타입 처리가 강제되면 이런 일은 생기기 어려움

    • C 전처리기로도 대수적 합 타입을 만들 수 있음: https://github.com/Hirrolot/datatype99
      하지만 기본값이 중요하고, 커널이 코딩 관행 현대화를 오래 미뤄온 역사가 C 쪽 개선에는 불리하게 작용함
      아이러니하게도 같은 저항 때문에 Rust 개발자들도 좌절하는데, 각 하위 시스템을 정리하거나 동작 방식을 문서로 남기는 것조차 잘 받아들여지지 않기 때문임
      https://github.com/llvm/llvm-project/issues/74205 같은 게 커널까지 내려오면 도움이 될 수도 있지만, 그래도 타입으로 안전성을 확보하기보다는 포인터를 수동으로 오버로딩하는 방식을 계속 고를 것 같음
  • GPU 확장 모듈을 단 Framework AMD 노트북에서 Linux/Windows 듀얼 부팅을 쓰고 있어서 이 작업이 도움이 될 것 같음
    직접 후원하거나 선호하는 자선단체에 기부하고 싶은데, 연락처는 프로필에 있음

  • 이름 짓기, 캐시 무효화, off-by-one 오류가 컴퓨터 과학의 가장 큰 두 문제라고 생각했는데, sleep/wake 문제를 알고 나니 이건 NP-완전으로 보임

    • sleep/wake는 캐시 무효화의 부분집합이라고 봄
      모든 주변장치가 상태를 가지지 않는다면 아마 문제가 아니었을 것임
    • Linux에서만 그렇고, Windows에서는 O(n²), macOS에서는 O(log n)임
  • Linux에서 메모리 관리와 특히 OOM 상황은 여전히 믿기 어려울 만큼 고통스러운 악몽임
    이런 문제를 항상 겪는 건 아니지만 비슷한 문제를 디버깅하려다 실패한 적이 분명 있고, 결국 OOM이 나면 보통 RAM을 더 꽂게 됨
    낭비이고 비싸지만, OOM 상황을 우아하게 처리하는 일은 앞으로도 Linux가 풀기 어려운 문제일 듯함
    이번 작업은 훌륭하고, 앞으로 비슷한 문제를 디버깅할 때 기준점이 될 것임
    systemd의 debug-shell 기능도 반갑고 그런 기능이 있는 줄 몰랐음
    다만 내 X670E Steel Legend 보드에는 시리얼 헤더가 없는 것 같은데, 요즘 내장 시리얼 포트는 어떻게 동작하는지 궁금함
    칩셋 PCIe 레인에 붙어 있는 걸까
    Linux 커널을 파고들 때 FOSDEM이나 Linux Plumbers Conference 같은 곳의 커널 하위 시스템 발표 녹화가 큰 도움이 되며, 예를 들어 대부분의 데스크톱 GPU DRM 드라이버가 쓰는 TTM 메모리 하위 시스템 영상은 이쪽임: https://www.youtube.com/watch?v=MG7_tUNKSt0

    • Windows에서는 내 메인보드의 시리얼 포트가 Pci Bus → PCI standard ISA bridge에 연결됐다고 나옴
      DOS 만세
      TTM 영상은 시간 날 때 보겠음
    • OOM을 cgroups로 가두는 건 꽤 잘 됐음
      Linux가 하는 것보다 더 나은 최신 OOM 처리 방식이 있는지는 잘 모르겠고, 관련해서 읽을 만한 자료가 있다면 알고 싶음
    • 맞음, 좋게 말해도 끔찍함
      Linux는 OOM 상황을 제대로 처리하지 못함
      cgroups로 가드레일을 세울 수 있고, earlyoom을 설치할 수도 있고, swap을 늘리거나 zram을 쓸 수도 있다는 건 알고 있음
      하지만 결국 전부 가끔 한 번 살려줄 수 있는 지저분한 해킹일 뿐이고, 이런 상황이 처리되는 방식을 고치지는 못함
      이런 걸 해결책으로 제시하지 않았으면 함
      커널이 dm_crypt에서 메모리를 할당하지 못해 LUKS 볼륨이 스스로 읽기 전용으로 마운트되는 걸 봤는데, 제발 사용자 공간 프로세스 하나를 죽이면 됨
      현재 상태는 도저히 받아들일 수 없고 변명도 지쳤음
    • zswap/zram을 써봤는지 궁금함
      zstd를 쓰면 8GB RAM을 별 문제 없이 20GB ‘RAM’처럼, 16GB를 40GB처럼 쓸 수 있음
      더 과감하게는 메모리를 100% 넘게 오버커밋할 수도 있고, Android도 이렇게 하니 꽤 안정적인 방식임
  • 좋은 소식임
    AMD의 Linux 그래픽 드라이버는 대체로 잘 동작했지만, 이 문제만큼은 여러 번 겪은 예외였음

    • 내 운은 조금 덜 좋았음
      최근 겪는 문제는 절전에서 깨어난 뒤 드라이버가 WARNING: CPU: 12 PID: 11871 at drivers/gpu/drm/amd/amdgpu/../display/dc/dc_helper.c:100 generic_reg_update_ex+0x1d2/0x290 [amdgpu] 이후 "[drm] scheduler comp_1.0.n is not ready, skipping"을 로그에 계속 뿌리는 것임
      https://gitlab.freedesktop.org/drm/amd/-/issues/3911
    • 나도 전반적으로 좋은 경험이지만, 기기가 잠든 상태에서 모니터가 연결된 Thunderbolt를 분리하면 비슷한 문제가 생김
      다만 노트북이라 드라이버 구성이 많이 다르고 PCIe GPU도 없음
  • amdgpu.ko 커널 모듈을 저장해서 꺼내고, Ghidra로 디컴파일한 다음, dm_resume의 크래시 위치를 커널 소스의 해당 줄에 매핑했다는 부분이 디버깅에서 늘 가장 좋아하는 장면임