저는 커널 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
FLASH echo 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
그것이 왜 중요한지 명확하지 않습니다. 더티 데이터를 플러시하기 위해 또 다른 타이머를 시작합니까? ? ?