SPI-NANDFLASH性能低问题
-
问题描述
使用过程中,发现nandflash的性能比较低,影响了系统启动速率。
初步分析
1、查看驱动代码,发现SPI频率已经配置成了100MHz,也开启了4线模式,按理理论最大传输速率可以达到50MB/s,而实际只有4.5MB/s,软件开销非常大。
2、把SPI频率设置成100MHz,传输速率也有2.x MB/s,再次印证软件开销非常大,软件(CPU)成为瓶颈。
3、通过top和perf工具分析,发现是dma中断处理消耗了大量的资源
4、发现spi通信过程中有大量的1、2、4、64字节的小数据量传输,
如果这些小数据量传输用spi查询模式做,是否能提升性能?各种测试
dd工具测试:
# dd.coreutils if=/dev/mtdblock3 of=/dev/null bs=100M count=1 1+0 records in 1+0 records out 104857600 bytes (105 MB, 100 MiB) copied, 22.8465 s, 4.6 MB/s # dd.coreutils if=/dev/mtdblock3 of=/dev/zero bs=4KB count=10000 10000+0 records in 10000+0 records out 40000000 bytes (40 MB, 38 MiB) copied, 8.60103 s, 4.7 MB/s # dd.coreutils if=/dev/mtdblock3 of=/dev/zero bs=1KB count=10000 10000+0 records in 10000+0 records out 10000000 bytes (10 MB, 9.5 MiB) copied, 2.21347 s, 4.5 MB/s
top工具分析
CPU: 0% usr 71% sys 0% nic 0% idle 7% io 0% irq 20% sirq Load average: 1.70 1.30 0.58 1/110 454 PID PPID USER STAT VSZ %VSZ %CPU COMMAND 147 2 root DW< 0 0% 73% [kworker/0:2H+kb] 9 2 root RW 0 0% 11% [ksoftirqd/0] 449 327 root D 101m 21% 4% dd.coreutils if=/dev/mtdblock3 of=/dev 49 2 root SW 0 0% 2% [spi0] 205 1 root S 485m 99% 1% /usr/bin/voice-service 450 327 root R 2544 1% 1% top 300 114 root S 12040 2% 0% /lib/systemd/systemd-udevd 96 1 root S 17764 4% 0% /lib/systemd/systemd-journald 192 1 messageb S 3292 1% 0% /usr/bin/dbus-daemon --system --addres 10 2 root IW 0 0% 0% [rcu_preempt] 159 2 root SW 0 0% 0% [xradio_bh] 202 1 root S 384m 79% 0% /usr/bin/appx 215 1 root S 289m 59% 0% /usr/bin/adbd 198 1 root S 87288 17% 0% /usr/bin/gstd --enable-http-protocol - 167 1 systemd- S 79268 16% 0% /lib/systemd/systemd-timesyncd 163 1 systemd- S 14340 3% 0% /lib/systemd/systemd-networkd 114 1 root S 12040 2% 0% /lib/systemd/systemd-udevd 299 114 root S 12040 2% 0% /lib/systemd/systemd-udevd 321 320 root S 8484 2% 0% (sd-pam) q^C07 1 root S 8344 2% 0% /usr/sbin/wpa_supplicant -u -i wlan0 -
perf工具分析
Samples: 54K of event 'cycles', Event count (approx.): 4804340650 Overhead Command Shared Object Symbol 25.93% dd.coreutils [kernel.kallsyms] [k] sun6i_dma_tasklet 13.66% dd.coreutils [kernel.kallsyms] [k] _etext 10.97% dd.coreutils [kernel.kallsyms] [k] sunxi_spi_dma_cb_rx 8.69% dd.coreutils [kernel.kallsyms] [k] finish_task_switch 4.73% dd.coreutils [kernel.kallsyms] [k] preempt_count_sub 4.56% dd.coreutils [kernel.kallsyms] [k] __asm_copy_to_user 3.02% dd.coreutils [kernel.kallsyms] [k] get_page_from_freelist 2.75% dd.coreutils [kernel.kallsyms] [k] __handle_mm_fault 2.02% dd.coreutils [kernel.kallsyms] [k] preempt_schedule_irq 1.73% dd.coreutils [kernel.kallsyms] [k] do_page_fault 1.53% dd.coreutils [kernel.kallsyms] [k] memset 1.19% dd.coreutils [kernel.kallsyms] [k] dma_pool_free 1.18% dd.coreutils [kernel.kallsyms] [k] generic_file_read_iter 1.09% dd.coreutils [kernel.kallsyms] [k] vchan_complete 1.03% dd.coreutils [kernel.kallsyms] [k] kfree 0.95% dd.coreutils [kernel.kallsyms] [k] copy_page_to_iter 0.74% dd.coreutils [kernel.kallsyms] [k] __alloc_pages_nodemask 0.73% dd.coreutils [kernel.kallsyms] [k] __sched_text_start 0.63% dd.coreutils [kernel.kallsyms] [k] vmacache_find 0.61% dd.coreutils [kernel.kallsyms] [k] __add_to_page_cache_locked 0.57% dd.coreutils [kernel.kallsyms] [k] find_get_entry
-
-
到不了理论值那么高吧,SPI-Nand顺序写估计能到2MB/s(四线),顺序读5MB/s差不多了。SPI-Nand随机写是120iops左右,随机读估计在600iops左右
-
-
@xiaowenge 到不了理论值的,应该小于理论值很多,但是不到理论值的1/10就有点低了。另外,uboot读nand能有接近10MB/s。
是否能优化spi小数据读写?
-
启动速度慢 是慢在uboot读内核到ddr的过程中吗?我测试海思的读速度在16MB/S左右 写在2MB/S左右
-
@chenlinfei 在 SPI-NANDFLASH性能低问题 中说:
不了理论值的,应该小于理论值很多,但是不到理论值的1/10就有点低了。另外,uboot读nand能有接近10MB/s。
是否能优化spi小数据读写?还有擦除耗时和编程耗时啥的,每page(2k)大概耗时在45us左右,算下来读取的速度应该在22M/s左右。DMA耗时的问题确实存在,已经内部在查这个问题了。
-
@xiaowenge 另外跟踪下来发现,sun6i_dma_tasklet 的性能比较低,如果能把这个部分优化,还可以提升不少。
总体来看,cpu占用率已经达到100%,性能瓶颈在软件处理上面了。
-
@xiaowenge 这个问题是否有进展,可否对外share?
-
@chenlinfei 还在查,还没找到病因,初步怀疑是5.4内核调度问题
-
@xiaowenge 其他版本内核是快的吗?
-
@chenlinfei 快亿点点(50%左右,还是达不到理论值,所以应该是有复合原因影响,复合影响的问题,都不好查)
-
SPI 读写是会影响什么性能
-
-
发现一个可能可以优化的点:每次dma transfer都会触发3次tasklet的执行,其中2次sun6i_dma_tasklet,1次vchan_complete。
[ 112.851477] vchan_complete [ 112.854540] sun6i_dma_tasklet [ 112.857142] sun6i_dma_tasklet
-
u-boot的读速率也只有不到10MiB/s,怀疑是SPI没有开启4线模式。
尝试开启4线模式后,读写会失败,是否可以帮忙看下?[02.134]bmp_name=bootlogo.bmp size 38454 38454 bytes read in 4 ms (9.2 MiB/s)
-
@chenlinfei 经过内核驱动等的优化,目前已经到了8.4MB/s,系统启动速率有了显著提升。
-
@chenlinfei 帅气
-
@bedrock 仍需继续努力提升
-
@chenlinfei 您好,兄弟,你是修改了那里提高的性能?可以将具体修改的地方发发吗
-
@chenlinfei 在 SPI-NANDFLASH性能低问题 中说:
u-boot的读速率也只有不到10MiB/s,怀疑是SPI没有开启4线模式。
尝试开启4线模式后,读写会失败,是否可以帮忙看下?[02.134]bmp_name=bootlogo.bmp size 38454 38454 bytes read in 4 ms (9.2 MiB/s)
uboot我们这边测试是可以达到18M的,
你开4线模式读写失败是什么情况?贴log看看?
你这内核驱动优化到8.4MB/s有点强,怎么做的?
我们这些分析到的根因是,cs拉低后隔比较长时间才传输,传输完也比较长时间才拉高,得看看代码逻辑是否有问题 -
@xiaowenge @Banquo
修改点1:见sun6i-dma.c,修改中有暴力魔改。
修改点2:抢占策略改成 Preemption Model (No Forced Preemption (Server))
sun6i-dma.cuboot中改成4线我不太会改,见下图。请教下你们是怎么改的?
我是这么改的:
-
好奇, 我也测试一下
花了 62秒,搬运了 250M 数据
root@TinaLinux:/# date;dd if=/dev/mtd3 of=/dev/null bs=1M;date; Thu Jan 1 08:30:41 CST 1970 250+0 records in 250+0 records out Thu Jan 1 08:31:43 CST 1970
我的测试结果:250/62= 4.03M/s
接下来我试一试楼上的补丁包 sun6i-dma.c
-
我根据楼上说得改完sun6i-dma.c 测试:
root@TinaLinux:/# time dd if=/dev/mtd3 of=/dev/null bs=4096 count=10240 [ 35.040957] usb1-vbus: disabling 10240+0 records in 10240+0 records out real 0m 8.84s user 0m 0.02s sys 0m 5.70s
-
root@TinaLinux:/# date;dd if=/dev/mtd3 of=/dev/null bs=1M;date; Thu Jan 1 08:07:50 CST 1970 250+0 records in 250+0 records out Thu Jan 1 08:08:41 CST 1970 root@TinaLinux:/# root@TinaLinux:/# root@TinaLinux:/# root@TinaLinux:/# time dd if=/dev/mtd3 of=/dev/null bs=4096 64000+0 records in 64000+0 records out real 0m 49.62s user 0m 0.27s sys 0m 36.03s
从 62 提高到 49秒, 速度 250/49 = 5.1M/s
有改善,但是没有想象中那么多。
-
@tigger 只修改抢占策略改成 Preemption Model (No Forced Preemption (Server)),性能提速大概18%
-
此回复已被删除! -
@banquo 还需要改别的地方吗?
-
@tigger 我只改了preemption model测试的
Copyright © 2024 深圳全志在线有限公司 粤ICP备2021084185号 粤公网安备44030502007680号