# 機能設計書 54-NVMeドライバ

## 概要

本ドキュメントは、FreeBSDにおけるNVMe（Non-Volatile Memory Express）SSDデバイスドライバの設計を記述する。NVMeドライバはPCIe接続のNVMe SSDへのアクセスを提供し、高性能なブロックI/Oを実現する。

### 本機能の処理概要

NVMeドライバは、NVMe仕様に準拠したPCIe接続SSDデバイスの制御を行う。Submission Queue/Completion Queueベースのコマンドインタフェースにより、低レイテンシかつ高スループットのストレージI/Oを実現する。

**業務上の目的・背景**：NVMeはSATA/AHCIに代わる次世代ストレージインタフェースとして、PCIeバスのパラレルI/O能力を最大限に活用する。従来のAHCI（最大1キュー、32コマンド）に対し、NVMeは最大65535キュー、各キュー最大65536コマンドをサポートし、大幅な性能向上を実現する。

**機能の利用シーン**：NVMe SSDからのシステム起動、高性能データベースのストレージI/O、仮想化環境のストレージバックエンド、CAM経由のディスク管理（nvmecontrol）。

**主要な処理内容**：
1. NVMeコントローラの検出・初期化（PCI/AHCI接続）
2. Admin Queue/I/O Queueの作成・管理
3. Submission Queue/Completion Queue操作
4. ネームスペース管理
5. 割り込み処理（MSI-X対応、CPU親和性）
6. 非同期イベント要求（AER）処理
7. sysctl経由の統計情報・パラメータ管理
8. コントローラリセット・エラーリカバリ
9. CAM SIM連携（nvme_sim.c）
10. パススルーコマンド（ioctl）

**関連システム・外部連携**：CAMストレージサブシステム（nvme_sim.c経由）、nvmecontrolユーザ空間管理ツール、devctl（イベント通知）との連携。

**権限による制御**：カーネルドライバとして動作。ユーザ空間からのパススルーコマンドはioctl経由で実行され、root権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | （カーネルドライバのため関連画面なし） | - | - |

## 機能種別

デバイスドライバ / ブロックI/O / 高性能ストレージ

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| PCI Device ID | uint32 | Yes | NVMeコントローラのPCIデバイスID | NVMeクラスコード |
| NVMe BAR | resource | Yes | NVMeレジスタベースアドレス | 有効なメモリマップドI/O |
| bio | struct bio | Yes | ブロックI/Oリクエスト | 有効なbioポインタ |
| nvme_pt_command | struct | No | パススルーコマンド（ioctl） | 有効なNVMeコマンド |

### 入力データソース

- PCI構成空間（デバイス検出）
- BIOリクエスト（ファイルシステム層）
- ioctl（パススルーコマンド）
- NVMeレジスタ（ステータス読み取り）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| I/O完了通知 | bio callback | BIO完了コールバック |
| コントローラデータ | nvme_controller_data | Identifyコントローラ情報 |
| ネームスペースデータ | nvme_namespace_data | Identifyネームスペース情報 |
| devctlイベント | string | コントローライベント通知 |

### 出力先

- BIO完了コールバック
- CAMサブシステム
- sysctl（hw.nvme統計情報）
- devctl（イベント通知）
- dmesg（デバイス検出・エラーログ）

## 処理フロー

### 処理シーケンス

```
1. PCI probe
   └─ NVMeクラスコードに基づくデバイス検出
2. PCI attach
   └─ BAR/割り込みリソース確保、コントローラ初期化
3. Admin Queue初期化
   └─ Admin Submission/Completion Queueの作成
4. コントローラ識別
   └─ Identify Controllerコマンドの発行
5. I/O Queue作成
   └─ CPUコア数に応じたI/O Queueペアの作成
6. ネームスペース初期化
   └─ 各ネームスペースの検出と初期化
7. CAM SIM登録
   └─ nvme_sim.cを通じたCAMへの登録
8. I/Oリクエスト処理
   └─ BIOを受け取り、NVMeコマンドとしてSQに投入
9. 割り込み処理
   └─ CQエントリの処理、BIO完了通知
10. 非同期イベント処理
    └─ AERの受信と処理（温度警告、エラー通知等）
```

### フローチャート

```mermaid
flowchart TD
    A[PCI probe] --> B[PCI attach]
    B --> C[BAR/割り込みリソース確保]
    C --> D[Admin Queue初期化]
    D --> E[Identify Controller]
    E --> F[I/O Queue作成 per CPU]
    F --> G[ネームスペース初期化]
    G --> H[CAM SIM登録]
    H --> I[I/O待ち受け]
    I --> J{BIOリクエスト}
    J --> K[NVMeコマンド構築]
    K --> L[SQにコマンド投入]
    L --> M[ドアベルレジスタ書き込み]
    M --> N{CQ割り込み}
    N --> O[CQエントリ処理]
    O --> P[BIO完了通知]
    P --> I
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-54-01 | Queue per CPU | I/O QueueをCPUコア数に応じて作成し、ロック競合を最小化 | コントローラ初期化時 |
| BR-54-02 | Admin Queue制限 | Admin Queueエントリ数は128（NVME_ADMIN_ENTRIES） | コントローラ初期化時 |
| BR-54-03 | I/O Tracker制限 | I/Oトラッカー数のデフォルトは128（NVME_IO_TRACKERS） | I/O Queue初期化時 |
| BR-54-04 | 最大ネームスペース数 | 最大16ネームスペース（NVME_MAX_NAMESPACES） | ネームスペース検出時 |
| BR-54-05 | AER上限 | 最大8非同期イベント（NVME_MAX_ASYNC_EVENTS） | AER登録時 |

### 計算ロジック

I/O Queueエントリ数: デフォルト256（NVME_IO_ENTRIES）。Admin Queueエントリ数は最小2（NVME_MIN_ADMIN_ENTRIES）から最大4096（NVME_MAX_ADMIN_ENTRIES）。

## データベース操作仕様

該当なし（カーネルドライバ）。

### テーブル別操作詳細

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| NVME_SC_INTERNAL_DEVICE_ERROR | デバイスエラー | デバイス内部エラー | コントローラリセット |
| NVME_SC_COMMAND_TIMEOUT | タイムアウト | コマンド応答なし | コントローラリセット |
| - | AERイベント | 温度超過、信頼性劣化等 | devctl通知、ログ記録 |

### リトライ仕様

コントローラリセット時、未完了のI/Oリクエストはエラーとして上位に通知。B4_CHK_RDY_DELAY_MS（2300ms）のディレイがコントローラバグ回避のために設定されている。

## トランザクション仕様

NVMeはSubmission Queue/Completion Queueのペアでコマンドを管理。各I/O Queueは独立して動作し、異なるCPUコアから同時にアクセス可能。

## パフォーマンス要件

- PCIe Gen3 x4: 理論帯域幅約3.9GB/s
- PCIe Gen4 x4: 理論帯域幅約7.9GB/s
- 数十万IOPSのランダムI/O性能
- Queue per CPUアーキテクチャによるスケーラブルな性能

## セキュリティ考慮事項

- パススルーコマンド（ioctl）はroot権限が必要
- NVMeセキュリティコマンド（Secure Erase、Format NVM等）のアクセス制御
- devctl通知によるデバイスイベントの監視

## 備考

- NVMeドライバはIntelにより寄贈され、FreeBSDコミュニティにより拡張
- nvme_ahci.cはAHCI接続のNVMeデバイス対応
- nvme_sim.cはCAM SIMインタフェースを提供し、camcontrolからの管理を可能にする

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | nvme.h | `sys/dev/nvme/nvme.h` | NVMe仕様のデータ構造、ioctl定義、レジスタ定数 |
| 1-2 | nvme_private.h | `sys/dev/nvme/nvme_private.h` | ドライバ内部構造体、定数定義 |

**読解のコツ**: nvme.hの**29-51行目**にNVMe ioctl定義（NVME_PASSTHROUGH_CMD, NVME_RESET_CONTROLLER等）がある。nvme_private.hの**52行目**のDEVICE2SOFTCマクロはdevice_tからsoftcへの変換に頻出。**59-78行目**のキュー関連定数（NVME_ADMIN_ENTRIES=128, NVME_IO_ENTRIES=256, NVME_IO_TRACKERS=128, NVME_MAX_NAMESPACES=16）が重要。

#### Step 2: コントローラ管理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | nvme_ctrlr.c | `sys/dev/nvme/nvme_ctrlr.c` | コントローラの初期化・管理・リセット |

**主要処理フロー**:
1. **53行目**: B4_CHK_RDY_DELAY_MS = 2300 - コントローラバグ回避ディレイ
2. **58-62行目**: nvme_ctrlr_barrier() - バスバリア操作
3. **64-79行目**: nvme_ctrlr_devctl_va() - devctlイベント通知（sbufを使用）

#### Step 3: Queue Pair管理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | nvme_qpair.c | `sys/dev/nvme/nvme_qpair.c` | Submission/Completion Queueペア管理 |

#### Step 4: ネームスペース管理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | nvme_ns.c | `sys/dev/nvme/nvme_ns.c` | ネームスペースの初期化・I/O処理 |
| 4-2 | nvme_ns_cmd.c | `sys/dev/nvme/nvme_ns_cmd.c` | ネームスペースコマンド発行 |

#### Step 5: PCI接続とCAM連携を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | nvme_pci.c | `sys/dev/nvme/nvme_pci.c` | PCI probe/attach処理 |
| 5-2 | nvme_sim.c | `sys/dev/nvme/nvme_sim.c` | CAM SIMインタフェース |

### プログラム呼び出し階層図

```
PCI バス
    |
    +-- nvme_pci_probe() / nvme_pci_attach() [nvme_pci.c]
        |
        +-- nvme_ctrlr_construct() [nvme_ctrlr.c]
        |   +-- Admin Queue作成
        |   +-- Identify Controller
        |   +-- I/O Queue作成 (per CPU)
        |   +-- nvme_ns_construct() [nvme_ns.c]
        |
        +-- nvme_sim_attach() [nvme_sim.c]
            +-- CAM SIM登録

I/Oパス:
    bio / CAM CCB
        |
        +-- nvme_ns_bio_process() [nvme_ns.c]
            +-- nvme_ns_cmd_read/write() [nvme_ns_cmd.c]
                +-- nvme_qpair_submit_tracker() [nvme_qpair.c]
                    +-- ドアベル書き込み
                        |
                    CQ割り込み → コールバック → bio完了
```

### データフロー図

```
[入力]                    [処理]                         [出力]

BIOリクエスト ────▶ nvme_ns_bio_process()     ────▶ NVMe SQ投入
                    nvme_ns_cmd_read/write()
                    nvme_qpair_submit_tracker()
                        |
NVMe CQ      ◀──── 割り込みハンドラ           ────▶ BIO完了コールバック
(完了エントリ)     nvme_qpair_process_completions()

ioctl        ────▶ nvme_ctrlr_passthrough_cmd() ──▶ 管理コマンド結果
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| nvme.h | `sys/dev/nvme/nvme.h` | ヘッダ | NVMe仕様データ構造、ioctl定義 |
| nvme_private.h | `sys/dev/nvme/nvme_private.h` | ヘッダ | ドライバ内部構造体 |
| nvme.c | `sys/dev/nvme/nvme.c` | ソース | ドライバモジュール登録 |
| nvme_ctrlr.c | `sys/dev/nvme/nvme_ctrlr.c` | ソース | コントローラ管理 |
| nvme_qpair.c | `sys/dev/nvme/nvme_qpair.c` | ソース | Queue Pair管理 |
| nvme_ns.c | `sys/dev/nvme/nvme_ns.c` | ソース | ネームスペース管理 |
| nvme_ns_cmd.c | `sys/dev/nvme/nvme_ns_cmd.c` | ソース | ネームスペースコマンド |
| nvme_ctrlr_cmd.c | `sys/dev/nvme/nvme_ctrlr_cmd.c` | ソース | コントローラコマンド |
| nvme_pci.c | `sys/dev/nvme/nvme_pci.c` | ソース | PCI接続対応 |
| nvme_sim.c | `sys/dev/nvme/nvme_sim.c` | ソース | CAM SIM連携 |
| nvme_sysctl.c | `sys/dev/nvme/nvme_sysctl.c` | ソース | sysctl統計情報 |
| nvme_ahci.c | `sys/dev/nvme/nvme_ahci.c` | ソース | AHCI接続NVMe対応 |
| nvme_util.c | `sys/dev/nvme/nvme_util.c` | ソース | ユーティリティ |
| nvme_test.c | `sys/dev/nvme/nvme_test.c` | ソース | テスト用I/O |
| nvme_if.m | `sys/dev/nvme/nvme_if.m` | インタフェース | NVMeインタフェースメソッド |
