MTDのLinux UBIFSでのファイルシステムキャッシュ調整の問題について

MTDのLinux UBIFSでのファイルシステムキャッシュ調整の問題について

私はカーネル5.10.24を使用し、MTDでUBIFSを使用して組み込みLinuxシステムを開発しています。

テストチームはディスクファイル(open、、、writecloseに書き込んだ後、システムの電源を切るテストを行いました。電源を入れるとディスクファイルが空になり、実際にデータは書き込まれません。ファイルが作成されたことを確認してから約1分遅れてシステムを再起動すると、ファイルが更新されます。

私は少し研究をして、注目を集めました。

  1. ubifsはカーネルスレッドを作成しubifs_bgt0_0、約30秒ごとにそれを予約します。バッファをブロックレイヤーに書き込みます(おそらく間違っている可能性があります)。
  2. wbuf のタイマーを作成し、ubifs_bgt0_0タイマー期間dirty_write_intervalを定義に従ってunsigned int dirty_writeback_interval = 5 * 100; /* centiseconds */約 5 秒に設定します。これはテストチームが報告した1分遅れと一致しません。
  3. はい、/sys/block/mtdblock0/queue/scheduler5000、5秒です。[mq-deadline]/sys/block/mtdblock0/queue/iosched/write_expire

上記の結果を見ると、UBIFSでのファイル書き込みは5秒以内にFLASHへの書き込みになると考えられます。その前に電源装置を再起動すると、データが失われる可能性があります。

したがって、まず上記の分析を修正します。

2次に、にリストされている調整可能なパラメータを変更して分析を検証したいと思います3
次のように変更し、 echo 100 > /proc/sys/vm/dirty_writeback_centisecsFLASHecho 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なぜそれが重要なのか明確ではありません。ダーティデータをフラッシュするために別のタイマーを起動しますか? ? ?

関連情報