眼鏡止水

FPGA、ネットワーク機器、料理、そしてメガネ女子。

【Linux 5.0】デバイスツリーのCPUコア数は実在する数を超えてはいけない

概要

Linuxを実行可能なマルチコアシステムを実装する上では、Linuxカーネルの理解は欠かせません。

本記事は、RISC-V向けLinuxカーネルの実装を読み、筆者が思い込みを解消した備忘録です。

本編

筆者は現在、RISC-VのCPU (コア) を複数搭載したマルチコアシステムを開発しています。 また、筆者は過去にLinux on LiteX-VexRiscvを用いたマルチコアRISC-V SoCのシミュレーションについて紹介しました。

blog.ojioji.ikeojihouse.com

本記事は、Linux on LiteX-VexRiscvのノリでデバイスツリーを作成し、自分の環境で利用したところ、システムが起動しなかったというお話です。

Linux on LiteX-VexRiscvが配布するLinuxカーネルのイメージはv5.14のものです。 この環境において、筆者はシステムに実在するCPUコア数を超える数のCPUをデバイスツリーに登録した状態でシステムを起動しようとしました。 すると、セカンダリCPUの起動時に少々待ってからCPUnの起動に失敗した旨が表示されました。

[    0.040410] smp: Bringing up secondary CPUs ...
[    1.100982] CPU1: failed to come online
[    2.166129] CPU2: failed to come online
[    3.231268] CPU3: failed to come online
[    3.232132] smp: Brought up 1 node, 1 CPU

これを見た筆者は「Linuxは賢いなあ。ほなコア数増やしてもええようにデバイスツリーにたくさん書いといてもええんや。」と思い込んでしまいました。

ところかわって筆者の環境、筆者は上のように思い込んだままデバイスツリーに実際よりも多くのコアを記述しました。 すると、いつまでたってもカーネルが立ち上がってきませんでした。

これはおかしいと思い、システムのCPUのプログラムカウンタを確認したところ、どうやら無限ループに陥っていることがわかりました。 その無限ループはlinux/arch/riscv/kernel/smpboot.cで定義される__cpu_up関数内のようでした。

筆者の環境はLinuxカーネルv5.0を採用しており、__cpu_up関数は待機対象コアが起動するまで無限ループするという実装になっていました。 一方で、Linux on LiteX-VexRiscvが採用するv5.14では、起動を試みてから約1秒待機し、コアが起動していなければメッセージを表示して終了するという実装になっていました。 やってしまいましたな。 上記の変更はcommit e15c6e3で行われたようです。 RISC-V向けLinuxカーネルの開発もv5.0と比べてかなり進んでいる可能性を実感しました。

かくして、筆者は思い込みを解消し、カーネルv5.0を使っている間はひとまずコア数を実在とデバイスツリーで一致させるという方針を取ることにしました。 思い込みはよくないと身をもって知るとともに、そろそろ新しいバージョンのカーネルを使い始めたほうがいいのではないかと感じました。