关于在 MTD 上调整 Linux UBIFS 中文件系统缓存的问题

关于在 MTD 上调整 Linux UBIFS 中文件系统缓存的问题

我正在开发一个嵌入式Linux系统,内核是5.10.24,并且使用MTD上的UBIFS。

测试团队进行了一个测试,即写入磁盘文件(依次为openwriteclose),然后关闭系统电源。上电后,磁盘文件为空,没有真正写入数据。发现文件写入后,延迟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/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并且echo 1000 > /sys/block/mtdblock2/queue/iosched/write_expire.我想将FLASH写入时间从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_centisecs100(1秒),在文件写入后1秒重新启动系统可以使文件正确更新。

我需要阅读有关这些参数的更多信息,到目前为止我仍然不清楚为什么dirty_expire_centisecs很重要,它是否会启动另一个计时器来刷新脏数据???

相关内容