리눅스 커널 eBPF 락(Lock) 문제, 250ms 시스템 프리징의 비밀

by DD
2개월 전
조회수 6

Superluminal CPU 프로파일러 사용 중, Fedora 42 시스템 프리징(System Freezing) 현상 발생

eBPF 코드와 커널 내부의 락(Lock) 메커니즘 간의 상호작용에서 문제 원인 규명

rqspinlock의 AA 데드락(Deadlock) 감지 실패 및 NMI 인터럽트(Interrupt)로 인한 250ms 타임아웃(Timeout) 문제 발견

커널 코드 수정 및 패치를 통해 문제 해결(Problem Solving), 6.19 커널에 반영

문제 발생: Superluminal 프로파일러와 시스템 프리징

기사에서는 Superluminal CPU 프로파일러 사용 중 발생한 시스템 프리징 현상을 상세히 설명한다. 특히, Fedora 42 환경에서 프로파일러를 실행하면 시스템이 주기적으로 250ms 이상 멈추는 문제가 발생했다. 문제 재현(Reproduction)을 위해 다양한 환경을 시도한 끝에 물리 머신에서 문제를 재현하는 데 성공했다. 이는 eBPF 코드와 커널 내부의 락(Lock) 메커니즘 간의 상호 작용에서 기인한 것으로 밝혀졌다.

디버깅 과정: 커널 내부 깊숙이

저자는 커널 프리징 문제를 해결하기 위해 커널 디버깅을 시도했지만, gdb가 응답하지 않는 문제에 직면했다. 최소 재현(Minimal Reproduction)을 위해 eBPF 코드를 분석하고, 샘플링(Sampling) 및 컨텍스트 스위치(Context Switch) 이벤트의 상호 작용에 주목했다. eBPF 코드의 락(Lock) 사용과 NMI(Non-Maskable Interrupt)의 상호 작용으로 인해 250ms 타임아웃(Timeout)이 발생한다는 가설을 세웠다.

락(Lock) 메커니즘 심층 분석: qspinlock과 rqspinlock

기사에서는 리눅스 커널의 락(Lock) 메커니즘인 qspinlock과 eBPF 시스템에서 사용되는 rqspinlock에 대한 심층적인 분석을 제공한다. qspinlock은 MCS 락(Lock)을 기반으로 하며, 캐시 라인 바운싱(Cache Line Bouncing)과 락(Lock) 공정성 문제를 해결한다. rqspinlock은 qspinlock을 기반으로 하며, 데드락(Deadlock)을 감지하고 복구하는 기능을 제공한다. rqspinlock의 AA 데드락(Deadlock) 감지 실패가 문제의 핵심 원인으로 지목되었다.

문제 해결 및 패치: NMI와 락(Lock)의 충돌

문제 해결을 위해 rqspinlock의 AA 데드락(Deadlock) 감지 코드를 수정하여 NMI 인터럽트(Interrupt) 발생 시에도 락(Lock) 획득 문제를 해결했다. 구체적으로, 락(Lock) 획득 전에 held lock table을 업데이트하도록 코드를 변경했다. 또한, 1-2ms 및 6-26ms 타임아웃(Timeout) 문제를 해결하기 위해 check_timeout 함수와 rqspinlock slow path를 수정했다. 이러한 수정 사항은 리눅스 커널 6.19 버전에 반영되었다.

결론: 락(Lock) 문제의 중요성

결론적으로, 이번 사건은 리눅스 커널 내부의 락(Lock) 메커니즘과 eBPF 코드의 상호 작용에서 발생한 문제를 해결하는 과정을 보여준다. 특히, NMI 인터럽트(Interrupt)와 락(Lock)의 상호 작용으로 인한 시스템 프리징(System Freezing) 문제를 해결하는 과정에서 락(Lock)의 중요성을 강조한다. 또한, 커널 개발자가 아닌 eBPF 프로그램 작성자가 락(Lock) 메커니즘의 세부 사항을 이해하기 어렵다는 점을 지적하며, rqspinlock과 같은 안전한 락(Lock) 메커니즘의 필요성을 강조한다.

A tale about fixing eBPF spinlock issues in the Linux kernel

댓글 0

첫 번째 댓글을 남겨보세요!