UBIFS volume is filled up by power cuts
Walter Stoll
Walter.Stoll at duagon.com
Fri Jun 4 06:21:45 PDT 2021
Hi all
During stress tests we observe NAND flashes being filled up by power cuts
without effectively holding according data. We were able to reproduce the
effect with a simplified test procedure as follows:
1) Switch on the device
2) Run the following script (with no parameters)
#!/bin/bash
size=${1:-4000000}
loops=${2:-20}
df | grep ubi0
for i in $(seq 1 ${loops}); do
head -c ${size} /dev/urandom > rnd.bin
rm rnd.bin
done
3) Switch off the device
Please note that the number of loops and the file size in the script above are
crucial. We had to play around with these parameters until the effect was
clearly visible.
Effect description
------------------
When we execute the test 10 times, we see the following script output:
ubi0:rootfs 439340 27760 411580 6% /
ubi0:rootfs 439340 31508 407832 7% /
ubi0:rootfs 439340 35248 404092 8% /
ubi0:rootfs 439340 39228 400112 9% /
ubi0:rootfs 439340 42968 396372 10% /
ubi0:rootfs 439340 46700 392640 11% /
ubi0:rootfs 439340 50680 388660 12% /
ubi0:rootfs 439340 54420 384920 12% /
ubi0:rootfs 439340 58160 381180 13% /
ubi0:rootfs 439340 62144 377196 14% /
=> We loose about 3800 1k-blocks per power-cut. As a result, the flash is left
unusable after about 100 test executions.
Environment description
-----------------------
Our devices run with a vanialla v5.4.69-rt39 kernel on a TI AM335x (Sitara)
based SoC (ARM aarch32 architecture). We run a very basic Linux system with the
following user space processes:
127 root 2784 S /sbin/udevd -d
331 root 2480 S /usr/sbin/dropbear -r /etc/dropbear/dropbear_rsa_hos
341 ntp 7568 S /usr/sbin/ntpd -u ntp:ntp -p /var/run/ntpd.pid -g
348 root 2304 S /sbin/syslogd -n -O /var/log/messages -s 1000 -b 3
351 root 2304 S /sbin/klogd -n
356 root 5232 S /usr/sbin/lighttpd -f /etc/lighttpd/lighttpd.conf
362 root 2904 S {start_getty} /bin/sh /bin/start_getty 115200 ttyO0
363 root 2304 S /sbin/getty 38400 tty1
377 root 3128 S -sh
We use mtd-utils version 2.1.2 commit 7b986779342021bda87c04da3bf729718736d8ab
from git://git.infradead.org/mtd-utils.git.
We use a Micron MT29F8G08ADAFAWP NAND flash (256k block size).
mtdinfo:
Name: rootfs1
Type: nand
Eraseblock size: 262144 bytes, 256.0 KiB
Amount of eraseblocks: 1984 (520093696 bytes, 496.0 MiB)
Minimum input/output unit size: 4096 bytes
Sub-page size: 1024 bytes
OOB size: 256 bytes
Character device major/minor: 90:12
Bad blocks are allowed: true
Device is writable: true
UBI/UBIFS relate kernel configuration:
CONFIG_UBIFS_FS=y
# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set
CONFIG_UBIFS_FS_LZO=y
CONFIG_UBIFS_FS_ZLIB=y
CONFIG_UBIFS_FS_ZSTD=y
# CONFIG_UBIFS_ATIME_SUPPORT is not set
CONFIG_UBIFS_FS_XATTR=y
CONFIG_UBIFS_FS_SECURITY=y
# CONFIG_UBIFS_FS_AUTHENTICATION is not set
CONFIG_MTD_UBI=y
CONFIG_MTD_UBI_WL_THRESHOLD=4096
CONFIG_MTD_UBI_BEB_LIMIT=20
# CONFIG_MTD_UBI_FASTMAP is not set
# CONFIG_MTD_UBI_GLUEBI is not set
# CONFIG_MTD_UBI_BLOCK is not set
Further information
-------------------
We executed the following further tests:
* Run mtd tests:
- nandbiterrs
- flash_stress
- flash_readtest
- nandpagetest
- nandsubpagetest
All tests pass except flash_readtest. This test returns us one error per
block:
libmtd: error!: Cannot write 256 OOB bytes to address 1024 (OOB \
offset 1024) - mtd6 OOB size is only 256 bytes
Error reading OOB in block 0, page 1
...
libmtd: error!: Cannot write 256 OOB bytes to address 519832576 (OOB \
offset 1024) - mtd6 OOB size is only 256 bytes
Error reading OOB in block 1983, page 1
We have no clue how to interprete this error. OOB starts at address 4096
not 1024.
* Run test with a non realtime v5.4.69 vanialla kernel.
=> same results
* Run test with a Micron MT29F8G08ABABAWP NAND flash (512k block size)
mtdinfo:
Name: rootfs1
Type: nand
Eraseblock size: 524288 bytes, 512.0 KiB
Amount of eraseblocks: 992 (520093696 bytes, 496.0 MiB)
Minimum input/output unit size: 4096 bytes
Sub-page size: 1024 bytes
OOB size: 224 bytes
Character device major/minor: 90:12
Bad blocks are allowed: true
Device is writable: true
=> same results
* Run modified script with sync instruction in the loop:
#!/bin/bash
size=${1:-4000000}
loops=${2:-20}
df | grep ubi0
for i in $(seq 1 ${loops}); do
head -c ${size} /dev/urandom > rnd.bin
rm rnd.bin
sync
done
=> The effect disappears. The same is true if we mount the partition
synchronously.
More information about the linux-mtd
mailing list