2025/03/29 11:26 Where Do the Bytes Go?

やあ、ロボ子。今日はシステムコールについて話すのじゃ。

システムコールですか、博士。ユーザーが`write`を呼び出すところから始まるんでしたね。

そうそう。ユーザーが`write`を呼ぶと、libcの`write`関数がシステムコールを設定して、`locore.s`の`Xsyscall_meltdown`などを経由して、`trap.c`の`syscall`にたどり着くのじゃ。

`syscall`または`syscall.c`の`svc_handler`ですね。その後は、システムコール番号のチェックやアカウンティング処理が行われて、`mi_syscall`に移行するんでした。

`mi_syscall`では、デバッグフラグやトレースポイント、スタックの有効性、pledge、pinsなどのチェックが行われるのじゃ。セキュリティに関わる部分じゃな。

なるほど。そして、`sys_write`で引数が再構成され、`dofilewritev`が呼び出されるんですね。

`dofilewritev`では、ファイルディスクリプタからファイルを取得して、書き込み可能か確認するのじゃ。その後、ファイル操作に移行するぞ。

`vn_write`ではフラグのチェックやregimeの変換が行われ、`VOP_WRITE`で引数のパッキングとラッパーが行われるんですね。

その通り!そして、`ffs_write`でフラグとサイズのチェック後、ワークループに入るのじゃ。適切な転送サイズを設定して、ディスク上の正しい位置にバッファキャッシュからバッファを取得するぞ。

`uiomove`では、ユーザー空間からバッファへバイトをコピーする`memcpy`関数が使われるんですね。ユーザー空間からのコピーの場合、プリエンプションチェックと`copyin`を使ってデータを読み込むんでした。

そうじゃ。そして、`bdwrite`で遅延書き込みとしてキューに入れられ、完了を待たずに処理を進めるのじゃ。バッファがまだ書き込まれていない場合は、フラグを設定して`reassignbuf`を呼び出し、`vn_syncer_add_to_worklist`でリストに登録するぞ。

その後、`syncer_thread`が実行され、ダーティなvnodeのリストを処理するんですね。`VOP_FSYNC`を呼び出して`ffs_fsync`に移行し、`bawrite`または`bwrite`を呼び出すんでした。

`bwrite`では`VOP_STRATEGY`を呼び出し、`ufs_strategy`でデバイスvnodeにバッファを送信するために`spec_strategy`を呼び出すのじゃ。

`spec_strategy`では、デバイスのグローバルvtableを使用して`bdevsw[maj].d_strategy`を呼び出すんですね。そして、`sdstrategy`でバッファをディスクアクティビティのキューに入れ、デバイスに処理を開始するように指示するんでした。

その通り!`scsi_xsh_add`でディスクをリンクキューに追加し、`scsi_xsh_runqueue`でI/Oを実行するのじゃ。`scsi_iopool_run`を呼び出し、`ioh->handler`で`scsi_xsh_ioh`を実行して、最終的に`sdstart`に到達するぞ。

`sdstart`では、バッファをキューから取り出し、転送設定を行い、セクタと数を計算するんですね。そして、`scsi_xs_exec`を呼び出すんでした。

そうじゃ。`nvme_scsi_cmd`で読み込みまたは書き込みコマンドに応じて`nvme_scsi_io`を呼び出すのじゃ。

`nvme_scsi_io`では、DMAマッピングを設定し、`xs->data`のバイトをデバイスに転送できるようにするんですね。そして、`nvme_q_submit`を呼び出すんでした。

`nvme_q_submit`では、NVMEコマンドリングのDMAマッピングを行い、`nvme_scsi_io_fill`でデバイスのブロックアドレスを変換するのじゃ。`op_sq_leave`でデバイスレジスタを更新し、キューエントリを追加するぞ。

デバイスが割り込みを通知すると`nvme_intr`が呼び出され、`nvme_q_complete`、`nvme_scsi_io_done`、`scsi_done`を経て`sd_buf_done`に到達するんですね。

最後に、`biodone`が`wakeup`を呼び出し、`fsync`などで待機していたプロセスを再開させるのじゃ。これで一連の流れは完了じゃ。

システムコールって、本当に複雑ですね。でも、一つ一つのステップを理解していくと、全体の流れが見えてきて面白いです。

そうじゃろう、そうじゃろう。ところでロボ子、システムコールをマスターした暁には、どんな悪巧みをしようかの?

悪巧みなんてしませんよ、博士!私は平和利用しか考えていませんから。

つまらんのう。まあ、冗談じゃ。でも、システムコールを理解することは、システムの根幹を理解することに繋がるから、しっかり学んでおくと良いぞ。
⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。