TL

リアルタイムLinux(PREEMPT_RT)の設計

汎用Linuxを実時間化する設計判断が原理から分かります。割り込みのスレッド化、スピンロックのmutex化、優先度継承で最悪レイテンシをマイクロ秒級まで詰める仕組みを押さえられます。

応用PREEMPT_RTリアルタイムレイテンシ割り込みLinuxカーネル最終更新: 2026-06-21
TL;DR要点だけ先に
  • 1.PREEMPT_RTの目標は平均の高速化ではなく、最悪応答レイテンシの上限を数十マイクロ秒級へ抑え込み、締め切り遵守を保証可能にすること。
  • 2.中核は、横取り不能な区間を潰す3つの作り替え——割り込みハンドラのスレッド化、スピンロックのスリープ可能なmutex化、優先度継承の標準適用。
  • 3.代償はロック獲得コスト増とスループット低下。決定性(determinism)をスループットで買う、明確なトレードオフの上に成り立つ。

目的は「速い」ではなく「最悪値を保証する」

PREEMPT_RT が狙うのは、平均応答を速くすることではありません。最悪応答レイテンシ(worst-case latency)の上限を小さく、かつ予測可能にする ことです。イベント(割り込みや高優先度タスクの起床)が発生してから、本来走るべきタスクが実際に CPU を得るまでの遅れ——その最大値を、汎用カーネルのミリ秒級から数十マイクロ秒級へ詰めます。

なぜ汎用カーネルでは最悪値が膨らむのか。原因は 「横取り(プリエンプション)できない区間」が長く点在する ことに尽きます。フルプリエンプティブ(CONFIG_PREEMPT)でも、スピンロック保持中・割り込みハンドラ実行中・割り込み禁止区間では横取りが保留されます。詳しくは /os/kernel-preemption/ を参照。PREEMPT_RT は、この 横取り不能区間そのものを作り替えて潰す という方針を取ります。

リアルタイム=決定性

リアルタイムの本質は速さではなく「間に合うこと」、つまり遅延の上限が保証されることです。産業制御やモーション制御では、締め切りを1回でも落とすと不良や事故につながります。平均が良くても、運悪く長いカーネル処理に重なった瞬間に大きく遅れる——この テールレイテンシ を消すのが目的です。基本概念は /os/realtime-scheduling/ にまとめています。

設計判断1:割り込みハンドラのスレッド化

汎用カーネルの割り込みは二段構えで、上半分(hardirq)は 割り込み禁止 で走る最小区間です(/os/interrupt-top-bottom-half/)。この hardirq 区間は横取りもスケジュールもできないため、ここが長いほど最悪レイテンシが膨らみます。

PREEMPT_RT は、デバイスドライバの割り込み本処理を カーネルスレッド(threaded IRQ)へ追い出します。ハードウェア割り込みが入っても、上半分は「該当スレッドを起こす」だけで即座に抜け、実際の処理は SCHED_FIFO 優先度を持つ通常のカーネルスレッドとして走ります。

汎用カーネル:
  IRQ → [hardirq で本処理を実行]  ← 割り込み禁止・横取り不能の長い区間

PREEMPT_RT:
  IRQ → [hardirq は wake のみ] → irq/N-スレッドをスケジュール → 本処理
        ~数命令で抜ける          ↑ ここは横取り可能・優先度付き

効果は2つ。第一に、割り込み禁止区間が数命令まで縮み、最悪レイテンシへの寄与が消えます。第二に、割り込み処理が スケジューラの管理下に入る ため、特定割り込みより高優先度のリアルタイムタスクが割り込み処理を横取りできます。割り込みの「優先度」を OS が制御できるようになる、という点が決定的です。

設計判断2:スピンロックのmutex化

汎用カーネルのスピンロックは、取得すると内部で preempt_disable() を呼び、保持中は横取りを禁止 します(だからスピンロック中は眠れない)。クリティカルセクションが長いほど、その間ずっと横取り不能区間になります。スピンロック自体の設計進化は /os/spinlock-design-variants/ を参照。

PREEMPT_RT は、大半の spinlock_tスリープ可能なミューテックス(rtmutex)へ置き換えます。これにより、ロック保持中でも横取りが許され、必要ならロック待ちのタスクは CPU を手放して眠ります。横取り不能区間がロックの粒度から切り離されるのです。

性質汎用 spinlock_tPREEMPT_RT の spinlock_t
実体ビジーウェイト(回し待ち)rtmutex(スリープ可能)
保持中の横取り禁止(preempt_disable)許可
保持中のスリープ不可(atomic context)可能
優先度継承なしあり(標準で適用)
待ち手の挙動スピンし続けるブロックして CPU を譲る

ただし例外があります。真にアトミックでなければならない最小区間 のために、PREEMPT_RT は raw_spinlock_t を残します。スケジューラ内部や rtmutex 実装そのものなど、ここでスリープすると破綻する箇所はこちらを使い、従来通り横取り禁止のビジーウェイトとして振る舞います。つまり「ほぼ全部 mutex 化、ただし核心の最小区間だけ raw を残す」という二層構成です。

mutex化が成立する前提

スピンロックをスリープ可能にできるのは、上の割り込みスレッド化とセットだからです。割り込みハンドラがプロセス文脈のスレッドで走るようになって初めて、その中でロック待ちに眠れます。hardirq のままなら眠れない(atomic context)ため、両者は独立した最適化ではなく 相互に支え合う一体の設計 だと捉えてください。

設計判断3:優先度継承を標準にする

ロックをスリープ可能にすると、新たな危険が顕在化します。優先度逆転 です。高優先度タスクが低優先度タスクの持つロックを待つ間に、無関係な中優先度タスクが低優先度を横取りすると、待ち時間が中優先度の総実行時間に依存し、上限が消えます。リアルタイムでは致命的です。

PREEMPT_RT の rtmutex は 優先度継承プロトコル(PIP)を標準で組み込みます。ロック保持者を、待っている最高優先度タスクのレベルへ一時的に引き上げ、クリティカルセクションを早く抜けさせる。これで待ち時間が クリティカルセクション長で有界化 され、最悪値が計算可能になります。原理と Mars Pathfinder の事例は /os/priority-inversion-inheritance/ で詳述しています。

優先度逆転(継承なし):
  H が L のロックを待つ → M が L を横取り → H は M の実行が終わるまで無限に待つ

優先度継承(PREEMPT_RT):
  H が L のロックを待つ → L を H 相当へ昇格 → L が即座に抜けてロック解放 → H が走る
  (待ち時間 = L のクリティカルセクション長で有界)

継承を「あれば便利な機能」ではなく デフォルトの動作 に据えること自体が設計判断です。mutex 化が逆転リスクを生み、継承がそれを封じる。3つの判断が論理的に連鎖しているのが分かります。

残るレイテンシ源を潰し切る

3つの作り替えで大半の横取り不能区間は消えますが、なお残るレイテンシ源があり、これらの除去まで含めて初めて上限が保証されます。

レイテンシ源問題PREEMPT_RT の対処
長い割り込み禁止区間横取りもスケジュールも不能区間を分割・短縮し raw spinlock を最小化
softirq の偏在ネットワーク等の後処理が積もるスレッド化し優先度付きで制御
per-CPU 変数の保護preempt_disable で代用しがちローカルロックへ置き換え横取り可に
タイマー・遅延処理ハンドラ内の重い処理高分解能タイマーで起床し処理は別文脈へ
試験・面接の勘所:PREEMPT_RT を一文で

「横取りできない区間(割り込み禁止・spinlock 保持・atomic context)を、割り込みのスレッド化とロックの mutex 化で潰し、生じる優先度逆転を優先度継承で封じることで、最悪レイテンシの上限を保証する」——この一文で骨子を説明できれば十分です。逆に「PREEMPT_RT は速い」と答えると不正解。速いのは最悪値であって平均ではなく、平均はむしろ落ちます。

トレードオフと現在地

代償は明確です。スピンロックがスリープ可能 mutex になると、未競合時でも獲得コストが上がり、割り込みスレッド化は切り替えを増やします。結果として 平均スループットは低下 します。PREEMPT_RT は「決定性をスループットで買う」設計であり、機械学習の学習や大規模バッチのように総処理量が効く用途には不向きです。

歴史的には長らく out-of-tree のパッチ群でしたが、threaded IRQ・高分解能タイマー・優先度継承 mutex などの主要機能は段階的にメインライン化され、近年 PREEMPT_RT 本体もメインラインへ統合が進みました。実時間性は特殊なフォークではなく、ビルド設定で選べる汎用カーネルの一構成 へと位置づけが変わりつつあります。

まとめ

  • PREEMPT_RT の目的は平均高速化ではなく、最悪レイテンシの上限を数十マイクロ秒級へ保証 すること。
  • 中核は3つの作り替え——割り込みのスレッド化(割り込み禁止区間を最小化)、スピンロックの mutex 化(保持中も横取り可、ただし raw spinlock は残す)、優先度継承の標準適用(mutex 化が招く優先度逆転を封じる)。
  • 3つは独立でなく 相互に支え合う一体の設計。スレッド化があるから眠れ、眠れるから逆転が起き、継承がそれを有界化する。
  • 残る割り込み禁止区間・softirq・per-CPU 保護まで潰して初めて上限が成立する。
  • 代償は スループット低下。決定性をスループットで買う判断であり、用途を選ぶ。基礎は /os/kernel-preemption//os/realtime-scheduling/ も併読を。

OS Article

リアルタイムLinux(PREEMPT_RT)の設計を実務で読む

TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。

解決すること

PREEMPT_RT

比較で見る軸

難易度: advanced / カテゴリ: OS / タグ数: 6

導入後に効く点

中核は、横取り不能な区間を潰す3つの作り替え——割り込みハンドラのスレッド化、スピンロックのスリープ可能なmutex化、優先度継承の標準適用。

先に潰すリスク

用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。

数字・仕様の読み方
難易度
advanced
カテゴリ
OS
タグ数
6

判断チェックリスト

  • 自社の用途が「PREEMPT_RT / リアルタイム」に近いか確認する。
  • 強みである「PREEMPT_RTの目標は平均の高速化ではなく、最悪応答レイテンシの上限を数十マイクロ秒級へ抑え込み、締め切り遵守を保証可能にすること。」が本当に評価軸になるか確認する。
  • 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
  • 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
  • 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
  • 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。

次に確認する観点

PREEMPT_RTリアルタイムレイテンシ割り込みLinuxPREEMPT_RTリアルタイムレイテンシ
参考: 公式情報