Rocky Linux 8.9 - THP(Transparent Huge Pages)로 인한 커널 I/O 교착 및 비정상 재부팅 원인

반응형
Rocky Linux 8.9 - THP(Transparent Huge Pages)로 인한 커널 I/O 교착 및 비정상 재부팅 원인 분석

Rocky Linux 8.9 - THP(Transparent Huge Pages)로 인한 커널 I/O 교착 및 비정상 재부팅 원인 분석

1️⃣ 장애 개요

Rocky Linux 8.9 기반의 VM 서버에서 새벽 시간대에 예고 없이 재부팅이 발생했습니다. 시스템 로그(/var/log/messages)를 확인한 결과, 커널 레벨에서 다음과 같은 경고 메시지가 반복 출력된 직후 시스템이 멈추고 watchdog이 강제 재부팅을 수행한 것으로 확인되었습니다.

Nov  2 11:10:01 kernel: INFO: task khugepaged:51 blocked for more than 120 seconds.
Nov  2 11:10:01 kernel: task:khugepaged state:D stack:0 pid:51 ppid:2 flags:0x80004000
Nov  2 11:10:01 kernel: Call Trace:
Nov  2 11:10:01 kernel: __schedule+0x2d1/0x870
Nov  2 11:10:01 kernel: schedule_timeout+0x281/0x320
Nov  2 11:10:01 kernel: lru_add_drain_all+0x13f/0x190
Nov  2 11:10:01 kernel: INFO: task jbd2/dm-1-8:667 blocked for more than 120 seconds.
Nov  2 11:10:01 kernel: task:jbd2/dm-1-8 state:D stack:0 pid:667 ppid:2 flags:0x80004000
Nov  2 11:10:01 kernel: jbd2_journal_commit_transaction+0x14d6/0x19f0 [jbd2]

이 로그는 커널의 khugepagedjbd2 스레드가 모두 “D 상태 (Uninterruptible Sleep)”에 진입해 I/O 요청을 완료하지 못하고 교착된 상황을 의미합니다. 즉, **디스크 쓰기 작업이 응답하지 않아 커널 스케줄러 자체가 정지한 상태**입니다.

2️⃣ 원인 분석

장애 당시의 환경은 다음과 같습니다.

  • OS 버전: Rocky Linux release 8.9 (Green Obsidian)
  • 커널 버전: 4.18.0-513.5.1.el8_9.x86_64
  • VM 환경: KVM 기반 가상머신 (스토리지: virtio-blk)
  • 파일시스템: LVM + ext4
  • THP 상태: [always] madvise never — 항상 활성화

위 조합은 RHEL 8.9 기반에서 이미 보고된 THP(Transparent Huge Pages)와 ext4/jbd2 간 Deadlock 버그의 대표적인 조건과 일치합니다.

특히 커널 버전 4.18.0-513.5.1.el8_9 에서는 khugepaged (THP 병합 데몬)가 ext4 저널링 프로세스(jbd2)의 락을 동시에 요청하면서 커널 스케줄링 순서가 꼬이는 현상이 발생할 수 있습니다.

3️⃣ THP(Transparent Huge Pages)란?

Transparent Huge Pages는 리눅스가 메모리 효율을 높이기 위해 도입한 기능입니다. 일반적으로 리눅스는 4KB 단위의 페이지로 메모리를 관리하지만, THP는 이를 2MB 단위의 huge page로 묶어 관리합니다.

  • ✅ CPU TLB 캐시 미스(TLB miss) 감소 → 메모리 접근 속도 향상
  • ✅ 애플리케이션 수정 없이 자동 적용
  • ❌ 메모리 병합 중 CPU 점유 증가 및 커널 락 경합 가능
  • ❌ ext4/LVM 환경에서는 I/O 요청이 장시간 대기 상태에 머물 가능성

일반 서버에서는 성능 향상 효과가 있으나, DB·파일시스템·LVM을 사용하는 환경에서는 오히려 I/O 교착(lock) 문제를 유발할 수 있습니다.

🔍 현재 서버 설정 확인 예시

# cat /sys/kernel/mm/transparent_hugepage/enabled
[always] madvise never

이 상태는 always로 THP가 항상 작동 중임을 의미합니다. 따라서 커널 I/O 락 교착이 발생할 가능성이 높은 설정입니다.

4️⃣ 재현 가능한 시나리오

  • 파일 I/O가 집중된 시점(예: 백업, 로그 로테이션)
  • 메모리 병합(THP) 스레드가 active
  • LVM layer를 통해 ext4 디스크에 동시에 flush 발생

이때 khugepaged 스레드가 페이지 병합을 시도하며, jbd2 프로세스와 동일한 페이지 락을 요청하면 다음과 같은 순환대기(deadlock)가 발생합니다.

khugepaged → ext4 → jbd2 → memory allocator → khugepaged

결과적으로 커널 스케줄러가 응답하지 못해 watchdog이 시스템을 강제 재부팅하게 됩니다.

5️⃣ 해결 방법

① THP 비활성화 (즉시 조치)

# echo never > /sys/kernel/mm/transparent_hugepage/enabled
# cat /sys/kernel/mm/transparent_hugepage/enabled
always madvise [never]

이 명령으로 즉시 THP 기능이 꺼집니다. [never] 로 표시되면 비활성화가 완료된 상태입니다.

② 부팅 시 자동 비활성화 (영구 조치)

# cat < /etc/systemd/system/disable-thp.service
[Unit]
Description=Disable Transparent Huge Pages
[Service]
Type=oneshot
ExecStart=/bin/sh -c "echo never > /sys/kernel/mm/transparent_hugepage/enabled"
[Install]
WantedBy=multi-user.target
EOF

# systemctl enable disable-thp

다음 부팅 이후에도 자동으로 THP가 꺼집니다.

③ 커널 업데이트

Red Hat에서 배포된 4.18.0-513.24.1.el8_9 이후 버전에서는 해당 deadlock 버그가 수정되었습니다.

# dnf update kernel -y
# reboot

④ 추가 권장 설정

  • kdump 활성화 — 커널 크래시 덤프 수집
  • sysstat 활성화 — CPU/I/O 통계 저장
  • systemd-journald 영구저장 설정 — 재부팅 전 로그 보존

6️⃣ 검증 및 결과

THP 비활성화 후 동일 부하 조건에서 khugepagedjbd2 교착 현상은 재발하지 않았습니다. 또한 sariostat 결과에서도 I/O 대기율(%iowait)이 3% 미만으로 안정화되었습니다.

# sar -u 1 5
avg-cpu:  %user  %system  %iowait  %idle
           7.25    0.80     2.74    89.21

즉, THP 비활성화로 인해 커널 I/O 스케줄링이 안정화되고 시스템 재부팅 현상이 해소되었습니다.

7️⃣ 결론 요약

  • 문제 커널: 4.18.0-513.5.1.el8_9.x86_64
  • 원인: THP와 ext4/jbd2 병행으로 인한 커널 Deadlock
  • 증상: 커널 hang → watchdog reboot
  • 조치: THP 비활성화 + 커널 업데이트

요약: THP(Transparent Huge Pages)는 CPU 성능 향상에는 유리하지만, I/O 중심 서버에서는 교착 문제를 유발할 수 있습니다. 따라서 Rocky Linux 8.9 기반 커널에서는 THP를 never 로 설정하고 커널을 최신 버전으로 유지하는 것이 가장 안정적입니다.

8️⃣ 기본 오류 대응 4단계

  • ① 장애 로그 확인 (/var/log/messages, dmesg)
  • ② 커널 관련 프로세스 상태 점검 (khugepaged, jbd2)
  • ③ THP 상태 확인 및 비활성화
  • ④ 커널 업데이트 및 kdump 활성화
반응형
LIST