世界を動かす技術を、日本語で。

カーネル開発のための今後のRust言語機能

概要

  • Rust for Linux プロジェクトがRust言語の進化に貢献
  • カーネル開発向けの重要な言語機能3つに注目
  • 開発の遅さは「注目の分散」が主な原因
  • 新機能の安定化と優先順位付けが議論の中心
  • 今後のRust言語機能とLinuxカーネルへの影響

Rust for LinuxプロジェクトとRust言語の進化

  • Rust for Linux プロジェクトがRustコミュニティに大きな刺激を与えている現状

  • Tyler Mandry (Rust言語設計チーム共同リーダー)がKangrejos 2025で最新のRust機能を紹介

  • Rust for Linux開発者への感謝と、彼らが新機能推進の原動力であることを強調

  • Rust言語の新機能開発の遅さは「 注目の分散」によるものが大きい

  • Rust for Linuxが注目を集め、特定の機能に開発リソースが集中する効果

    • ボランティア主体のRust開発体制
    • Linuxカーネルが必要とする機能に焦点を当てた推進力
  • 今後追加予定のRust言語機能例

    • サイズ不明型の対応
    • 参照カウントの改善
    • ユーザー定義関数修飾子(constのようなもの)
  • Rust for Linuxが必要とする機能の優先順位付け

    • 現在カーネルで使われている unstable機能の安定化 が最優先
    • コード構造を変える言語機能
    • その他の新機能

カーネル開発に重要なRust言語機能3選

  • Field Projections(フィールド射影)

    • 構造体へのポインタから、そのフィールドへのポインタへ変換する仕組み
    • 標準の参照・ポインタ型では既に可能だが、独自スマートポインタ型では未対応
    • カーネルでの 参照カウント外部ロック などの用途に不可欠
    • 一般化されたフィールド射影により、C言語のような自然なアクセスがRustでも実現可能
    • RCU(Read-Copy-Update)との連携例
      • RCU保護フィールドへロックなしでアクセスできるバインディング実現
      • Mutexとの組み合わせによる効率的なデータ保護
  • Arbitrary Self Types(任意Self型)

    • メソッドのself引数に、PinやArcなどスマートポインタ型を指定可能にする提案
    • カーネルRustコードでのスマートポインタ多用によるニーズ増加
    • 新たなReceiverトレイト導入で、Derefとの相互作用問題を解決
    • ポインタ型ごとに任意Self型対応を明示的に選択できる仕組み
    • 機能安定化のため、Craterツールによる既存ライブラリへの影響検証が必要
  • In-place Initialization(インプレース初期化)

    • 構造体をPinでラップして初期化するpin_init!()マクロの言語組み込み化提案
    • カーネルコードの可読性・安全性向上
    • 大規模なFutureのヒープ配置や、traitのdyn互換性向上にも寄与
    • 複数案が検討中で、最小限の言語拡張から高度な型システム統合まで幅広い選択肢

Rust言語機能開発の現状と課題

  • 新機能開発は 慎重な設計安定性重視 のため進行が遅い
  • Rust for Linuxのような「利用者の声」が推進力となる重要性
  • Debian stableに含まれるRustバージョンへの対応が必須条件
    • Debian 14(2027年予定)までに機能安定化が必要
  • カーネル開発者からの積極的なフィードバックとテスト協力が求められる

Rust for Linuxプロジェクトの今後

  • カーネルバインディングにおける独自ポインタ型の簡素化
  • ドライバ開発の効率化と安全性向上
  • Rustコミュニティとカーネル開発者の 連携強化
  • 新機能の安定化とDebianへの組み込みに向けた取り組み継続

サポートのお願い

  • LWN はマーケティングが得意ではないが、開発者・管理者・FOSS支持者に不可欠な情報源
  • サブスクリプションによる継続的な情報発信の支援呼びかけ

Hackerたちの意見

これって、LinuxにおけるRustの最初の機能で、カーネルにほぼ独占的に役立つものじゃないように思える。私の感覚では、カーネル向けの機能に焦点を当てることで、言語や標準ライブラリの他の部分の開発が遅れている気がするんだよね。

私の理解では、システムプログラミングがRustの優先アプリケーションエリアで、OSや組み込み、他のベアメタルケースのプロジェクトがたくさんあるし、複雑なCコードベースとの相互運用性もある。ぱっと見た感じ、これらの機能はかなり一般的で、特にカーネルに結びついているわけじゃないと思う。実際のプログラミングでこういうことをするための重要なユーティリティだよね。

Rustが低レベルのシステムプログラミングに適してるのは分かるけど、ユーザースペースのコンパイルされた管理言語は他の用途にはずっと良い選択肢だと思う。SelfやInferno、Androidのようなアーキテクチャに従うシステムでは、低レベルのCのような機能に焦点を当てる努力に大きな意味は感じないな。

カーネルやファームウェアの開発にはたくさんの機能が追加されてるけど、みんなが注目してるわけじゃないんだよね。Philoppはこの分野で特に変化をもたらしてる人だよ。

この記事で説明されているトークの後、フィールドプロジェクションに関する作業が更新されたみたい。LossinがLWNに連絡して、すべての構造体のフィールドが構造的にピン留めされると考えられるようになったって。だから、Pinをプロジェクトすると、常にPinかそれに似た値が得られるようになるんだ。ああ、その部分見逃してた。結構技術的なポイントだけど、彼らがその決定を下してくれて嬉しいよ。たくさんの議論が進んだしね。

最終的なデザインはC++からインスパイアを受けたもので、保証された最適化の形になる。新しい値を構築してからすぐにヒープに移動させると、最初からヒープ上で構築されることになるんだ。提案の名前については議論があるみたいだけど、「最適化」って言うと誤解を招くから(オプションだったりバックエンドに依存するかもしれないって感じで)。

「統合ヒープ構築」や「統合ヒープ割り当て」ってどういうこと?

多分、問題の複雑さを誤解してるかもしれないけど、正しい呼び出し規約を定義するだけで解決できるんじゃない?「xより大きい構造体、またはマーカータイプでマークされた構造体は、呼び出し元が正しいサイズのバッファへのoutrefを提供して返され、呼び出し先がそのバッファに直接構造体を書き込む。」そうすれば、普通のコードを書くだけで済むんじゃない?例えば、fn initialize() -> A { // 初期化コード } みたいに。それで、他の多くの状況でも不必要なコピーが減るし。これだけの労力がこの問題にかけられて、提案された解決策がずっと不便に感じるから、何か見落としてる気がする。

なんでこれを裏方の最適化にするの?普通にnewを導入すれば、みんなにとってもっと分かりやすくなると思うんだけど。

機能が言及されるたびに、「誰かがカーネルにtokioを入れるまで楽しいことばかりだ」って思っちゃう。もっと言えば、Rustが十分に完成して、誰かが直接合成レンダラーを作ったら、カーネル内で完全に動作するアプリケーションができるかもしれなくて、それは…面白いかもしれないね。

カーネルで非同期ランタイムを実装するのは簡単だよ。カーネルのワークキューは、実質的にランタイムみたいなもんだからね。

これらの機能は本当に素晴らしいし、カーネル以外のケース(特に一般的なプロジェクション)にも役立つと思う。Linuxが言語を前に進めてるのを見るのはすごく嬉しい!

Rust for LinuxプロジェクトはRustにとって良いものだと思う。カーネルツリーで「find -name "*.rs"」をやって、これが何なのかを感じ取ってみたんだけど、API互換レイヤー(/rustにある)と、既存のドライバーの単純な書き換えに見える概念実証ドライバーがいくつかあるだけみたい。未完成のNVIDIAのやつを除いて、実際には使われてないみたいだし。AndroidのバインダーのRust書き換えも、なんか残骸みたいな感じだね。全体的にちょっと可愛いけど、プログラミング言語の共同開発の実験は、世界で最も重要なソフトウェアのソースツリー以外の場所でやるべきじゃない?Redoxは未来のOSになりそうなクールな実験ソフトウェアだし、そこでやればいいのに。

AppleシリコンのGPUドライバーはRustで書かれてて、著者はCで実装するのはもっと難しかっただろうと言ってる。まだアップストリームには上がってないけど。""" 普通、こんなに複雑なカーネルドライバーを新しく書くと、シンプルなデモアプリからGPUを同時に使う複数のアプリを持つフルデスクトップに移行する際に、いろんなレースコンディションやメモリリーク、使った後の解放問題などが発生するんだけど、そういうのが全然起こらなかったんだ!論理バグをいくつか修正しただけで、メモリ管理コードのコア部分で一つ問題があったけど、あとは全て安定して動いたよ!Rustは本当に魔法みたいだね!その安全機能のおかげで、ドライバーの設計がスレッドセーフでメモリセーフであることが保証されるんだ。ほんと、安全なだけじゃなくて良い設計に導いてくれる。""" > 全体的にちょっと可愛いけど、プログラミング言語の共同開発の実験は、世界で最も重要なソフトウェアのソースツリー以外の場所でやるべきじゃない?トーバルズは君に同意してないみたいだね。

「実験」って言葉は誤解を招くよ。Rustは十分に長く存在してて、信頼性の高いコードを書く上での実際の利点をたくさん示してるから、これがやりたいことだってわかってるんだ。

複雑なドライバーを持つ前に、ドライバーが構築されるインターフェースレイヤーが必要だよ。RfLプロジェクトはそれに取り組んでて、複雑なドライバーを提出するのに十分なインフラをアップストリームしてる。Redhatはnovaに取り組んでて、AsahiはAppleのGPU、CollaboraはARM Mali用のドライバーを作ってる。もし3つのGPUドライバーが複雑な実際のドライバーとしてカウントされないなら、何がカウントされるの?

私が見る限り、AndroidのバインダーのRust書き換えは、残存的なものだね。残存的ってどういうこと?Linusのツリーにあるコミットメッセージ(コミットeafedbc7c050c44744fbdf80bdf3315e860b7513の「rust_binder: Rust Binderドライバを追加」)を見ると、かなり完成度が高いように見えるよね。> Rustバインダーは、Androidオープンソースプロジェクトにおけるバインダーの正確性を検証するすべてのテストに合格しているよ。デバイスを起動して、さまざまなアプリや機能を問題なく動かせるんだ。Cuttlefish AndroidエミュレーターとPixel 6 Proの両方でこれを実行したよ。> 機能の互換性については、Rustバインダーは現在、Cバインダーがサポートするすべての機能を実装していて、一部のデバッグ機能を除いているよ。欠けているデバッグ機能は、Rust実装を上流に提出する前に追加される予定だよ。---- > このプログラミング言語の共同開発の実験は、世界で最も重要なソフトウェアのソースツリー以外の場所で行われるべきじゃないの?Linux用のRustは、もともとツリー外プロジェクトとして始まったんだ。問題は、ツリー外でどれだけ作業をしても、統合を真剣に試みるなら、いつかは実験的なサポートを取り込まなきゃいけないってことだね。今まさにそれが起こっているようなものだ。

現在のカーネルにおける既存のRustコードの比較的小さな範囲を、Rustがカーネルで使われることの有用性を否定するものとして見るのは難しいよね。なぜなら、主要なカーネルのメンテナーたちが、カーネルのコードベースにRustコードがマージされるのを阻止するために全力を尽くしていると公言しているから。

私が見る限り、AndroidのバインダーのRust書き換えは、残存的なものだね。これは間違いだよ。AndroidのバインダーのRust書き換えは、現在のC実装を完全に置き換える予定なんだ。https://www.phoronix.com/news/Rust-Binder-For-Linux-6.18 そして、AppleのMシリーズハードウェア用に書かれた大きなドライバのほとんどはRustで書かれていて、それらは単なる書き換えや概念実証ではないよ。

これが他の場所で行われるべきじゃないの? それは面白いアイデアだね。この人に技術的な決定に異議を唱えることを伝えてみたら? -> torvalds@linux-foundation.org

軽量クローン機能のRust RFCを見てるんだけど[1]、理解するのにちょっと時間がかかったよ。理解できたら、その機能にワクワクしたけど、しばらくすると、Rustが学ぶにはとても複雑な言語だということに再び気づいた。私にとって、どちらも学んでいない人間としては、'真の'モダンC++(Cにいくつかの追加機能があるもの)とHaskellの機能や概念が組み合わさったように見える。でも、人々はそれで役立つものを作るのが好きみたいだから、何か正しいことがあったんだろうね。だから、また本格的に使ってみようと思ってるよ。[1]: https://github.com/joshtriplett/rfcs/blob/use/text/3680-use....

CコードをRustに自動変換するためにLLMを使った研究やプロジェクトはある?チャット、USB、I2C、GPUドライバからRustコードを生成して、自動でビルドしてテストすることは可能?それとも、SQLite、Apache、Nginxなどの「小さな」プロジェクトから始めるのはどう?可能かな?