1回のアプリケーションによる書き込みは、複数のデバイスコマンドに分割される場合もあれば、キャッシュに留まる場合もあります。ブロック層では、データ範囲、キューイング位置、完了の約束 をそれぞれ追跡する必要があり、アプリケーション IOPS とデバイスコマンド数を直接同一視することはできません。
参照目標 読書位置
bio、単位、分割と結合 第 1~2 節
マルチキュー、バッチ処理、スケジューリング 第 3~5 節
キュー深度、永続化、観測 第 6~9 節
1. 1回の write が 1回のデバイスコマンドに相当するわけではない
バッファリング書き込みは通常、ページキャッシュを先に更新し、後続のライトバックでブロック I/O が生成されます。キャッシュヒットによる読み取りでは、デバイスにアクセスしない場合もあります。ダイレクト I/O は一部のキャッシュパスをバイパスしますが、アラインメント、ファイルシステム、デバイスの制限により、1回の呼び出しが複数のリクエストに分解される可能性があります。
ファイル操作、bio、request、ハードウェアコマンドは1対1で対応しない
上位のデータ範囲
ファイルシステム / ダイレクトブロックアクセス
bio 記述
デバイス区間 + メモリフラグメント
request
キューとデバイスの制約に従って構成
上位への完了返却
完了と永続化は区別が必要
blk-mq スケジューリング / ディスパッチ
マージ、キューイング、タグ、バックプレッシャ
ドライバーとコントローラ
DMA、コマンド、完了ステータス
1つの bio は分割され、複数の bio は結合される可能性があります。完了順序も送信順序と一致する必要はありません。
bio はブロックデータ操作とそのメモリ範囲を記述する ものであり、ディスクトランザクションの原子単位ではありません。bio はクローン作成、分割、再マッピングが可能であり、互換性のある複数の bio は同じ request に結合されます。device-mapper、RAID などのスタック層では、異なる下位デバイス向けの I/O が生成されることもあります。
現代のカーネルでは、現在位置と残り長さは主に bio.bi_iter の bi_sector、bi_size などで記述され、bi_status は blk_status_t です。旧バージョンの平坦化メンバの擬似構造を、現在コンパイル可能な API として扱ってはいけません。
3種類の「セグメント」
bio_vec はメモリ範囲を記述し、開始ページ、オフセット、長さを含みます。現代の multipage bvec はページを跨ぐことができるため、必ずしも1つが1つのページに正確に対応するわけではありません。
bio イテレータは現在処理中の部分を記述しており、bi_vcnt のみから残りの I/O を推測することはできません。
ドライバーが最終的に使用する DMA スキャターギャザーセグメントは、マッピングとマージを経ており、元の bvec の数と一致する必要はありません。
マッピングルールについては、IOMMU と DMA API を参照してください。
2. セクタ単位と分割・結合
同じデバイスのバイト位置でも、異なる層で使用される単位は異なります。
表現層 1 MiB 開始位置の表現
バイトオフセット 1048576
Linux ブロック層 512 バイト セクタ 2048
4096 バイト ロジカルブロックの NVMe LBA 256
ブロック層のセクタは固定で 512 バイト単位でカウントされ、デバイスのロジカルブロックも 512 バイトである必要はありません。
連続する2つの 4 KiB bio のデバイス区間がそれぞれ [2048,2056) と [2056,2064) セクタの場合、操作、フラグ、キューの制限などが互換性があれば、8 KiB の request に合成される可能性があります。メモリの物理アドレスが隣接しているかどうかは唯一の条件ではなく、request は SG を使用して離散メモリを表現できるためです。
逆に、256 KiB の bio は、128 KiB の転送しか許可されていないパスや、セグメント数や境界の制約が厳しいパスでは、複数の request に分割される可能性があります。制限は総バイト数だけでなく、最大セグメント数、単一セグメントの長さ、境界、アラインメント、および異なる操作タイプの特異な制約を含みます。
したがって、アプリケーション IOPS、bio 数、request 数、デバイスコマンド数は同じ指標ではありません。マージ率の向上はコマンドオーバーヘッドを削減する可能性がありますが、それによってビジネスリクエストが減ったと見なすことはできません。
3. blk-mq:マルチエントリ並列実行、必ずしもロックレスではない
blk_mq_ctx は CPU 向けのソフトウェア送信コンテキストを提供し、blk_mq_hw_ctx はドライバーへのディスパッチキューの状态を管理します。CPU はキューマッピングに基づいて hctx を選択し、読み取り、書き込み、ポーリングなどのキュータイプにも異なるマッピングを持たせることができます。
hctx はソフトウェア構造体であり、コントローラが直接読み取る SQ メモリではありません。ドライバーは request をデバイスコマンドに変換し、自前のキューに配置します。ソフトウェアキュー、ハードウェアキュー、CPU数、割り込みベクタ数は等しいことが保証されておらず、ctx を汎用の per-cgroup キューと呼ぶことはできません。
マルチキューはホットスポットを分散共有しますが、キューリスト、スケジューラ、タグ割り当て、ドライバーでは依然としてロックやアトミック操作が必要になる場合があります。1つのスケジューラが request_queue 範囲の共有状態を維持することもあり、例えば mq-deadline のスケジューリング状態などです。「すべてのスケジューラが各 hctx 上で独立して動作する」と一律に記述することはできません。blk-mq ドキュメント を参照してください。
タグとバックプレッシャ
タグは、進行中の request を識別・管理するために使用され、完了パスがリクエストを特定できるようにします。スケジューラタグ、ドライバータグ、共有タグセットなど、異なる構成が存在します。各 request が作成から完了まで常に同じ固定ハードウェアタグのみを使用するとは限りません。
リソースが不足している場合、リクエストは待機、ディスパッチの遅延、再キューイング、または NOWAIT などの規約に従って即時実行不能として返される可能性があります。これは、デバイスがコマンドを受信した後にメディアエラーを返すこととは異なります。ドライバーがリクエストを受け入れた後、プロトコルに従って最終的に完了させる必要があり、「一時的にビジー」と「リクエストを保持しているが後で完了する」を混同してはいけません。
4. プラグ:短時間のバッチ処理、トランザクションではない
プラグは現在のタスクに関連付けられ、バッチ処理に適した request を一時保存し、マージの機会を増やし、個別ディスパッチのオーバーヘッドを削減します。基本的な呼び出し形式は以下の通りです。これは既存のカーネル送信パス内のローカル構造であり、ユーザー空間プログラムではありません。
struct blk_plug plug;
blk_start_plug ( & plug) ;
blk_finish_plug ( & plug) ;
パラメータは struct blk_plug * であり、current ではありません。プラグは、finish まですべての I/O を常に保留するわけではありません。ブロッキングスケジューリング、容量などの条件により、早期の送信を促すことがあります。また、バッチ全体の原子性完了や、送信順序でのバッチ全体の完了を保証するものではありません。
バッチ処理はスループットを増加させる一方で、待機時間も増加させる可能性があるため、バッチサイズを無限に拡大することはできません。読み書きの依存関係、flush、ファイルシステムトランザクションの順序は、対応するメカニズムによって保証されます。
5. スケジューラが解決するのはトレードオフ
スケジューラ 核心的な考え方 検証が必要なコスト
none エレベータソート戦略を余分に加えない ブロック層/ドライバーのキューイングが残っており、マージや待機がないわけではない
mq-deadline アドレスソートと期限切れキューの組み合わせで、読み書きの待機をバランスさせる expire はスケジューリングの目標であり、ハードウェア完了のリアルタイム上限ではない
kyber レイテンシフィードバックに基づき、異なるカテゴリの進行中リクエストを制限 トークンで並行性を制御しており、単純な固定レートトークンバーストではない
BFQ エンティティごとの予算と重み付けにより、帯域幅、公平性、応答性を提供 公平性/インタラクティブ性の最適化、キュー待機、スループットの間にトレードオフが存在
「NVMe には none、デスクトップには BFQ」といった一般論で測定を代替しないでください。ストレージメディア、デバイス内部の並列性、混合読み書き、cgroup、バックグラウンドライトバック、CPUコストは結論を変更します。
read_expire / write_expire は、アプリケーションから完了までの最大レイテンシを保証するものではありません。writes_starved は読み書きの選択戦略を制御するものであり、各ビジネスに SLA を設定するものではありません。スケジューラパラメータの単位と利用可能な項目は、実際の sysfs を参照してください。mq-deadline 、Kyber 、BFQ を参照してください。
6. キュー深度、スループット、レイテンシの定量的関係
安定したシステム、同じ測定境界において、リトルの法則 L = λ × W を使用します。
入力 数値
完了率 λ 100000 IOPS
平均応答時間 W 200 μs = 0.0002 s
平均在途数 L 100000 × 0.0002 = 20
統計的な境界を合わせてから、この平均値を解釈します。
この 20 は観測平均値であり、sysfs パラメータを強制的に 20 に設定する必要があるわけではありません。キューには変動があり、ソフトウェアとハードウェアにはそれぞれ割り当てがあります。並行性を増やすと、デバイスが飽和していない場合はスループットが向上する可能性があります。飽和後に深度を増やすと、主にキューイングとテールレイテンシが増加します。
同様に、100000 回の 4096 バイトのデータ操作は約 409.6 MB/s、つまり 390.625 MiB/s です。IOPS は、I/O サイズ、読み書き比率、同期セマンティクス、レイテンシと組み合わせて解釈する必要があります。
以下に、固定されたサービス能力を持つ閉ループキューを用いて、この数式を図示します。まず並行リソースを増やし、次にリクエスト深度を増やし、スループットのプラットフォームが出現した後、余分なリクエストがどこに停止するかを比較します。
λ = d min ( Q , K ) , W = λ Q
この図は理想的な閉ループモデルを採用しています。Q 個のリクエストが常に在途状態にあり、K 個の並列サービススロットがあり、各サービスの所要時間は d です。λ は毎秒の完了数、W は同じ境界内の平均時間です。
図を準備しています 再読み込み
スループットがプラットフォームに到達した後、余分な深度はどこへ行くのか? 飽和していない状態で並行性を増やすと、完了率が向上する。サービススロットが満杯になると、余分な作業は主にキューイングを増加させる。リトルの法則は、同じ統計的範囲内で平均量を使用して適用する必要がある。
{"id":"io-depth-throughput-latency","title":"スループットがプラットフォームに到達した後、余分な深度はどこへ行くのか?","summary":"飽和していない状態で並行性を増やすと、完了率が向上する。サービススロットが満杯になると、余分な作業は主にキューイングを増加させる。リトルの法則は、同じ統計的範囲内で平均量を使用して適用する必要がある。","height":1000,"html":"<h2 data-i18n=\"heading\"></h2><p class=\"intro\" data-i18n=\"intro\"></p><div class=\"control\"><label for=\"q\" data-i18n=\"q\"></label><output for=\"q\" id=\"q-value\"></output><input id=\"q\" type=\"range\" min=\"1\" max=\"16\" value=\"4\" step=\"1\"></div><div class=\"control\"><label for=\"k\" data-i18n=\"k\"></label><output for=\"k\" id=\"k-value\"></output><input id=\"k\" type=\"range\" min=\"1\" max=\"8\" value=\"4\" step=\"1\"></div><div class=\"control\"><label for=\"d\" data-i18n=\"d\"></label><output for=\"d\" id=\"d-value\"></output><input id=\"d\" type=\"range\" min=\"20\" max=\"1000\" value=\"100\" step=\"20\"></div><div class=\"track-row\"><span data-i18n=\"service\"></span><div id=\"service\" class=\"track\"></div></div><div class=\"track-row\"><span data-i18n=\"queued\"></span><div id=\"queued\" class=\"track\"></div></div><p class=\"caption\" data-i18n=\"rate\"></p><div class=\"curve\"><svg viewBox=\"0 0 320 150\" aria-hidden=\"true\"><path class=\"axes\" d=\"M10 5V135H310\"/><polyline id=\"curve-rate\"/><line id=\"mark-rate\" y1=\"5\" y2=\"135\"/><circle id=\"dot-rate\" r=\"4\"/></svg><span id=\"max-rate\"></span></div><div class=\"axis\"><span>Q=1</span><span>8</span><span>16</span></div><p class=\"caption\" data-i18n=\"latency\"></p><div class=\"curve\"><svg viewBox=\"0 0 320 150\" aria-hidden=\"true\"><path class=\"axes\" d=\"M10 5V135H310\"/><polyline id=\"curve-latency\"/><line id=\"mark-latency\" y1=\"5\" y2=\"135\"/><circle id=\"dot-latency\" r=\"4\"/></svg><span id=\"max-latency\"></span></div><div class=\"axis\"><span>Q=1</span><span>8</span><span>16</span></div><div class=\"metrics\"><div><span data-i18n=\"rate\"></span><strong id=\"rate\"></strong></div><div><span data-i18n=\"latency\"></span><strong id=\"latency\"></strong></div></div><div class=\"formula\" id=\"arithmetic\"></div><div class=\"copy\"><p id=\"explanation\" role=\"status\"></p><p class=\"reserve\" aria-hidden=\"true\" data-i18n=\"note\"></p></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.curve{position:relative}.curve svg{display:block;width:100%;height:auto;max-height:220px;overflow:visible}.curve .axes{fill:none;stroke:var(--rule)}.curve polyline{fill:none;stroke:var(--accent);stroke-width:3}.curve line{stroke:var(--second);stroke-width:1;stroke-dasharray:4 3}.curve circle{fill:var(--second)}.curve>span{position:absolute;left:14px;top:0;font:11px var(--viz-font-ui);background:var(--paper);padding:2px}.formula{min-height:6em}#queued{display:grid;grid-template-columns:repeat(8,minmax(0,1fr))}#queued .cell,#service .cell{min-height:20px;height:20px;padding:0;font-size:9px}","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)));}function draw(){const q=+$('#q').value,k=+$('#k').value,d=+$('#d').value,rate=Math.min(q,k)*1e6/d,latency=q/rate*1e6;for(const[id,v]of [['q',q],['k',k],['d',d]])set(id+'-value',v);cells('service',Array.from({length:8},(_,i)=>({text:i<k?'●':'—',cls:i<Math.min(q,k)?'on':'empty'})));cells('queued',Array.from({length:16},(_,i)=>({text:i<Math.max(0,q-k)?'●':'',cls:i<Math.max(0,q-k)?'gold':'empty'})));for(const[name,fn,max]of [['rate',n=>Math.min(n,k)*1e6/d,k*1e6/d],['latency',n=>n*d/Math.min(n,k),16*d/k]]){const points=Array.from({length:16},(_,i)=>[10+i*20,135-fn(i+1)/max*120]);$('#curve-'+name).setAttribute('points',points.map(p=>p.join(',')).join(' '));$('#mark-'+name).setAttribute('x1',points[q-1][0]);$('#mark-'+name).setAttribute('x2',points[q-1][0]);$('#dot-'+name).setAttribute('cx',points[q-1][0]);$('#dot-'+name).setAttribute('cy',points[q-1][1]);set('max-'+name,viz.number(max,0)+(name==='rate'?' IOPS':' μs'));}set('rate',viz.number(rate,0));set('latency',viz.number(latency,1));set('arithmetic','λ = min('+q+', '+k+') / '+d+' μs\\nQ = λ × W = '+q);set('explanation',t('note'));}for(const id of ['q','k','d'])$('#'+id).oninput=draw;draw();","audio":false,"strings":{"d":"各サービス時間 D / μs","heading":"スループットがプラットフォームに到達した後、余分な深度はどこへ行くのか?","intro":"キュー深度 Q、並列サービススロット K、固定サービス時間 D を変更する。2つの曲線は Q 軸を共有し、現在の点を縦線で示す。","k":"並列サービススロット K","latency":"平均応答 W / μs","note":"同じ Q の縦線上の2つの結果を見る。Q を K を超えて押し上げると、完了率はプラットフォームを維持したまま、平均応答時間は増加し続ける。これらは互いに無関係なパフォーマンスの数値ではない。","q":"在途深度 Q","queued":"サービス待ちのリクエスト","rate":"完了率 λ / IOPS","reset":"リセット","scope":"固定 Q の閉ループ、K 個の理想的な並列サービススロット、各項目の固定 D、他のボトルネックやジッターなし。λ=min(Q,K)/D、W=Q/λ。K は教育モデルの容量であり、実際の NVMe の固定された内部並列数には対応しない。平均曲線はテールレイテンシを予測するものではない。","scopeLabel":"モデルの範囲と規約","service":"サービススロット:青はサービス中、白は使用不可"}}
7. 完了、順序、永続化
ブロック層の完了通知は、現在のデバイススタックの契約においてその操作が終了したことを示すものであり、通常の write completion のみをもって、データが停電後も保持されるメディアに書き込まれたと断定することはできません。揮発性ライトキャッシュはこの境界を変更します。
フラグ 永続化の制約
REQ_PREFLUSH 後続のデータフェーズの前に、以前のキャッシュ書き込みの永続化を処理する
REQ_FUA 今回の書き込みが対応する永続化条件を満たしてから完了を報告する
デバイスネイティブのサポートとブロック層のシミュレーションでは、異なるコマンドシーケンスが生成されます。どちらも、任意の範囲の書き込みの原子性を直接保証するものではありません。ライトキャッシュ制御 を参照してください。
アプリケーションの fsync() は、ファイルシステムがデータと必要なメタデータを調整し、適切なブロック層操作をプッシュダウンします。ファイル作成/名前変更に関連するディレクトリの永続化については、ディレクトリ同期も考慮する必要があり、1つの bio フラグのみでファイルトランザクション全体を解釈することはできません。
8. 読み取り専用で実際のキューパラメータを確認
from pathlib import Path
fields = ( ' logical_block_size' , ' physical_block_size' , ' max_sectors_kb' ,
' max_hw_sectors_kb' , ' nr_requests' , ' scheduler' , ' write_cache' )
for dev in sorted ( Path ( ' /sys/block' ) . glob ( ' *' ) ) :
if dev . name . startswith ( ( ' loop' , ' ram' ) ) :
continue
print ( dev . name )
for field in fields :
try :
print ( ' ' , field , ( dev / ' queue' / field ) . read_text ( ) . strip ( ) )
except OSError :
pass
print ( ' ' , ' visible hctx directories:' , len ( list ( ( dev / ' mq' ) . glob ( ' [0-9]*' ) ) ) )
scheduler 内の角括弧は現在選択されている項目を示します。mq ディレクトリが存在しない場合は、スタックデバイスなどの場合による可能性があります。nr_requests を物理デバイスのキューあたりの最大コマンド数として一般的に解釈することはできず、max_sectors_kb にもすべてのデバイスに適用される固定のデフォルト値はありません。
9. 統計から証拠へ
iostat -x の await には、対応するデバイスの統計的範囲内の待機時間とサービス時間が含まれており、アプリケーションリクエストのエンドツーエンドのレイテンシではありません。%util が 100% に近づいても、並列デバイスにとって「スループットが絶対的な上限に達した」ことを意味するものではなく、CPU 利用率として扱うこともできません。
blktrace/ブロック層の tracepoint を使用して、キューイング、ディスパッチ、完了を観察できますが、分割、マージ、リトライ、部分的な完了、イベントの損失により、単純なアドレスによるペアリングは機能しなくなります。まず、アイデンティティと階層を特定し、その後で時間差を計算します。統計フィールドはブロックデバイス統計 を、トレーシング方法はトレーシングとデバッグ を参照してください。