记一次emmc测速失败的问题

问题

更换EMMC之后使用 time dd if=/rootfs.tar.bz2 of=/mnt/testB bs=512 conv=fsync 命令测试会很慢。

然后换为bs=1M就是正常的了。

分析

于是换了个板子,用其他的EMMC用相同的命令进行测试,结果是好的。于是问AI发现可能是缓存的问题。

然后:

apt install mmc-utils
mmc extcsd read /dev/mmcblk0 | grep CACHE_SIZE

对比两个,一个是128KB的,一个是4MB的。

然后查看新换的EMMC的手册发现确实是这个,

alt text

使用dd命令的时候,不加bs参数,默认bs=512,

eMMC 内部的 Write Cache 大小,是决定小数据块(512B)可以存多少个然后统一存入,就是测试的121MB的数据,缓存128KB的需要EMMC内部调用945次,而缓存4MB的只需要调用30次。所以会有问题。

现象

同一片 eMMC 硬件,dd bs=512 测试写速度:

测试条件 RK3568 i.MX6ULL
dd bs=512
dd bs=512 conv=fsync 未测
dd bs=1M

根因

RK3568 的 / 分区挂载带了 sync 选项:

/dev/mmcblk0p7 on / type ext4 (rw,relatime,sync)

工作机制

  • sync 挂载:每次 write() 系统调用都等数据真正写入 eMMC 硬件才返回
  • dd bs=512 → 每次写 512 字节 → 触发一次 eMMC 单块 CMD25 写入 → 等待 ~2ms FTL 编程完成 → 再写下一块 → 几次循环,全是等待开销
  • dd bs=1M → 合并为一次多块写入,只等 1 次编程结束 → 满带宽

为什么 i.MX6ULL 看起来快

i.MX6ULL 没有 sync 挂载:

  • 数据写到 page cache(页缓存) 就返回,dd 测的是内存写入速率
  • conv=fsync 强制刷入硬件后同样变慢 → 证明两个板子的 eMMC 硬件小 IO 性能一致

诊断命令

# 检查是否带了 sync 挂载 
mount | grep mmcblk 
 
# 检查脏页阈值(默认值) 
sysctl vm.dirty_background_ratio vm.dirty_ratio 
 
# 检查 I/O 调度器 
cat /sys/block/mmcblk0/queue/scheduler 
 
# 确认 eMMC 工作模式 
cat /sys/kernel/debug/mmc0/ios 
 
# 绕过 page cache 测真实硬件速度(O_DIRECT) 
dd if=/rootfs.tar.bz2 of=/test.img bs=512 oflag=direct 
dd if=/rootfs.tar.bz2 of=/test.img bs=1M oflag=direct 

修复方案:

去掉 sync 挂载(推荐) 

# 编辑  /etc/fstab :

/dev/mmcblk0p7  /  ext4  rw,relatime,data=ordered  0  1 

# 临时验证(不重启):
mount -o remount,defaults / 

如果确实需要防掉电保护

用 data=ordered (默认)或 data=writeback + 余额电量正常关机,不要用 sync 挂载——它会直接杀死小 IO 性能。

通用教训

  1. sync 挂载是 Linux 小 IO 性能的第一杀手——每个 write() 都同步等硬件

  2. 大块 IO(bs=1M)能掩盖几乎所有性能问题——因为多块写入只等一次编程

  3. conv=fsync 是揭露真相的开关——测试 buffered IO 时必须加上才能看到真实硬件性能

  4. RK3568 的 HS200/HS400 配置没问题——问题不在接口速率,在文件系统挂载参数

  5. i.MX6ULL 并没有硬件优势——只是 page cache 替

涉及的关键概念

· eMMC 单块写入: CMD25 + 512B 数据 + R1b 等待 ~2ms FTL 编程

· eMMC 多块写入: CMD25 + N×512B 数据 + 停止 + R1b 仅等待 1 次

· page cache: Linux 内核缓存写入数据,后台异步刷入硬件

· sync 挂载: 禁用 page cache 延迟写,代价是小 IO 性能灾难

ps

# EMMC是否开启了缓存
mmc extcsd read /dev/mmcblk0 | grep CACHE_CTRL 
Control to turn the Cache ON/OFF [CACHE_CTRL]: 0x01
posted @ 2026-07-03 15:11  杨旭0324  阅读(10)  评论(0)    收藏  举报