eBPF 보안 에이전트, inode 캐시로 커널 CPU 비용 약 90% 절감
Dropping eBPF CPU Cost by About 90% with Memoization (Not AI Gen)
TL;DR Highlight
파일 open마다 하던 경로 탐색을 inode 캐시로 바꿔 커널 CPU가 약 90% 줄었다
Who Should Read
파일 접근 정책을 매번 계산하느라 느려진 eBPF·리눅스 보안 에이전트를 만드는 시스템 개발자
Core Mechanics
- 병목은 정책 집행이 아니라 정책 찾기
- 프로파일링해 보니 가장 비싼 부분은 allow/deny 집행이 아니었다.
- 파일 open 때 어떤 정책이 적용되는지 찾는 일이 가장 비쌌다.
- 매번 경로를 끝까지 거슬러 올라갔다
- 정책이 경로 기반이라 LSM 훅(파일 open 때 실행되는 커널 후크)에서 경로를 복원하고 부모 dentry(디렉터리 항목 객체)를 따라 올라갔다.
- 같은 파일이나 같은 하위 디렉터리를 여러 번 열어도 매번 같은 작업을 반복했다.
- dentry 대신 inode 기반 캐시 키
- dentry는 포인터라 eBPF 맵에 저장할 수 없었다.
- 키는 mount namespace ID, mount ID, inode 번호 세 필드로 구성했다.
- 캐시는 LRU 해시 맵, 값은 정책 비트 위치와 상태
- 맵 타입은 BPF_MAP_TYPE_LRU_HASH이고 max_entries는 10000이다.
- 값에는 access_index(정책 비트마스크 내 위치)와 state가 들어간다.
- 200,000번 같은 파일 open 벤치마크에서 커널 사이클 280억 → 30.3억
- 캐시가 없을 때 is_restricted_filepath는 스택의 81.9%, path_check_callback은 63.7%를 차지했다.
- 캐시가 있으면 두 함수 모두 약 0.02%로 줄었다.
Community Reactions
- 메모리 비용은 측정하지 않았다는 지적
- 메모이제이션은 CPU를 줄이는 대신 메모리를 쓰는데 글에는 메모리 측정이 없다는 의견이 있었다.
- "측정하지 말고 가정하지 말라"는 취지였다.
- 같은 파일만 여는 벤치마크라는 비판
- 90% 수치는 같은 파일을 반복해서 여는 최선의 경우라는 의견이 있었다.
- 매번 다른 파일을 열면 캐시 기록 때문에 오히려 약간 느려질 것이라는 의견이었다.
- 캐시 무효화와 보안 우려
- 상위 디렉터리 이동, 권한 변경, 하드링크 추가, 삭제 시 캐시가 어떻게 무효화되느냐는 질문이 여러 개 달렸다.
- 정책이 사용자 조작으로 바뀔 수 있는데 적용 정책을 캐시하면 보안 문제가 될 수 있다는 의견도 있었다.
- bind mount 같은 경로 우회 질문
- 경로 기반 규칙이 bind mount처럼 다른 경로로 보이게 하는 방법을 어떻게 처리하느냐는 질문이 있었다.
- 글의 핵심은 메모이제이션이 아니라 캐시 키 설계라는 의견
- 이 글의 흥미로운 점은 eBPF와 리눅스 파일시스템 제약 안에서 경로→정책 매핑을 올바르게 캐싱한 것이라는 의견이 있었다.
- 제목을 'eBPF에서 파일 경로의 캐시 키 계산하기'로 했으면 좋았겠다고 했다.
How to Apply
- 핫패스 프로파일링부터 해 보기
- 오늘 perf record -e cycles:k로 훅이 걸린 커널 경로를 30분간 수집하라.
- 플레임그래프에서 집행 로직과 조회 로직 중 어느 쪽이 비싼지 먼저 확인하라.
- 캐시 키에 식별 범위를 모두 넣기
- 포인터는 맵에 못 넣으니 mntns_id, mount_id, inode 같은 값 타입 필드로 키를 구성하라.
- inode 번호만 쓰면 마운트 트리마다 겹칠 수 있으니 마운트 정보를 함께 넣어라.
- 캐시가 틀릴 수 있는 경우는 느린 경로로 우회하기
- 하드링크처럼 한 객체에 경로가 여러 개인 경우는 i_nlink가 1일 때만 캐시를 쓰도록 조건을 걸어라.
- 건너뛴 횟수를 통계 카운터로 남겨 캐시 커버리지 손실을 확인하라.
- 벤치마크에 캐시 미적중 시나리오도 넣기
- 같은 파일 반복 open과 매번 다른 파일 open을 둘 다 돌려 비교하라.
- 캐시 맵의 메모리 사용량도 함께 기록하라.
Try It
# Claude나 ChatGPT에 그대로 붙여넣는 프롬프트 (논문 방법의 간이 버전: 코드 리뷰용)
나는 eBPF LSM 훅으로 파일 open마다 경로 정책을 검사하는 보안 에이전트를 만들고 있다.
현재는 매번 dentry를 따라 올라가며 정책을 찾는다.
아래 코드를 보고 inode 기반 캐시를 도입할 때의 위험을 점검해 달라.
{{현재 정책 조회 코드}}
캐시 키 후보: mount namespace ID, mount ID, inode 번호
캐시 맵: BPF_MAP_TYPE_LRU_HASH, max_entries 10000
하드링크(i_nlink != 1)는 캐시를 쓰지 않고 느린 경로로 처리
다음을 답해 달라.
1. 캐시가 틀린 결과를 줄 수 있는 경우를 목록으로 정리
2. 각 경우의 우회 조건 제안
3. 캐시 적중과 미적중을 모두 재는 벤치마크 계획
이어서 해 볼 것: 디렉터리 이동, 권한 변경, 정책 갱신 시 캐시를 어떻게 비울지 설계안을 요청해 보라.Terminology
관련 논문
Mercury 3: 규모를 키운 diffusion LLM, 초당 1,000토큰 이상
Diffusion LLM을 40배 키웠더니 속도 4~8배, 품질은 속도 특화 모델 수준
Timestral: Mistral의 시계열 파운데이션 모델
209M 파라미터 시계열 모델이 3대 벤치마크 1위, CPU에서도 돌아간다
DeepSeek V4.1 Flash 1017 (Max) 성능·속도·가격 분석
DeepSeek V4.1 Flash 1017 Max는 지능 지수 45에 211 tok/s, 입력 $0.30
LLM 프록시를 직접 안 돌리면 무슨 일이 벌어지는지 어떻게 아나
자체 LLM 프록시를 세웠더니 키·모델·캐시 미스를 직접 볼 수 있다
DeepSeek V4.1 Flash 1017: 싼 가격에 1M 컨텍스트를 주는 에이전트용 모델
DeepSeek V4.1 Flash 1017은 입력 $0.05/M, 1M 컨텍스트의 에이전트용 모델
DeepSeek-V4.1-Flash-1017 공개: 더 짧게 생각하고 더 빠르게 일하는 에이전트용 모델
DeepSeek V4.1 Flash 마이너 업데이트로 코딩·에이전트 벤치 점수↑, 실행 시간·출력 길이↓
Llmspeed: 로컬 LLM 속도를 하드웨어 구매 전에 체감해 보는 시뮬레이터
GPU·모델을 고르면 로컬 LLM 속도를 미리 체감하게 해 주는 시뮬레이터