私はカーネル5.10.24を使用し、MTDでUBIFSを使用して組み込みLinuxシステムを開発しています。
テストチームはディスクファイル(open
、、、write
)close
に書き込んだ後、システムの電源を切るテストを行いました。電源を入れるとディスクファイルが空になり、実際にデータは書き込まれません。ファイルが作成されたことを確認してから約1分遅れてシステムを再起動すると、ファイルが更新されます。
私は少し研究をして、注目を集めました。
- ubifsはカーネルスレッドを作成し
ubifs_bgt0_0
、約30秒ごとにそれを予約します。バッファをブロックレイヤーに書き込みます(おそらく間違っている可能性があります)。 - wbuf のタイマーを作成し、
ubifs_bgt0_0
タイマー期間dirty_write_interval
を定義に従ってunsigned int dirty_writeback_interval = 5 * 100; /* centiseconds */
約 5 秒に設定します。これはテストチームが報告した1分遅れと一致しません。 - はい、
/sys/block/mtdblock0/queue/scheduler
5000、5秒です。[mq-deadline]
/sys/block/mtdblock0/queue/iosched/write_expire
上記の結果を見ると、UBIFSでのファイル書き込みは5秒以内にFLASHへの書き込みになると考えられます。その前に電源装置を再起動すると、データが失われる可能性があります。
したがって、まず上記の分析を修正します。
2
次に、にリストされている調整可能なパラメータを変更して分析を検証したいと思います3
。
次のように変更し、
echo 100 > /proc/sys/vm/dirty_writeback_centisecs
FLASHecho 1000 > /sys/block/mtdblock2/queue/iosched/write_expire
書き込み時間を50秒から1秒に短縮したいと思います。
上記の変更でディスク書き込みテストを実行し、2秒以内にシステムの電源を切ります。しかし、驚くべきことに、ファイルが正しく書かれていませんでした!
上記の2つのパラメータを別の値(50秒未満)に変更しようとしましたが、50秒以内にシステムの電源を入れ直してもFLASHにデータを書き込むことはできません。
私はFtraceを使ってファイルが作成された後に呼び出される関数を調べましたecho 100 /proc/sys/vm/dirty_writeback_centisecs
。
約10秒間のFtraceです(ファイルが作成された後)。
######### 10 centiseconds
# CPU DURATION FUNCTION CALLS
# | | | | | | |
1) | ubifs_write_iter() {
1) + 18.334 us | ubifs_write_begin();
1) + 10.833 us | ubifs_write_end();
1) + 62.167 us | }
------------------------------------------
1) exe-399 => ubifs_b-72
------------------------------------------
1) | mtd_write() {
1) | mtd_write_oob() {
1) | mtd_write_oob_std() {
1) | emu_nand_write_oob() {
1) ! 491.167 us | nand_do_write();
1) ! 502.000 us | }
1) ! 507.167 us | }
1) ! 512.667 us | }
1) ! 525.667 us | }
電源を入れ直してもディスクファイルは記録されません。
これは、ファイルが作成されてから60秒間取得された関数トレースです。
# tracer: function_graph
#
# CPU DURATION FUNCTION CALLS
# | | | | | | |
1) | ubifs_write_iter() {
1) + 20.000 us | ubifs_write_begin();
1) 9.000 us | ubifs_write_end();
1) + 59.166 us | }
------------------------------------------
1) exe-924 => kworker-61
------------------------------------------
1) | ubifs_writepage() {
1) + 49.500 us | ubifs_write_inode();
1) ! 110.000 us | }
1) 3.833 us | ubifs_write_inode();
0) | mtd_write() {
0) | mtd_write_oob() {
0) | mtd_write_oob_std() {
0) | emu_nand_write_oob() {
0) ! 477.666 us | nand_do_write();
0) ! 489.000 us | }
0) ! 493.833 us | }
0) ! 500.000 us | }
0) ! 516.500 us | }
0) | mtd_write() {
0) | mtd_write_oob() {
0) | mtd_write_oob_std() {
0) | emu_nand_write_oob() {
0) ! 459.333 us | nand_do_write();
0) ! 465.667 us | }
0) ! 470.000 us | }
0) ! 474.666 us | }
0) ! 481.500 us | }
1) + 54.333 us | ubifs_write_inode();
1) + 26.000 us | ubifs_write_inode();
1) + 20.666 us | ubifs_write_inode();
1) + 19.834 us | ubifs_write_inode();
1) + 14.000 us | ubifs_write_inode();
1) + 13.667 us | ubifs_write_inode();
1) + 11.500 us | ubifs_write_inode();
1) + 14.333 us | ubifs_write_inode();
0) | mtd_write() {
0) | mtd_write_oob() {
0) | mtd_write_oob_std() {
0) | emu_nand_write_oob() {
0) ! 471.167 us | nand_do_write();
0) ! 481.167 us | }
0) ! 486.500 us | }
0) ! 492.167 us | }
0) ! 506.166 us | }
#
再起動すると、ディスクファイルが正しく記録されます。
Ftraceの違いはほぼぐらいになるようですがinode
、調整が可能かどうかはよくわかりませんね!
そのため、UBIFSファイルの書き込みを調整しようとしたときに重要なことを見逃しているようです。
答え1
ファイルを書くハンドルを見つけたと思います。すぐにフラッシュストレージに。
dirty_writeback_interval
以下に定義されている別のパラメータがありませんunsigned int dirty_expire_interval = 30 * 100; /* centiseconds */
。
dirty_writeback_centisecs
(1秒)に設定すると、100
ファイルを書き込んでから1秒後にシステムを再起動すると、ファイルが正しく更新されることがあります。
これらのパラメータについてもっと読む必要があります。これまでは、dirty_expire_centisecs
なぜそれが重要なのか明確ではありません。ダーティデータをフラッシュするために別のタイマーを起動しますか? ? ?