본문으로 건너뛰기

ankit-sam/LMCache#1 (daegyu base) — 8커밋 시간순 해부

브랜치: remotes/ankit/pr-1 (daegyu94 author: daegyu94.han@samsung.com) 대상 PR: ankit-sam/LMCache#1Refine Rust raw block FDP handling and update offload examplesOPEN since 2026-05-08 상류 dev에 머지된 커밋: 0건. origin/dev에는 FDP 코드 전무.


시간순 표

#커밋날짜카테고리한 줄 의미
18bb1f36a2026-04-29safetyplacement_id 없으면 FDP directive 끔 (dtype=0x20x0)
279183c872026-05-06cleanupnvme identify 디버그 print 제거
39b4014882026-05-06docs/exampleoffload 예제·README 갱신, --per_tp_device_paths/--use_fdp/--max-data-transfer-size 노출
424ae8ab82026-05-07compatibilityFDP status를 header-first로 조회 (nvme-cli 호환)
52be75bb52026-05-08정책placement 정책 정리 — rank 1개 = PID 1개, data/metadata RUH 분리, fail-fast
6108125022026-05-08featureopt-in transfer split auto-config (max_data_transfer_size=-1 → sysfs 자동)
78b7219e12026-05-08testsuring_cmd 테스트 fixture 안정화
88288b6d12026-05-08styleraw_block 스타일 이슈 수정

전체 스토리: FDP PoC가 이미 들어와 있던 상태에서 (안전장치 → 호환성 → 정책 정리 → 운영 옵션 → 테스트/스타일) 순으로 다듬는 작업. "PoC → 운영 가능한 설정 핸들링" 한 묶음.


커밋 #1: 8bb1f36a — placement_id가 없으면 FDP directive 끔

파일: rust/raw_block/src/lib.rs (3 hunks, +3/-3)

핵심 변경: 세 군데에서 dtype: 0x2 (FDP directive 활성) 하드코딩을 → dtype: if placement_id.is_some() { 0x2 } else { 0x0 }로 변경. dspecplacement_id.unwrap_or(0).

의미: 이전 PoC는 placement_id를 안 주면 directive type만 0x2로 박혀서 dspec=0이 들어가 invalid 경계 케이스 발생. 이걸 **3-way 검증 일관성 (dtype·dspec 동시 unset)**으로 정리. 후속 정책 변경(#5)의 전제.


커밋 #2: 79183c87 — nvme identify 디버그 print 제거

파일: rust/raw_block/src/lib.rs (1 hunk, -3)

의미: PoC 시절 남은 println! 흔적 정리. 단독 의미는 없고 PR 합치기 전 cleanup.


커밋 #3: 9b401488 — examples/README FDP 옵션 갱신

파일: examples/kv_cache_reuse/local_backends/rust_backend_offload.py (+112/-10), README.md (+8)

노출되는 CLI 플래그 (예제 차원):

  • --use_fdp
  • --per_tp_device_paths /dev/ng0n1 /dev/ng0n2
  • --tp <int>
  • --max-data-transfer-size {0,-1,positive}

README 추가 문구 (그대로 인용):

  • The current FDP placement policy is rank-based and is mainly intended for multi-TP runs.
  • --max-data-transfer-size defaults to 0 (no splitting); set -1 for auto-detection from max_hw_sectors_kb, or provide a positive byte value to force splitting.

의미: 사용자 진입점에서 어떤 toggle을 켜야 FDP가 동작하는지 명시. 단, 이건 in-process 예제 — MP는 lmcache storage configure 또는 L2 adapter JSON으로 가야 함 (이 커밋엔 없음).


커밋 #4: 24ae8ab8 — FDP status header-first 조회

파일: rust/raw_block/src/lib.rs (+17/-12)

문제: 일부 namespace가 큰 버퍼(header_size + max_ruhs * desc_size)로 한 번에 받으면 빈 응답을 반환. nvme-cli는 정상 응답.

해결: nvme-cli 동작 모방 — ① fixed-size header만 먼저 fetch → ② header의 nruhsd 값 읽어 정확한 크기 버퍼로 재요청.

nvme_fdp_reclaim_unit_handle_status(fd, nsid, header_size as u32, &mut header as *mut _ as *mut u8)?;
let nruhsd = u16::from_le(header.nruhsd);
let actual_ruhs = min(nruhsd, max_ruhs) as usize;
let bytes = header_size + actual_ruhs * desc_size;
let mut buffer: Vec<u8> = vec![0; bytes];
nvme_fdp_reclaim_unit_handle_status(fd, nsid, bytes as u32, buffer.as_mut_ptr())?;

의미: device 호환성 PoC. 운영 환경(다른 SSD 모델/펌웨어) 대응. 이건 dongdongju PoC에 없는 ankit#1만의 강점 (01_branch_audit/03_fdp_implementation_audit.md (d) 참조).


커밋 #5: 2be75bb5 — placement 정책 정리 (이 PR의 메인 커밋)

파일: rust/raw_block/src/lib.rs (+17/-12), plugins/rust_raw_block_backend.py (+95/-50), tests/test_uring_cmd.py (+257)

이 PR의 핵심 정책 결정. 본 대화에서 자세히 분석한 커밋.

5-1. Rust 인터페이스 확장

  • fetch_ruhs() -> Vec<u16> (PID만) → fetch_fdp_status() -> Vec<(u16, u16)> ((PID, RUH ID) 튜플)
  • PyO3: RawBlockDevice.fetch_reclaim_unit_handlesfetch_fdp_status

5-2. Python 정책 전면 교체

기존 (_get_placement_id_for_cuda_device)변경 (_assign_fdp_placement_rank_based)
torch.cuda.current_device() 인덱스로 PID 선택rank별 첫 번째 PID 하나 고정
범위 초과 시 placement_ids[0] fallback무조건 placement_ids[0]
실패 시 use_fdp=False silent 비활성화fail-fast RuntimeError
write마다 placement_id를 element별로 append_data_placement_ids_cache에 같은 PID 미리 채워 슬라이스 재사용

5-3. 데이터 vs 메타데이터 분리 (lifetime isolation, 이미 hardcode)

  • 데이터 쓰기: 설정된 단일 _data_placement_id
  • 체크포인트 metadata 쓰기: FDP directive 안 붙임 (default RUH) — 메타·데이터 수명 차이로 WAF 우려.

5-4. Fail-fast 강화

  • use_fdp=True인데 use_uring/use_uring_cmd 꺼져있으면 즉시 RuntimeError
  • FDP status 조회 실패 / 빈 응답 → RuntimeError

5-5. 평가

  • _assign_fdp_placement_rank_based 이름은 거창하지만 실제로는 placement_ids[0] 하나 — placeholder.
  • 코드 코멘트 그대로: "this policy simply uses the first placement ID per rank".
  • → daegyu가 제안한 3축 정책 (rank/domain/model)이 들어갈 자리는 여기.

커밋 #6: 10812502 — opt-in transfer split auto-config

파일: plugins/rust_raw_block_backend.py (+72), tests/test_uring_cmd.py (+88)

신규 옵션 의미 (rust_raw_block.max_data_transfer_size):

  • > 0: 명시적 split size (byte)
  • 0: split 안 함 (기본)
  • -1: sysfs (/sys/block/nvmeXnY/queue/max_hw_sectors_kb) 자동 감지

핵심 함수: _resolve_max_data_transfer_size() — char device path (/dev/ngXnY) → sysfs queue path 매핑 (_resolve_sysfs_queue_dir() 정규식).

의미: FDP 직접 관련 아닌 운영 옵션 (MDTS 한계 자동 적용). FDP와 묶여 들어온 이유는 NVMe passthrough write 경로 공유 + 같은 PR 묶음.


커밋 #7: 8b7219e1 — uring_cmd 테스트 fixture 안정화

파일: tests/v1/storage_backend/test_uring_cmd.py (+18/-14)

PR 통합 시점에 fixture 동작이 환경별로 갈리는 문제 정리. PoC 트랙 보존 작업.


커밋 #8: 8288b6d1 — raw_block 스타일 이슈 수정

파일: rust/raw_block/src/lib.rs (+19/-9)

clippy/rustfmt 정리. 상류 PR 통합 직전 cleanup.


추가된 표면 요약 (다른 문서가 참조할 수 있게)

Config 키 (in-process plugin 전용, extra dict):

  • rust_raw_block.use_fdp: bool (default False)
  • rust_raw_block.per_tp_device_paths: dict[str→str] (default {})
  • rust_raw_block.max_data_transfer_size: int (default 0, -1 auto)

Python 메서드 (RustRawBlockBackend):

  • _configure_fdp_placements() — init 시 호출, status fetch + 정책 적용
  • _fetch_fdp_status()list[(int, int)]
  • _assign_fdp_placement_rank_based(placement_ids) → 단일 PID (현재: placement_ids[0])
  • _get_data_placement_id()int (FDP off면 -1)
  • _build_data_placement_ids(num_requests)Optional[list[int]]

Rust/PyO3 표면 (RawBlockDevice):

  • fetch_fdp_status(max_ruhs=256) -> Vec<(u16, u16)> (PyO3 메서드)
  • batched_write(offsets, buffers, total_lens, placement_ids=None) (시그니처 확장)
  • write_uring(offset, data, payload_len, total_len=None, placement_id=None)
  • nvme_uring_cmd_prep에서 cmd.cdw13 = (dspec as u32) << 16, cmd.cdw12 |= (dtype as u32) & 0x0F

시사점 (items.md로 이어짐)

  1. _assign_fdp_placement_rank_based는 정책의 형태만 갖춘 placeholder → 실제 정책 결정이 발굴 아이템.
  2. lifetime isolation (data/metadata RUH 분리)은 이미 hardcode → WAF 정량 효과 입증의 최단 경로.
  3. fetch_fdp_status 자동 조회는 ankit#1만의 강점 → dongdongju PoC와 머지 시 가져갈 단위 (03_audit (d) gap).
  4. MP adapter 경로엔 이 8커밋 중 어느 것도 반영 안 됨mp_integration_gap.md 참조.