同じネームスペースに対して複数のパスが存在し、コマンドの完了後も揮発性キャッシュに依存している可能性があります。NVMe を理解するには、ストレージオブジェクト、キュープロトコル、データアドレス、回復状態 をそれぞれ明確に位置づける必要があります。
参照目標 読書位置
コントローラ、ネームスペース、SQ/CQ 第1~2節
LBA、PRP と回復 第3~4節
マルチパス、DM、キャッシュモード 第5~8節
1. コントローラ、ネームスペース、サブシステム
コントローラはホストのアクセスインターフェースと管理機能を提供し、ネームスペースは論理ブロックアドレス空間を提供します。サブシステムは複数のコントローラを含み、共有ネームスペースを提供できます。ネームスペースは必ずしも独立したNANDチップにマッピングされるわけではなく、単なるパーティションと同等でもありません。
1つのネームスペースは異なるパスからアクセス可能であり、それが同一のストレージオブジェクトとして認識されるかどうかは、サブシステム、NSID、UUID/NGUID/EUIなどの識別子および共有属性を組み合わせる必要があり、容量や /dev 名だけで比較してはいけません。パスが消失するとデバイス番号が変化する可能性があるため、永続的な位置特定には適切な安定した識別子を使用する必要があります。
Identifyコマンドは機能やフォーマットなどの情報を返しますが、実際のI/Oキューリソースはネゴシエーションと作成が必要です。コントローラがサポートする上限、ドライバが実際に使用する数、およびワークロードの現在の並列度は、3つの異なる値です。
2. SQ/CQ:2つのプロデューサ・コンシューマプロトコル
PCIe NVMe:コマンドリングと完了リングはそれぞれ進行する
ホストがSQに書き込み
コマンドとDMAデータアドレス
コントローラが実行
コマンドを取得しデータを転送
コントローラがCQに書き込み
CID、ステータス、phaseなど
SQ tail通知
ホストが完了を処理
ステータスを確認しCQ領域を返却
完了後にのみ、コマンドが参照するデータリソースを回収可能
割り込みの結合やポーリングが可能であり、CQの消費とコマンドの実行は同じ動作ではない。
PCIeパスにおいて、ホストはコマンドをサブミッションキュー(SQ)に書き込み、プロトコルに従ってコントローラに新しいtailを通知します。コントローラは実行後、コンプリーションキューエントリ(CQE)をCQに書き戻し、ホストは処理してCQ headを進めます。
1つのSQは1つのCQに関連付けられますが、プロトコルでは複数のSQが1つのCQを共有することが許可されています。Linuxドライバではペアで構成されることが多いですが、これはプロトコルで強制されている一対一の対応ではありません。MSI-Xベクトルも各キューに必ずしも一対一でバインドする必要はなく、ポーリングキューでは割り込みを使用しない可能性があります。キューの数はハードウェア、ドライバ、CPUトポロジ、リソースによって決定され、CPUごとに独占され完全にロックフリーであることが保証されるわけではありません。
CQのphaseタグは、リングスロットが現在のラウンドでコントローラによって有効な完了として書き込まれたかどうかを区別するのに役立ちます。ホストが有効な状態を検出すると、DMA/メモリの順序規則に従って他のフィールドを読み取る必要があります。コマンドは順序不同で完了する可能性があり、SQ識別子やコマンド識別子(CID)などを頼りにリクエストを特定する必要があり、最初に送信されたものが最初に終了すると仮定してはいけません。
完了キューを一杯にして1周消費し、スロット0に戻ります。図では意図的に消費済みのCIDバイトを残していますが、それが有効かどうかを決定するのは現在のheadと期待されるphaseであり、スロットが空に見えないかどうかではありません。
図を準備しています 再読み込み
スロットに古いバイトが残っているのに、なぜ新しい完了として扱われないのか? ホストは現在のheadでCQEのphaseと期待されるphaseを比較し、一致して初めてこのラウンドで消費可能な完了とみなす。ロールオーバーにより期待値が変更されるため、古いバイトは新しいラウンドの完了として誤認されない。
{"id":"nvme-completion-phase","title":"スロットに古いバイトが残っているのに、なぜ新しい完了として扱われないのか?","summary":"ホストは現在のheadでCQEのphaseと期待されるphaseを比較し、一致して初めてこのラウンドで消費可能な完了とみなす。ロールオーバーにより期待値が変更されるため、古いバイトは新しいラウンドの完了として誤認されない。","height":1000,"html":"<h2 data-i18n=\"heading\"></h2><p class=\"intro\" data-i18n=\"intro\"></p><div class=\"actions\"><button id=\"produce\" data-i18n=\"produce\"></button><button id=\"consume\" data-i18n=\"consume\"></button></div><div class=\"track-row\"><span data-i18n=\"host\"></span><div id=\"host\" class=\"track\"></div></div><div class=\"track-row\"><span data-i18n=\"device\"></span><div id=\"device\" class=\"track\"></div></div><div class=\"cq\"><div class=\"slot\" id=\"slot-0\"><header>slot 0</header><strong id=\"cid-0\"></strong><span id=\"phase-0\"></span><small id=\"pointer-0\"></small></div><div class=\"slot\" id=\"slot-1\"><header>slot 1</header><strong id=\"cid-1\"></strong><span id=\"phase-1\"></span><small id=\"pointer-1\"></small></div><div class=\"slot\" id=\"slot-2\"><header>slot 2</header><strong id=\"cid-2\"></strong><span id=\"phase-2\"></span><small id=\"pointer-2\"></small></div><div class=\"slot\" id=\"slot-3\"><header>slot 3</header><strong id=\"cid-3\"></strong><span id=\"phase-3\"></span><small id=\"pointer-3\"></small></div></div><div class=\"metrics\"><div><span data-i18n=\"pending\"></span><strong id=\"pending\"></strong></div><div><span data-i18n=\"consumed\"></span><strong id=\"consumed\"></strong></div></div><div class=\"card\"><header data-i18n=\"match\"></header><div id=\"match\" class=\"readout\"></div></div><div class=\"copy\"><p id=\"explanation\" role=\"status\"></p><p class=\"reserve\" aria-hidden=\"true\" data-i18n=\"note\"></p></div><div class=\"actions\"><button id=\"reset\" data-i18n=\"reset\"></button></div><details class=\"scope\"><summary data-i18n=\"scopeLabel\"></summary><p data-i18n=\"scope\"></p></details>","css":".intro{margin:8px 0 18px;color:var(--muted);font-size:14px}.caption,.hint{font-size:12px;color:var(--muted);margin-top:12px}.control{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:6px 12px;align-items:center;margin:14px 0;font-size:13px}.control label{font-size:13px}.control output{color:var(--accent);min-width:5em;text-align:right;font-variant-numeric:tabular-nums}.control input{grid-column:1/-1;width:100%;margin:0}.presets{display:flex;gap:4px;align-items:stretch}.presets button{flex:1 1 0;min-width:0;overflow-wrap:anywhere;font-size:13px}.actions{display:flex;gap:8px;flex-wrap:wrap;margin:14px 0}.actions button{flex:1;min-width:0;font-size:13px;min-height:42px}.copy{display:grid;font-size:14px;margin:16px 0}.copy>*{grid-area:1/1;margin:0}.reserve{visibility:hidden}.scope{margin-top:14px;color:var(--muted);font-size:12px}.scope summary{padding:8px 0;cursor:pointer}.scope p{margin-top:10px}.two{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin:16px 0}.card{border:1px solid var(--rule);border-radius:9px;padding:14px;min-width:0}.card header{font-size:14px;font-weight:600;margin-bottom:10px}.card button{font-size:12px;width:100%;min-width:0}.card small{display:block;font-size:12px;color:var(--muted)}.card code{font-size:12px;overflow-wrap:anywhere}.metrics{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin:16px 0}.metrics>div{border-left:2px solid var(--accent);padding-left:10px;min-width:0}.metrics span{display:block;min-height:3.2em;color:var(--muted);font-size:12px}.metrics strong{font-size:23px;display:block;font-weight:500;overflow-wrap:anywhere;font-variant-numeric:tabular-nums}.formula{border-top:1px solid var(--rule);padding-top:12px;margin-top:14px;font-size:13px;font-variant-numeric:tabular-nums;overflow-wrap:anywhere}.value{font:500 20px var(--viz-font-ui)}.legend{display:flex;flex-wrap:wrap;gap:6px 14px;font-size:12px;color:var(--muted);margin:12px 0}.legend span:before{content:'';display:inline-block;width:8px;height:8px;border-radius:2px;background:var(--accent);margin-right:6px}.legend .second:before{background:var(--second)}.check{display:flex;align-items:center;gap:8px;font-size:13px;margin:12px 0}.check input{width:16px;height:16px;flex-shrink:0;accent-color:var(--accent)}select,input[type=text],input[type=number]{background:var(--paper);color:var(--ink);font:inherit;font-size:13px;padding:10px;border:1px solid var(--rule);border-radius:7px;max-width:100%;min-width:0}select{width:100%;min-height:42px}.band{height:20px;display:flex;background:var(--surface);border-radius:4px;overflow:hidden}.band i{height:100%;display:block;background:var(--accent);transition:width .25s}.band i.second{background:var(--second)}button:disabled{cursor:default}.status{font-size:13px;min-height:4.8em}.mono{font-family:var(--viz-font-mono);font-variant-numeric:tabular-nums}.muted{color:var(--muted)}\n@media(max-width:480px){.two{gap:8px}.card{padding:12px 9px}.actions button,.presets button{font-size:12px}.metrics strong{font-size:20px}.metrics{gap:8px}}\n@media(prefers-reduced-motion:reduce){*,*::before,*::after{transition:none!important;animation:none!important}}\n.track-row{margin:16px 0}.track-row>span{display:block;font-size:12px;color:var(--muted);margin-bottom:7px}.track{display:flex;gap:5px;min-width:0}.cell{flex:1;min-width:0;min-height:48px;border:1px solid var(--rule);border-radius:5px;background:var(--surface);display:flex;align-items:center;justify-content:center;text-align:center;padding:5px 3px;font-size:12px;overflow-wrap:anywhere;font-variant-numeric:tabular-nums}.cell.on{background:var(--accent-soft);border-color:var(--accent)}.cell.gold{background:var(--second-soft);border-color:var(--second)}.cell.empty{border-style:dashed;color:var(--muted)}.cell.error{border-color:var(--second);text-decoration:line-through}.choices{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:6px;margin:14px 0}.choices button{min-width:0;padding:10px 4px;font-size:12px;overflow-wrap:anywhere}.choices button[aria-current=true]{border-color:var(--accent);background:var(--accent-soft)}.relation{display:grid;grid-template-columns:minmax(0,1fr) 28px minmax(0,1fr);align-items:center;gap:6px;margin:12px 0}.relation .cell{min-height:72px}.relation>i{text-align:center;font-style:normal;color:var(--accent)}.readout{font-size:13px;white-space:pre-line;min-height:6.4em;overflow-wrap:anywhere}.plot{position:relative;border-left:1px solid var(--rule);border-bottom:1px solid var(--rule);padding:8px 0;margin:18px 0}.plot-row{height:28px;position:relative;margin:4px 0;background:var(--surface)}.plot-row i{position:absolute;inset-block:5px;background:var(--accent);min-width:2px;transition:width .2s,left .2s}.plot-row b{position:relative;padding:4px 6px;font:11px/28px var(--viz-font-ui);background:var(--paper);border-radius:3px}.axis{display:flex;justify-content:space-between;font-size:11px;color:var(--muted)}\n\n.cq{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;margin:20px 0}.slot{border:1px dashed var(--rule);border-radius:8px;padding:12px;min-width:0;font:12px var(--viz-font-ui)}.slot:nth-child(3){order:3}.slot:nth-child(4){order:2}.slot header{color:var(--muted)}.slot strong{display:block;font-size:20px;margin:10px 0;overflow-wrap:anywhere}.slot span,.slot small{display:block;min-height:2em}.slot small{font-size:11px;margin-top:9px}.slot.pending{border-style:solid;background:var(--accent-soft);border-color:var(--accent)}.slot.head{box-shadow:inset 0 0 0 2px var(--second)}.readout{min-height:7em}","js":"const $=s=>document.querySelector(s);const set=(id,v)=>$('#'+id).textContent=v;const t=k=>viz.t(k);function cells(id,values){$('#'+id).replaceChildren(...values.map(v=>{const e=document.createElement('div');e.className='cell '+(v.cls||'');e.textContent=v.text;e.title=v.title||v.text;return e;}));}function pressed(mode){document.querySelectorAll('[data-mode]').forEach(e=>e.setAttribute('aria-pressed',String(e.dataset.mode===mode)));}let slots=Array.from({length:4},()=>({phase:0,cid:null,pending:false})),head=0,tail=0,hp=1,tp=1,count=0,serial=0,consumed=0;function draw(){cells('host',[{text:head+' / phase '+hp,cls:'gold'}]);cells('device',[{text:tail+' / phase '+tp,cls:'on'}]);for(let i=0;i<4;i++){$('#slot-'+i).classList.toggle('pending',slots[i].pending);$('#slot-'+i).classList.toggle('head',i===head);set('cid-'+i,slots[i].cid===null?'—':'#'+slots[i].cid);set('phase-'+i,'phase '+slots[i].phase);set('pointer-'+i,(i===head?'HEAD ':'')+(i===tail?'TAIL':''));}const match=slots[head].phase===hp;set('match',slots[head].phase+' '+(match?'=':'≠')+' '+hp+'\\n'+t(match?'valid':'stale'));set('pending',count);set('consumed',consumed);$('#produce').disabled=count===4;$('#consume').disabled=!match;set('explanation',t('note'));}$('#produce').onclick=()=>{if(count===4)return;slots[tail]={phase:tp,cid:++serial,pending:true};tail=(tail+1)%4;if(tail===0)tp^=1;count++;draw();};$('#consume').onclick=()=>{if(slots[head].phase!==hp)return;slots[head].pending=false;head=(head+1)%4;if(head===0)hp^=1;count--;consumed++;draw();};$('#reset').onclick=()=>{slots=Array.from({length:4},()=>({phase:0,cid:null,pending:false}));head=tail=count=serial=consumed=0;hp=tp=1;draw();};draw();","audio":false,"strings":{"consume":"ホストがheadを消費","consumed":"消費済み総数","device":"コントローラtail / 書き込みphase","heading":"スロットに古いバイトが残っているのに、なぜ新しい完了として扱われないのか?","host":"ホストhead / 期待phase","intro":"コントローラに完了を生成させるか、ホストがheadスロットを消費する。一杯にして1周消費し、両者のphaseがどのように切り替わり、古いスロットの内容が自動的にクリアされないかを観察する。","match":"現在のheadでのチェック","note":"最も誤判しやすいのは、ロールオーバーしてスロット0に戻った後である:CIDはまだそこにあり、phaseは前のラウンドのもの。ホストは現在のheadのみをチェックし、他のスロットの偶然のphaseの一致を順序不同消費として扱わない。","pending":"未消費完了数","produce":"コントローラが完了を1つ書き込む","reset":"リセット","scope":"4スロットCQ、初期状態で全スロットphase=0、両者の現在のphase=1。CQのみをシミュレートし、有効な完了は順序どおり書き込まれ、CIDは身份識別のみを行う。プロデューサは未消費のスロットを上書きせず、ホストがheadを更新するとコントローラに通知済みとみなす。DMA順序バリア、エラー状態、SQ関連付け、実際のdoorbellタイミングは無視する。","scopeLabel":"モデルの範囲と規約","stale":"不一致、新しい完了を待機","valid":"一致、消費可能"}}
なぜdoorbellは固定の「1回のMMIO」に書けないのか
コマンドの公開前に、関連する書き込みがデバイスによってプロトコル通りに認識可能であることを保証する必要があります。ホストは複数のSQエントリをバッチで公開してから通知したり、CQ headを更新したりします。doorbellバッファ、ポーリング、割り込み結合などのメカニズムは、アクセス頻度を変更します。
そのため、NVMeは制御オーバーヘッドを削減できますが、プラットフォーム間で統一された「I/Oごとに正確に1回のMMIO、AHCIより固定で5倍速い」という結論は存在しません。完了レイテンシは、フラッシュメモリ、キャッシュ、キュー待機、CPU、NUMA、電源状態の影響も受けます。
3. LBA、NLB、PRPの具体例
論理ブロックサイズ4096バイトを例に、LBA 256から8192バイトを読み取る場合:
フィールドまたは計算 結果
起点のバイトオフセット 256 × 4096 = 1 MiB
論理ブロック数 8192 / 4096 = 2
コマンドNLB ゼロベースカウント、1を記入
コマンドの単位を正しく解釈するには、まずネームスペースのフォーマットを確定させる必要があります。
これはLinuxブロック層の512バイトセクター単位とは異なり、ドライバは変換を行う必要があります。実際の struct nvme_command には異なるコマンドフォーマットの共用体が含まれており、フィールドはすべてのコマンドで共通の平坦なメンバの列ではありません。マルチバイトフィールドはプロトコルに従ってリトルエンディエン符号化されます。
PRPはコントローラがアクセス可能なデータアドレスを記述する
コントローラのページサイズは4096バイト、開始オフセットは1024、総長さは8192であり、3つのページが必要です:
データセグメント 配置可能なバイト数
第1ページの残り部分 4096 − 1024 = 3072
第2ページ 4096
第3ページの残りデータ 1024
したがって、第1ページの後にさらに2つのページが必要であり、その後でPRP2の意味を判断できます。
PRP1は第1セグメントの起点を指し、対応するページ内のオフセットを許可します。
残りのデータが1ページだけで済む場合、PRP2はそのデータページを直接指すことができます。
この例では残りを2ページ必要とするため、PRP2はPRPリストを指し、リストによって後続のページアドレスが与えられます。
PRPリストは「PRP2は常に2番目のデータポインタ」という意味ではなく、リストがページを跨ぐ場合、リンクルールがあります。アドレスはDMA APIによって確立され、名前にPhysicalが含まれているからといって、CPU仮想アドレスや変換されていない物理アドレスを直接記入できるわけではありません。
SGLは型や長さなどの情報を含む記述子を使用し、サポートされている機能はコマンドセット、コントローラ、トランスポートによって異なります。NVMe/RDMA、NVMe/TCPのデータ転送は、PCIeホストメモリのPRPメカニズムをそのまま適用することはできません。参照エントリ:NVM Express 仕様 およびカーネル include/linux/nvme.h。
4. Linuxでの送信と回復パス
drivers/nvme/host/core.c は共有プロトコルとコントローラ/ネームスペースのライフサイクルを担当し、pci.c はPCIeトランスポートを処理し、tcp.c、rdma.c、fc.c などは各自のトランスポートを処理し、fabrics.c はfabricsの共通部分を提供します。
PCIeの初期化では通常、デバイスと管理キューを有効にした後、機能の取得、リソースのネゴシエーション、I/Oキューの作成、ネームスペースのスキャンが行われます。プローブと回復には非同期ワークが含まれており、特定バージョンの関数名リストを永遠に同期実行される固定順序と見なしてはいけません。
リクエストを送信する際、ドライバはコマンドの設定、データのマップ、リソース失敗の処理を行い、コマンドをコントローラに公開します。キューのロールオーバーにおいて、index & (depth - 1) を無条件に使用してはいけません:このビット演算は深さが2のべき乗の場合にのみ成立します。
タイムアウトはホストが完了を確認していないことを示すだけで、デバイスが書き込みを実行していないことを証明するものではありません。ドライバはステータスに基づいてabort、リセット、再接続、または失敗処理を実施し、古いリクエストと遅延した完了を処理します。上位層は「再試行が成功した」ことから、古い副作用が完全に発生しなかったと推論してはいけません。完了においても、通常のライトキャッシュ、Flush、FUAの永続化セマンティクスを区別する必要があります。
5. ネイティブマルチパスとANA
LinuxのネイティブNVMeマルチパスは、識別子と設定の条件を満たす場合、複数のコントローラのネームスペースパスを1つの論理アクセスオブジェクトに集約します。ANAはパスのアクセス状態(例:最適化済み、非最適化)を記述し、ホストはこれとI/Oポリシーに基づいてパスを選択します。
NUMA、ラウンドロビン、キュー深度などのポリシーは、それらをサポートするバージョンにおいてそれぞれ用途があり、デフォルトポリシーをラウンドロビンに固定してはいけません。実際の状態は実行中のシステムから読み取る必要があります。パス選択はI/Oエレベータの別名ではありません:前者はアクセスパスを選択し、後者はキュー内のリクエストを配置します。
マルチパスはパスの冗長性を高めますが、データのコピー、バックアップ、または独立したディスク間での複製を自動的には提供しません。障害回復中はリクエストがキューイングされるか失敗する可能性があり、レイテンシはコントローラと接続の回復ポリシーの影響を受けます。NVMe multipath を参照してください。
NVMe/TCP、RDMA、FCは、NVMeアクセスをそれぞれのトランスポートに拡張します。ネットワークの輻輳、認証/暗号化設定、再接続、ターゲットのバックエンドは、パフォーマンスと信頼性を変更するため、RDMAに条件を無視した固定のマイクロ秒レイテンシを記述してはいけません。
6. SCSI と device-mapper の位置づけ
SCSIの上位ドライバにはディスク(sd)、光学ドライブ(sr)、テープ(st)が含まれます。中層は一般的なコマンド管理とエラー回復を処理し、下位ドライバはHBAまたは特定のトランスポートに接続します。SATAもlibataなどのパスを経由してLinuxではSCSIディスクとして表示される可能性があるため、/dev/sdX だけでは物理バスを名前で判断できません。
device-mapperはターゲットに基づいて論理ブロックアドレスを下位デバイスにマッピングし、複数の層を組み合わせることができます:
ターゲット/メカニズム 役割 保証されないこと
linear 連結またはオフセットマッピング 冗長性の自動追加なし
crypt ブロック暗号化 LUKSフォーマットの個別解析なし、改ざんのすべてをデフォルトで認証しない
thin / thin-pool 必要に応じた割り当てと共有スナップショット 論理容量がすでに確保された物理空間と等しいわけではない
cache 高速デバイスによる低速デバイスのブロックキャッシュ ダーティデータは依然としてキャッシュデバイスの生存に依存する
writecache 特定の永続メディア上のライトキャッシュ 汎用ライトスルーキャッシュの名称変更ではない
multipath 複数のパスを集約 RAIDコピーと等しくない
raid DM内で対応するRAIDメカニズムを使用 これに基づいてMD RAIDの開発が停止したと主張できない
LVMはユーザー空間のボリューム管理システムであり、複数のDMターゲットを構成可能であり、「dm-linearコマンドのラッパー」ではありません。MD、DM RAID、LVMのインターフェースと管理関係は明確に区別する必要があります。
Thin pool がデータとメタデータの両方を監視する理由
thinボリュームはまず論理容量を宣言し、実際の書き込み時にデータブロックを割り当てます。スナップショットはブロックを共有し、後続の書き込みで割り当てとマッピングの更新がトリガーされる可能性があります。データプールが満杯になることとメタデータプールが満杯になることは異なる障害であり、キューイング、読み込み専用、またはエラーパスに入る可能性があり、具体的な動作は設定と状態によって決まります。
スナップショットは依然として元のプール内のデータとメタデータに依存しており、独立したバックアップではありません。ファイルの削除が即座にプールのスペースを回収する保証はなく、discard、スナップショット参照、ターゲットのサポート状況によっても異なります。thin provisioning を参照してください。
7. キャッシュモードが故障時にデータがどこにあるか
キャッシュモード 確認時に注目すべきデータ位置
writeback 最新バージョンはキャッシュデバイス上にのみ存在し、バックエンドは依然として古い状態
writethrough モードに従ってバックエンド書き込み完了後に確認
writearound キャッシュをバイパスして書き込み、無効化ルールは実装による
モード変更時の障害回復の根拠は、正常時の速度だけを比較してはいけません。
「SSDなら安全、HDDなら危険」というわけではなく、ダーティデータ、マッピングメタデータ、flush規約の永続性を確定させる必要があります。電力損失保護付きのキャッシュデバイスはいくつかの停電リスクを緩和できますが、デバイス自体の破損により、まだ書き戻されていないデータが失われる可能性があります。
dm-cache、dm-writecache、bcacheは異なる実装であり、管理インターフェースや移行/削除フローは共通ではありません。bcacheはbcachefsの略称ではありません。dm-cache 、bcache を参照してください。
8. 読み取り専用観察と位置特定
lsblk - o NAME,TYPE,SIZE,LOG-SEC,PHY-SEC,PKNAME,MOUNTPOINTS
nvme-cliをインストールした後、nvme list、nvme list-subsys でオブジェクトとパスを確認でき、nvme id-ctrl / id-ns で指定されたオブジェクトの機能を確認できます。SMARTのpercentage_usedは推定された耐久消耗であり、「残り寿命のカウントダウン」ではありません。エラーカウントは変化傾向と具体的なエラー解釈と組み合わせて確認する必要があります。
アプリケーションからI/Oエラーが見えた場合、論理ボリューム、DM/RAID、ネームスペース/パス、コントローラ、下位デバイスの順で確認します。複数のスタック層にわたる同じデータの統計を物理スループットとして重複して累積しないでください。ブロック層の測定と完了セマンティクスについてはブロックデバイス層 を、キーの階層についてはCrypto API とストレージ暗号化 を参照してください。