linux nvme的sendfile流程
在nvme的硬盘上使用sendfile系统调用,到底需要经过哪些流程?
do_sendfile--->do_splice_direct-->splice_direct_to_actor--->do_splice_to 对于xfs,其实就是xfs_file_splice_read
xfs_file_splice_read--->generic_file_splice_read--->__generic_file_splice_read--->mapping->a_ops->readpage--->xfs_vm_readpage-->mpage_readpage--->submit_bio
在splice_direct_to_actor函数中,有一个while循环,执行一段direct_splice_actor,返回之后,就执行do_splice_from-->generic_splice_sendpage-->splice_from_pipe-->__splice_from_pipe-->
splice_from_pipe_feed-->pipe_to_sendpage-->sock_sendpage-->kernel_sendpage-->inet_sendpage-->udp_sendpage(我用的是udp)
堆栈如下:
0xffffffff816093ed : inet_sendpage+0x6d/0xe0 [kernel]
0xffffffff8156b0bb : kernel_sendpage+0x1b/0x30 [kernel]
0xffffffff8156b0f7 : sock_sendpage+0x27/0x30 [kernel]
0xffffffff812329c3 : pipe_to_sendpage+0x63/0xa0 [kernel]
0xffffffff812328be : splice_from_pipe_feed+0x7e/0x120 [kernel]
0xffffffff81232e8e : __splice_from_pipe+0x6e/0x90 [kernel]
0xffffffff8123483e : splice_from_pipe+0x5e/0x90 [kernel]
0xffffffff81234905 : generic_splice_sendpage+0x15/0x20 [kernel]
0xffffffff8123368d : do_splice_from+0xad/0xf0 [kernel]
0xffffffff812336f0 : direct_splice_actor+0x20/0x30 [kernel]
0xffffffff81233424 : splice_direct_to_actor+0xd4/0x200 [kernel]
0xffffffff812335b2 : do_splice_direct+0x62/0x90 [kernel]
0xffffffff81203518 : do_sendfile+0x1d8/0x3c0 [kernel]
0xffffffff81204b6e : SyS_sendfile64+0x5e/0xb0 [kernel]
0xffffffff816b78c9 : system_call_fastpath+0x16/0x1b [kernel]
流程真长啊。
在2.6的内核中,generic_make_request会先调用__generic_make_request,然后__generic_make_request再调用q->make_request_fn 这个回调函数,
在3.10的内核中,generic_make_request 会直接回调 q->make_request_fn,针对nvme,多队列的这种情况,使用的是 blk_mq_requeue_work.
submit_bio-->generic_make_request--->q->make_request_fn--->blk_mq_requeue_work
任务的执行:blk_mq_make_request--->blk_mq_run_hw_queue,blk_mq_map_request等。
static struct request *blk_mq_map_request(struct request_queue *q,
struct bio *bio,
struct blk_map_ctx *data)
{
struct blk_mq_hw_ctx *hctx;
struct blk_mq_ctx *ctx;
struct request *rq;
int rw = bio_data_dir(bio);
struct blk_mq_alloc_data alloc_data; blk_queue_enter_live(q);
ctx = blk_mq_get_ctx(q); /*
* This assumes per-cpu software queueing queues. They could be per-node
* as well, for instance. For now this is hardcoded as-is. Note that we don't
* care about preemption, since we know the ctx's are persistent. This does
* mean that we can't rely on ctx always matching the currently running CPU.
*/
static inline struct blk_mq_ctx *blk_mq_get_ctx(struct request_queue *q)
{
return __blk_mq_get_ctx(q, get_cpu());
}
static inline struct blk_mq_ctx *__blk_mq_get_ctx(struct request_queue *q,
unsigned int cpu)
{
return per_cpu_ptr(q->queue_ctx, cpu);
}
在nvme中,如何把bio插入的queue,映射为在各个cpu上运行的sq呢?利用的是blk_mq_map_queue函数,
static struct blk_mq_ops nvme_mq_admin_ops = {
.queue_rq = nvme_queue_rq,------------------指定blk-mq向驱动提交request的函数
.complete = nvme_complete_rq,---------------完成队列处理
.map_queue = blk_mq_map_queue,--------------映射函数,将software queue和hardware queue对应
.init_hctx = nvme_admin_init_hctx,----------hardware Queue创建时调用,将NVMe Queue与Hardware Queue绑定
.exit_hctx = nvme_admin_exit_hctx,
.init_request = nvme_admin_init_request,----在分配Request时调用
.timeout = nvme_timeout,--------------------发生timeout时的调用
}; static struct blk_mq_ops nvme_mq_ops = {
.queue_rq = nvme_queue_rq,
.complete = nvme_complete_rq,
.map_queue = blk_mq_map_queue,----------映射函数
.init_hctx = nvme_init_hctx,
.init_request = nvme_init_request,
.timeout = nvme_timeout,
};
queue_rq指定blk-mq向驱动提交request的函数,map_queue定义如何将software queue和hardware queue对应,init_hctx是hardware Queue创建时调用(可以在这里将NVMe Queue与Hardware Queue绑定),init_request是在分配Request时调用,timeout是发生timeout时的调用。
linux nvme的sendfile流程的更多相关文章
- Linux查看非root流程执行
Linux查看非root流程执行 youhaidong@youhaidong-ThinkPad-Edge-E545:~$ ps -U root -u root -N PID TTY TIME CMD ...
- Linux kernel 的 sendfile 是如何提高性能的
Linux kernel 的 sendfile 是如何提高性能的 现在流行的 web 服务器里面都提供 sendfile 选项用来提高服务器性能,那到底 sendfile 是什么,怎么影响性能的呢? ...
- linux独有的sendfile系统调用--“零拷贝,高效”
参考:http://blog.csdn.net/caianye/article/details/7576198 如今几乎每个人都听说过Linux中所谓的"零拷贝"特性,然而我经常碰 ...
- Linux系统的启动流程
Linux系统的启动流程: 1.通电(通常按下电源键,开始通电) 2.加载BIOS (通常看到显示器提示按F2进入主板) 3.读取MBR (MBR硬盘的入口地址,用来装载引导) 4.进入引导 (通常有 ...
- Linux的开机启动流程
Linux的开机启动流程 1.开机BIOS自检 --> 检查CPU,硬盘等硬件信息 2.MBR[Major ...
- Linux操作系统-CentOS7启动流程和服务管理
Linux操作系统-CentOS7启动流程和服务管理 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.systemd POST --> Boot Sequence --&g ...
- Linux操作系统-CentOS6启动流程和服务管理
Linux操作系统-CentOS6启动流程和服务管理 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Linux组成 1>.Linux: kernel+rootfs ker ...
- linux系统的启动流程梳理
1. 不同版本的linux系统的启动流程 1.1 centos6.x系统的启动流程 其详细启动步骤如下: 1)开机,BIOS自检,检查各个硬件是否正常 2)读取硬盘MBR信息,引导系统启动 3)加载g ...
- 2021年3月-第01阶段-Linux基础-Linux系统的启动流程
Linux系统的启动流程 理解Linux操作系统启动流程,能有助于后期在企业中更好的维护Linux服务器,能快速定位系统问题,进而解决问题. 上图为Linux操作系统启动流程 1.加载BIOS 计算机 ...
随机推荐
- 【原创】Android AOP面向切面编程AspectJ
一.背景: 在项目开发中,对 App 客户端重构后,发现用于统计用户行为的友盟统计代码和用户行为日志记录代码分散在各业务模块中,比如在视频模块,要想实现对用户对监控点的实时预览和远程回放行为进行统计, ...
- 北漂的IT人
北京的互联网人,是工作日完全没有个人生活的一类人,也是整个北漂大队伍中,下班时间最晚的那一波人,如果赶上周末还要加班,那毫不夸张地说,你的整个人生都在互联网上奋斗着. 虽说十点上班让多少行内外的人羡慕 ...
- 北斗卫星同步时钟(NTP网络时钟服务器)成功投运世界级工程港珠澳大桥
北斗卫星同步时钟(NTP网络时钟服务器)成功投运世界级工程港珠澳大桥 北斗卫星同步时钟(NTP网络时钟服务器)成功投运世界级工程港珠澳大桥 本文由北京华人开创科技公司提供 原址在 http://www ...
- TPFrame框架之robot模块的基本使用
经过几天的努力,基本功能版已经完成,有待大家验证... robot插件主要的功能是帮助我们写部分代码的基本,目前阶段已经实现后台curd数据管理的基本操作,更多功能待续... 1.首先下载robot插 ...
- bridged(桥接模式)、NAT(网络地址转换模式)和host-only(主机模式)-VMware下三种网络配置方式
VMWare提供了三种工作模式,它们是bridged(桥接模式).NAT(网络地址转换模式)和host-only(主机模式).要想在网络管理和维护中合理应用它们,你就应该先了解一下这三种工作模式. 1 ...
- .NET HttpClient的缺陷
using (HttpClient client = new HttpClient()){} 每次发起http请求每次new httpClient,它会打开许多套接字,比你实际的需求多许多,这极大地增 ...
- 关于获得当前的index的方法
每日一句English(start from today): In the previous section we just displayed a list of string entered st ...
- app额外后台运行操作
//在视图中运行操作中进行周期操作 - (void)applicationDidEnterBackground:(UIApplication *)application { [self beingBa ...
- DAY6-小变化(java提示框)-2018-1-16
终于有一点点小变化了,今天学习了java里的对话框,有四种类型:1.确认对话框(showConfirmDialog) 2.可选择输入的对话框(showInputDialog) 3.信息对话框(show ...
- Postman基本使用——get、post请求、断言、环境变量
Postman是一款功能强大的网页调试与发送网页HTTP请求的Chrome插件. 它提供功能强大的 Web API & HTTP 请求调试. 它能够发送任何类型的HTTP 请求 (GET, ...