링크와 레지스터에 접근된다고 Admin 준비가 끝난 것은 아닙니다
Linux v6.12의 nvme_pci_configure_admin_queue()는 컨트롤러를 비활성화한 뒤 Admin Queue의 크기·주소를 AQA·ASQ·ACQ에 설정하고 다시 활성화합니다. BAR를 읽었다는 기록이 있다고 해서 이 절차가 성공한 것은 아닙니다.
직전 비활성화 완료 → RDY=0 확인
Admin 설정 → EN=1 → RDY=1 확인
Identify·큐 협상 → I/O CQ → I/O SQ
큐 수를 협상했다고 큐가 생성된 것은 아닙니다
Number of Queues(FID 07h)는 I/O 큐를 만들기 전에 설정합니다. 이미 I/O SQ 또는 CQ가 만들어진 뒤 설정하면 Command Sequence Error 대상입니다. 요청·할당 필드는 0 기반이므로 값 7은 8개, 값 3은 4개입니다. 응답 수는 요청보다 작거나 클 수 있으며 실제 생성·활성 큐 수와 같다는 보장은 없습니다.
CQ를 먼저 만들고 그 CQ에 연결할 SQ를 만듭니다. 여러 SQ가 하나의 CQ를 공유할 수 있으므로 일반 규칙을 “SQ와 CQ는 언제나 일대일”로 쓰지 않습니다.
장치 식별과 namespace 용량을 따로 봅니다
Identify Controller의 CNS=01h와 NVM Command Set의 활성 namespace를 읽는 CNS=00h는 대상이 다릅니다. 후자의 NSZE·NCAP·NUSE는 논리 블록 수이며, 바이트로 비교하려면 선택된 LBA 형식을 알아야 합니다. NUSE를 NAND의 실측 점유량으로 해석하지 않습니다. thin provisioning을 지원하지 않는 경우 NUSE가 항상 NCAP와 같을 수 있습니다.
Linux가 실제로 만든 큐 수를 확인합니다
Linux v6.12의 nvme_setup_io_queues()는 협상 뒤에도 BAR 공간과 인터럽트 자원 등을 반영합니다. 생성 실패 뒤 더 적은 큐로 재시도하거나 Admin 전용 상태로 남을 수 있습니다. 폴링 큐에는 일반 IRQ 큐와 다른 조건이 적용됩니다. “요청·할당·생성·온라인”을 같은 숫자로 기록하지 않습니다.
이 글은 Base 2.0·NVM Command Set 1.0과 Linux v6.12 소스를 대조한 설명입니다. 특정 장치의 리셋·펌웨어·명령 완료를 직접 시험한 결과는 아닙니다. 데이터 읽기의 DMA·CQ 처리와 파일 캐시는 이어지는 별도 글에서 다룹니다.