Skip to content

Instantly share code, notes, and snippets.

@hikalium
Last active December 8, 2017 00:29
Show Gist options
  • Save hikalium/4e0507b2bbd12755e5045f345b612324 to your computer and use it in GitHub Desktop.
Save hikalium/4e0507b2bbd12755e5045f345b612324 to your computer and use it in GitHub Desktop.

NVMeのまとめ

spec: http://www.nvmexpress.org/wp-content/uploads/NVM_Express_Revision_1.3.pdf

SQ: Submission Queue PRP: Physical Region Page SGL: Scatter Gather List NS: NameSpace CNS: Controller or Namespace Structure

Submission Queue と Completion Queue がセットで用いられる。 これらはメモリ上に確保される。

Admin (Submission | Completion) Queue コントローラの管理に用いられる。 I/O (Submission | Completion) Queue をつくったり、コマンドを中止したりできる。

たいてい、各コアごとにひとつI/O Queue Pairを作成する(キャッシュとかが正しく働くように&ロックで悩まないで済むように) cf. p.8 Queue Pair Example

SQ の各エントリはコマンドで、ひとつあたり64bytes。リングバッファ。 4.2にその構造がある。 このうち、OPC(OPCode )は

NS(NameSpace)はNVMe上の領域を切り分けてそれに名前をつけられる機能。

p.61 Figure 25: SGL Read Example

p.74 5 Admin Command Set (Create | Delete) IO (Submisson | Completion) Queue p.172 6 NVM Command Set Read / Write / Flush

7.2.1 Command Processing

Figure 251: Command Processing

7.2.2 Basic Steps when Building a Command

7.2.5.1 Creating an I/O Submission Queue

Figure 252: PRP List Describing I/O Submission Queue PRP ListでどのようにQueueを定義するかの図解

7.6 Controller Initialization and Shutdown Processing 7.6.1 Initialization

概要まとめ

  • コマンドのやり取りはSQ/CQのペアで行う
  • SQ/CQは、メモリ上に配置される。

アクセス手順まとめ

共通:コマンドの送り方

7.2.1 Command Processing を参照 Figure 251: Command Processing にイメージ図あり

  • 送りたいコマンドをSQの末尾に追加する
    • コマンドのフォーマットは以下を参照
      • 4.2 Submission Queue Entry – Command Format
    • メモリ領域を指定する場合はPRPEntry(List)もしくはSGLを使用する
  • Submission Queue Tail Doorbell Register (Controller Registersの中にある)を更新する。すると、コントローラがコマンドを処理してくれる。
  • コマンドの実行順序はOutOfOrder
  • 実行が終わるとコントローラがCQの末尾にエントリを追加する。エントリのPhase Tagが反転するので、ホストは新しいエントリかどうか判別できる。
  • (オプション)割り込みを発生させる。設定によっては、毎回発生するわけではない。
  • ホストはCQの各エントリの処理が終わったら、Completion Queue Head Doorbell registerを設定し直す。

QueueのHeadとTailがどこを指すべきかは

4.1.1 Empty Queue Figure 8: Empty Queue Definition 4.1.2 Full Queue Figure 9: Full Queue Definition に図解がある。

初期化

7.6.1 Initialization を参照

  • デバイスをみつける
  • <BAR0, 1>を読んで、Controller Registersがマップされている場所を知る
    • Controller Registersの内容は3.1 Register Definitionにある
  • 割り込みはsingle-MSIをつかう
    • MSICAP.MC.MSIE=’1’
    • MSICAP.MC.MME=0h
    • 7.5.1.1.1 Interrupt Example (Informative) を参照
      • CQyHDBLを更新することでコントローラに割り込み処理終了を通知できる
  • CSTS.RDYが0になるまで待つ。
  • まずはAdmin Queueを設定する。
    • 3.1.8 Offset 24h: AQA – Admin Queue Attributes
      • ASQ, ACQの大きさ(エントリ数)を設定
    • 3.1.9 Offset 28h: ASQ – Admin Submission Queue Base Address
      • ASQの物理アドレスを設定
    • 3.1.10 Offset 30h: ACQ – Admin Completion Queue Base Address
      • ACQの物理アドレスを設定
      • ACQの領域は0クリアしておく(Phase Tagを0にしたいから)
  • 各レジスタを設定する
    • CC.AMS
      • 000b: Round Robin(とりあえずこっち?)
      • 001b: Weighted Round Robin with Urgent Priority Class
    • CC.MPS
      • ページサイズ(bytes) == (2 ^ (12 + MPS)) となるように設定
    • CC.CSS
      • 000b: NVM Command Set に設定
  • コントローラを有効化(CC.EN = 1)
  • CSTS.RDY == 1 になるまで待つ
  • Identifyコマンドを発行して、コントローラとNSの情報を取得する
    • 5.15 Identify command
  • 7.4.1 Queue Setup and Initialization に従ってQueueを設定する
    • 5.21.1.7 Number of Queues (Feature Identifier 07h) コマンドを発行して 各Queueを何個つくるかコントローラに設定。
    • 各キューを各コマンドで作成
      • 5.3 Create I/O Completion Queue command
      • 5.4 Create I/O Submission Queue command

シャットダウン手順

  • 7.6.2 Shutdown を参照
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment