Armadilloフォーラム

SDカード暗号化を行ったら、スリープができなくなった

iwaya_yoke

2025年5月29日 15時37分

掲題の通りセキュリティ対策のため、SDカードを暗号化した後、スリープ機能を使ったところ、適切にスリープモードを移行できなくなる現象が発生しています(SDカードを暗号化する前は適切にスリープモードへ移行はできていた)。

SDカード暗号化のために実施したことは以下の通り
1. カーネルコンフィギュレーション変更(以下の設定をMに変更して、kernel.swuをインストール)
- Device Drivers → Multiple devices driver support → Device mapper support
- Device Drivers → Multiple devices driver support → Crypt target support
- Cryptographic API → XTS support
2. cryptsetupインストール
3. SD暗号化
4. dmcryptによる自動暗号化解除
5. 再起動後、SDカードが暗号化されていることを確認

スリープ移行に出力されるエラーは以下の通りです。

Freezing of tasks failed after 20.005 seconds (3 tasks refusing to freeze, wq_busy=0)

SDカード暗号化の設定で追加した何らかのタスクがfreezeできていない?のかなと推定しています。
原因及び対策があればご教授いただけないでしょうか?

==========
製品型番:
Debian/ABOSバージョン:3.21.3-at.2
カーネルバージョン:5.10.234-cip55
==========

コメント

at_dominique.m…

2025年5月29日 16時32分

マルティネです。

> スリープ移行に出力されるエラーは以下の通りです。
>

> Freezing of tasks failed after 20.005 seconds (3 tasks refusing to freeze, wq_busy=0)
> 

このメッセージの後に dmesg 出力を確認するとタスクの名前とスタックが表示されるはずですので、それを確認してください。

> SDカード暗号化の設定で追加した何らかのタスクがfreezeできていない?のかなと推定しています。
> 原因及び対策があればご教授いただけないでしょうか?

Armadillo IoT A6E での暗号化を試してませんのでなんとも言えませんが、Armadillo IoT G4 と Armadillo IoT A9E で問題ないので機能としては動くはずです。
遅くてもさすがに20秒で freeze 処理は間に合うと思いますので、カーネル設定の問題かもしれません。
スタック類を確認すれば何か調べる方向が分かるかと。

よろしくお願いします

マルティネさん

ありがとうございます。
dmesgを実行すると、以下のような出力が得られました。

[  473.339377] Freezing remaining freezable tasks ...
[  493.351116] Freezing of tasks failed after 20.011 seconds (4 tasks refusing to freeze, wq_busy=0):
[  493.360144] task:kworker/u2:1    state:I stack:    0 pid:   51 ppid:     2 flags:0x00000000
[  493.360196] Workqueue:  0x0 (kcryptd/253:0)
[  493.360256] [<c0904d48>] (__schedule) from [<c09050a4>] (schedule+0x60/0xdc)
[  493.360293] [<c09050a4>] (schedule) from [<c012ffd8>] (worker_thread+0xe4/0x570)
[  493.360324] [<c012ffd8>] (worker_thread) from [<c01359a4>] (kthread+0x138/0x140)
[  493.360352] [<c01359a4>] (kthread) from [<c0100148>] (ret_from_fork+0x14/0x2c)
[  493.360366] Exception stack(0xc1319fb0 to 0xc1319ff8)
[  493.360383] 9fa0:                                     00000000 00000000 00000000 00000000
[  493.360403] 9fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[  493.360420] 9fe0: 00000000 00000000 00000000 00000000 00000013 00000000
[  493.360491] task:kworker/u2:4    state:I stack:    0 pid: 1443 ppid:     2 flags:0x00000000
[  493.360524] Workqueue:  0x0 (events_unbound)
[  493.360570] [<c0904d48>] (__schedule) from [<c09050a4>] (schedule+0x60/0xdc)
[  493.360599] [<c09050a4>] (schedule) from [<c012ffd8>] (worker_thread+0xe4/0x570)
[  493.360628] [<c012ffd8>] (worker_thread) from [<c01359a4>] (kthread+0x138/0x140)
[  493.360652] [<c01359a4>] (kthread) from [<c0100148>] (ret_from_fork+0x14/0x2c)
[  493.360664] Exception stack(0xc7d4bfb0 to 0xc7d4bff8)
[  493.360679] bfa0:                                     00000000 00000000 00000000 00000000
[  493.360699] bfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[  493.360716] bfe0: 00000000 00000000 00000000 00000000 00000013 00000000
[  493.360755] task:kworker/u2:0    state:I stack:    0 pid: 2816 ppid:     2 flags:0x00000000
[  493.360784] Workqueue:  0x0 (events_unbound)
[  493.360826] [<c0904d48>] (__schedule) from [<c09050a4>] (schedule+0x60/0xdc)
[  493.360854] [<c09050a4>] (schedule) from [<c012ffd8>] (worker_thread+0xe4/0x570)
[  493.360880] [<c012ffd8>] (worker_thread) from [<c01359a4>] (kthread+0x138/0x140)
[  493.360902] [<c01359a4>] (kthread) from [<c0100148>] (ret_from_fork+0x14/0x2c)
[  493.360914] Exception stack(0xc7e5bfb0 to 0xc7e5bff8)
[  493.360930] bfa0:                                     00000000 00000000 00000000 00000000
[  493.360951] bfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[  493.360967] bfe0: 00000000 00000000 00000000 00000000 00000013 00000000
[  493.360980] task:kworker/u2:2    state:I stack:    0 pid: 2906 ppid:     2 flags:0x00000000
[  493.361013] Workqueue:  0x0 (flush-179:8)
[  493.361053] [<c0904d48>] (__schedule) from [<c09050a4>] (schedule+0x60/0xdc)
[  493.361080] [<c09050a4>] (schedule) from [<c012ffd8>] (worker_thread+0xe4/0x570)
[  493.361106] [<c012ffd8>] (worker_thread) from [<c01359a4>] (kthread+0x138/0x140)
[  493.361126] [<c01359a4>] (kthread) from [<c0100148>] (ret_from_fork+0x14/0x2c)
[  493.361137] Exception stack(0xd04e5fb0 to 0xd04e5ff8)
[  493.361152] 5fa0:                                     00000000 00000000 00000000 00000000
[  493.361172] 5fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[  493.361189] 5fe0: 00000000 00000000 00000000 00000000 00000013 00000000
[  493.361204]
[  493.361212] Restarting kernel threads ... done.
[  493.361928] OOM killer enabled.
[  493.361935] Restarting tasks ... done.
[  493.403591] PM: suspend exit

at_dominique.m…

2025年5月29日 17時37分

出力ありがとうございます。

タスクが固まってなくて、暗号化関係のは関係してそうですね。
以下の2つのプロセスがあるということは SD カードに書き込んでるデータを待っている様に見えます:

> [  493.360196] Workqueue:  0x0 (kcryptd/253:0)
> [  493.361013] Workqueue:  0x0 (flush-179:8)

確認できること
* ハングしてなさそうなので、 /sys/power/pm_freeze_timeout に 20秒以上の値を設定してみるといずれサスペンドできそうに見えますが、サスペンドする際に20秒以上かかるとサスペンドする意味もなくなりますのであまり推奨できません。
* 起動時の cryptsetup open の際に「--perf-no_read_workqueue --perf-no_write_workqueue」を試してもいいかもしれません。
そうすると非同期の処理が少なくなりますので、コアの一つしかない A6E にはいいと思います。
* それでも suspend する時に flush が発生しますので dirty_bytes / sd の bdi max_ratio を調整してサスペンド前に書きこまないといけない量を減らしてください ( https://qiita.com/rarul/items/9257afd60d8ffb4c0229 に各設定の意味が説明されてます)。それか、suspend直前に sync コマンドを実行して書き込みをアプリケーション的に制限するのも有効だと思います。

よろしくお願いします。

マルティネさん

ありがとうございます。
試してみましたが、どれもうまくいきませんでした。
関係のあるコンテナをpodman stopで停止、umount、cryptsetup close、としてSDカード関連のあるものを停止しても、うまくスリープしてくれませんでした。

あと関係ありそうなSDカード暗号化に実施した設定としては、dmcryptで暗号化を自動解除するときに以下の設定を行っています。
dmcryptをsysinitレベルにしているのが影響したりしますでしょうか?

・/etc/conf.d/dmcryptに以下を追記

target=cryptsd
source='/dev/mmcblk1p1'
key='/etc/lukskeys/cryptsd.key'

・persist_file /etc/conf.d/dmcrypt
・rc-update add dmcrypt sysinit
・persist_file /etc/runlevels/sysinit/dmcrypt

ちなみに、kernel.swuをインストールした時点(SD暗号化する直前)までは、適切にスリープはできていました。

at_dominique.m…

2025年5月30日 19時11分

マルティネです。

カーネルをビルドして luks デバイスを作って、ある程度を書き込みしたら再現できました(SDカードじゃなくても再現します)

暗号化の問題で間違いないと思いますが、すみません理由は最後まで追ってません。

分かったこと:
* データを暗号化されてるデバイスに書き込まないと発生しない。また、発生し始めたら worker thread が終了するまでに直らない(明示的に worker thread を停止させない認識ですが、他のスレッドが起動してある程度の時間 idle になっていたら古いスレッドはいずれ終了して、終了されたらこの問題は発生しなくなる)
* ということは、flush 等の問題ではなく、書き込みを行った時に何かがあって worker を異常な状態にしてしまったということになりますので、完全にカーネルの不具合の領域に入ります。
* stack trace で特に何もわからない、他の worker thread と差はない(sysrq-t で確認)
* worker thread の実行歴史も確認したが怪しい関数はない (tracing 有効にして /sys/kernel/debug/tracing/events/workqueue/enable で確認)。
問題のあるスレッドでしか実行された関数はないのと、--perf-no_*_workqueue で暗号化関係の関数は workqueue で実行されてないので、worker 自体の問題ではなく、書き込み中で実行されていた worker がどこかから悪影響を受けた様に見えます
* テスト用のカーネルの v6.12 を試しても同じ問題ありますので、少なくとも最近までは直ってません。
* ちなみに Armadillo IoT G4 や Armadillo IoT A9E では再現できない問題です。CPU が一つしかないのも関係あるのではないかと推測してます。

すごく気になりますが、Armadillo IoT A6E での暗号化を標準のカーネルでサポートしてないので申し訳ないですがしばらくはこれ以上調べる時間を取れないと思います。
恐れ入りますが別で解析を進んでいただければ幸いです。
この問題は A6E の問題ではなさそうなので、最新の標準のカーネルで qemu で再現すればアップストリームで見てくれるかもしれません…
(それか、まだ開発の段階でしたら新しい Armadillo IoT A9E を検討するのもありと考えています)

大変お手数ですがよろしくお願いします