1,背景
文件系统的目的很简单,就是将磁盘里的数据读取到用户进程指定的内存中。在linux内核实际的实现中,除了将指定位置的磁盘内容读取到page cache中之外,根据临近原则,还会比指定位置的内容多读取一些内容到内存中,提高代码的运行效率。
2,实验描述
首先我用如下命令创建了一个8k大小的文件:
dd if=/dev/zero of=file bs=8k count=1
同时,我运行一个应用程序,先读文件file的前4k数据,然后再读后4k的数据。代码如下:
#include <unistd.h>
#include <fcntl.h>
main()
{
int fd;
char buf[4096];
sleep(30); //run ./funtion.sh to trace this process
fd = open("file", O_RDONLY);
read(fd, buf, 4096);
read(fd, buf, 4096);
close(fd);
}
最后,我使用ftrace的function_graph来获取这两次read的代码运行路径,脚本如下:
#!/bin/bash
debugfs=/sys/kernel/debug
echo nop > $debugfs/tracing/current_tracer
echo 0 > $debugfs/tracing/tracing_on
echo `pidof read` > $debugfs/tracing/set_ftrace_pid
echo function_graph > $debugfs/tracing/current_tracer
echo vfs_read > $debugfs/tracing/set_graph_function
echo 1 > $debugfs/tracing/tracing_on
我期望的效果是,通过function_graph的trace log,在第一次vfs_read运行的时候,可以看到从磁盘读取数据的过程,读取数据的大小除了应用指定的4k之外,剩余的4k也会预读到page cache中,这里面会涉及到文件系统,bio,io调度器和磁盘驱动这几个软件模块。在第二次vfs_read的过程中,由于第一次的预读,第二次直接page cache命中,可以看出预读机制对效率的提高。
3,实验步骤:
./read (期间留了30秒时间运行脚本,准备ftrace环境)
sudo ./function.sh
cat /sys/kernel/debug/tracing/trace > 8k.txt
4,实验结果:
使用vi -S折叠打开8k.txt,可以看到里面有两个vfs_read的调用过程,其中第一次读文件的过程如下:

可以简单看出里面包含了一次io调度和进程切换。
第二次vfs_read的过程如下:

文章详细描述了Linux内核中文件预读的工作原理,通过实验和代码分析展示了当应用程序读取文件时,内核如何利用pagecache进行预读,以及预读如何影响io调度和磁盘操作效率。作者还提供了调试技巧和相关参考文献。
最低0.47元/天 解锁文章
1458

被折叠的 条评论
为什么被折叠?



