# システムコール
## 定義
システムコールは、ユーザープログラムがデバイスI/Oなどの特権的なオペレーションの実行をカーネルに要求するための明確に定義されたプロトコルである。ユーザーランドは、システムコールを基礎としてより高度なプログラミングインターフェイスであるシステムライブラリ(libc、glibcなど)を構築する。カーネルを単純に保つため、システムコールの数はできる限り少なく抑える努力がなされてきたが、それでも現行カーネルは数百のシステムコールを持つ。(Source: [[@2023__OReillyJapan__詳解 システム・パフォーマンス 第2版 - Chapter 3 オペレーティングシステム]] §3.2.3)
`read(2)`・`write(2)`・`open(2)`・`fork(2)`・`clone(2)`・`connect()`・`mmap()`・`brk()`・`futex(2)`などが主要なシステムコールである。`ioctl(2)`はほかの目的が明確なシステムコールに適さない雑多な管理機能に、`mmap(2)`は実行可能ファイル・ライブラリのマッピングやメモリマップトファイルの作成に、`futex(2)`は高速なユーザーモードミューテックスの実装に使われる。(Source: [[@2023__OReillyJapan__詳解 システム・パフォーマンス 第2版 - Chapter 3 オペレーティングシステム]] §3.2.3)
ドキュメント化されたシステムコール数はカーネルによって大きく異なる。UNIX Version 7が48個、SunOS(Solaris)5.11が142個、FreeBSD 12.0が222個であるのに対し、Linux 5.3.0-1010-awsは493個を数える。ケン・トンプソンは2012年、UNIXが当初20種のシステムコールしか持たなかったのに対し、直接の子孫であるLinuxが千を超えるシステムコールを持つに至った複雑度の増大に懸念を表明した。(Source: [[@2023__OReillyJapan__詳解 システム・パフォーマンス 第2版 - Chapter 3 オペレーティングシステム]] §3.3)
### システムコール分析(アプリケーション性能分析としての利用)
システムコール分析の目的は、システムコールのタイプと呼び出された理由を含め、システムコールがどこで時間を使っているかを明らかにすることである。対象は、execve(2)による新プロセスのトレーシング(execsnoop(8)。実行時間の短いプロセスの問題分析に使う)、read(2)/write(2)/send(2)/recv(2)等のI/Oプロファイリング(bpftrace。I/Oサイズ・フラグ・コードパスを調べ大量の小規模I/Oのような非効率を見つける)、カーネル時間分析(syscount(8)。%sysとして表示されるCPU時間の説明に使う。ページフォールト・非同期カーネルスレッド・割り込みは例外)の3つである。システムコールはman ページを持つドキュメント化されたAPIであり、同期的に呼び出されるためスタックトレースから呼び出し元のアプリケーションコードパスをたどれ、フレームグラフで可視化できる。(Source: [[@2023__OReillyJapan__詳解 システム・パフォーマンス 第2版 - Chapter 5 アプリケーション]] §5.4.3)
代表的な観測ツールとして、perf(1)のtrace サブコマンド(strace(1)相当だがCPU単位バッファでオーバーヘッドが低くシステム全体をトレース可能。引数変換はstrace(1)に劣る)、strace(1)(ptrace(2)ベースのブレークポイント方式で侵入的。dd(1)の実測でシステムコールを多用するコマンドの速度が1/73に低下した例が示される)、execsnoop(8)・syscount(8)(BCC/bpftraceツール)、bpftraceのワンライナー(ヒストグラムによるサイズ・レイテンシ分析)がある。(Source: [[@2023__OReillyJapan__詳解 システム・パフォーマンス 第2版 - Chapter 5 アプリケーション]] §5.5.1, §5.5.4〜§5.5.7)
## 横断的知見
- 3章はシステムコールを「カーネル内部の定義・数の変遷」という静的な観点で説明するのに対し、5章は同じシステムコールを「アプリケーションのどこで時間を使っているか」という動的な計測対象として扱う。両者を突き合わせると、システムコールはmanページを持つ安定APIであるために(3章§3.2.3の定義)、strace(1)・perf(1) trace・execsnoop(8)・syscount(8)といった多様なツールが同じイベント集合を異なるオーバーヘッド・粒度で計測できる、という設計上の利点が見える。(Source: [[@2023__OReillyJapan__詳解 システム・パフォーマンス 第2版 - Chapter 3 オペレーティングシステム]], [[@2023__OReillyJapan__詳解 システム・パフォーマンス 第2版 - Chapter 5 アプリケーション]])
- ptrace(2)ベースのstrace(1)(侵入的、dd(1)実測で1/73に減速)と、CPU単位バッファ・BPFベースのperf(1)/BCC/bpftrace(オーバーヘッドが大幅に低い)という2系統のトレーサーの間には、実測で数十倍〜数百倍のオーバーヘッド差があることが5章の具体例からわかる。これはkprobe/uprobeのオーバーヘッド実測値(4章、kprobe 76ns〜uretprobe 1,931ns)とあわせて読むと、トレーシング手法の選択がアプリケーション性能そのものに与える影響の大きさを裏づける。(Source: [[@2023__OReillyJapan__詳解 システム・パフォーマンス 第2版 - Chapter 4 可観測性ツール]], [[@2023__OReillyJapan__詳解 システム・パフォーマンス 第2版 - Chapter 5 アプリケーション]])
## 未解決の問い
- Linuxのシステムコール数が版を追うごとに増加する傾向(UNIX Version 7の48個→Linux 5.3の493個)が、実際の性能・保守コストにどう影響するかを定量化した一次研究は本wikiに未収載。
- vDSO(仮想動的共有オブジェクト)がユーザーモードだけで実装するシステムコール(`gettimeofday(2)`・`getcpu(2)`など)の範囲と、そのカバレッジの限界について詳細な一次資料が必要。
- strace(1)の将来バージョンがperf(1) trace の別名になるという5章の見通し(§5.5.4.1)は、その後(2020年以降)実際にどこまで進展したか、最新版の一次資料での追跡が必要。
## 関連
- ソース: [[@2023__OReillyJapan__詳解 システム・パフォーマンス 第2版 - Chapter 3 オペレーティングシステム]] / [[@2023__OReillyJapan__詳解 システム・パフォーマンス 第2版 - Chapter 5 アプリケーション]]
- 概念: [[コンテキストスイッチ]] / [[BPF]] / [[eBPF]] / [[フレームグラフ]] / [[スレッド状態分析]]
- エンティティ: [[Linux]] / [[bpftrace]] / [[BCC]]
## 出典
- [[@2023__OReillyJapan__詳解 システム・パフォーマンス 第2版 - Chapter 3 オペレーティングシステム]](§3.2.3 システムコールの定義・主要システムコール一覧、§3.3 カーネル間のシステムコール数比較)
- [[@2023__OReillyJapan__詳解 システム・パフォーマンス 第2版 - Chapter 5 アプリケーション]](§5.4.3 システムコール分析、§5.5.1 perf、§5.5.4 strace、§5.5.5 execsnoop、§5.5.6 syscount)