IO调度器(二) IO的中断返回

IO的中断返回也是相当让人激动的一件事情:

28470  1)               |        handle_irq() {
 28471  1)   0.237 us    |          irq_to_desc();
 28472  1)               |          handle_edge_irq() {
 28473  1)   0.060 us    |            _raw_spin_lock();
 28474  1)               |            ack_apic_edge() {
 28475  1)   0.051 us    |              irq_complete_move();
 28476  1)   0.044 us    |              irq_move_irq();
 28477  1)   1.288 us    |            }
 28478  1)               |            handle_irq_event() {
 28479  1)   0.045 us    |              _raw_spin_unlock();
 28480  1)               |              handle_irq_event_percpu() {
 28481  1)               |                ahci_interrupt [libahci]() {
 28482  1)   0.046 us    |                  _raw_spin_lock();
 28483  1)               |                  ahci_handle_port_interrupt [libahci]() {
 28484  1)               |                    ata_qc_complete_multiple() {        // qc = ata_qc_from_tag(ap, tag); (会得到最终的command)
 28485  1)               |                      ata_qc_complete() {
 28486  1)               |                        __ata_qc_complete() {
 28487  1)   0.321 us    |                          ata_sg_clean();
 28488  1)               |                          ata_scsi_qc_complete() {
 28489  1)               |                            scsi_done() {
 28490  1)               |                              blk_complete_request() {
 28491  1)               |                                __blk_complete_request() {
 28492  1)   0.046 us    |                                  cpus_share_cache();
 28493  1)   0.588 us    |                                }
 28494  1)   0.961 us    |                              }
 28495  1)   1.342 us    |                            }
 28496  1)   0.051 us    |                            ata_qc_free();
 28497  1)   2.146 us    |                          }
 28498  1)   3.

上面是我lenovo笔记本上ATA硬盘中断返回的代码, 其中断处理函数是ata_qc_complete,

发现, 环环相扣的结构体,从中断的scsi指令,我们能追溯到block层封装的request, 然后把这个request放到软中断中去了, 然后该赢中断平安返回,

下面就是软中断处理主场了!

28512  1)               |        irq_exit() {
 28513  1)               |          __do_softirq() {
 28514  1)   0.044 us    |            msecs_to_jiffies();
 28515  1)               |            blk_done_softirq() {
 28516  1)               |              scsi_softirq_done() {
 28517  1)               |                scsi_decide_disposition() {
 28518  1)   0.125 us    |                  scsi_handle_queue_ramp_up();
 28519  1)   0.563 us    |                }
 28520  1)   0.070 us    |                scsi_log_completion();
 28521  1)               |                scsi_finish_command() {
 28522  1)               |                  scsi_device_unbusy() {
 28523  1)   0.044 us    |                    _raw_spin_lock_irqsave();
 28524  1)   0.042 us    |                    _raw_spin_unlock();
 28525  1)   0.049 us    |                    _raw_spin_lock();
 28526  1)   0.059 us    |                    _raw_spin_unlock_irqrestore();
 28527  1)   1.474 us    |                  }
 28528  1)   0.086 us    |                  sd_done();
 28529  1)               |                  scsi_io_completion() {
 28530  1)               |                    blk_end_request() {
 28531  1)               |                      blk_end_bidi_request() {
 28532  1)               |                        blk_update_bidi_request() {
 28533  1)               |                          blk_update_request() {
 28534  1)   0.154 us    |                            blk_account_io_completion();
 28535  1)   0.132 us    |                            bio_advance();
 28536  1)               |                            bio_endio() {

时间: 2024-12-31 14:57:52

IO调度器(二) IO的中断返回的相关文章

Linux IO 调度器

Linux IO Scheduler(Linux IO 调度器) 每个块设备或者块设备的分区,都对应有自身的请求队列(request_queue),而每个请求队列都可以选择一个I/O调度器来协调所递交的request.I/O调度器的基本目的是将请求按照它们对应在块设备上的扇区号进行排列,以减少磁头的移动,提高效率.每个设备的请求队列里的请求将按顺序被响应.实际上,除了这个队列,每个调度器自身都维护有不同数量的队列,用来对递交上来的request进行处理,而排在队列最前面的request将适时被移

Linux IO Scheduler(Linux IO 调度器)

每个块设备或者块设备的分区,都对应有自身的请求队列(request_queue),而每个请求队列都可以选择一个I/O调度器来协调所递交的request.I/O调度器的基本目的是将请求按照它们对应在块设备上的扇区号进行排列,以减少磁头的移动,提高效率.每个设备的请求队列里的请求将按顺序被响应.实际上,除了这个队列,每个调度器自身都维护有不同数量的队列,用来对递交上来的request进行处理,而排在队列最前面的request将适时被移动到请求队列中等待响应. IO调度器在内核栈中所处位置如下: 内核

IO调度器

由于对blktrace的好奇,来到了block层.通过阅读block层的代码,自己的几个错误认知被纠正,比如 一) 同步操作时,进程是在驱动中睡觉真实情况是:进程在文件系统睡觉 二) 对同一个数据块的读写是在block控制 真实情况是:对同一数据块的是在文件系统中控制. 两个周来,对文件系统肃然起敬,文件系统是一个你要花至少一年,才只能读懂其50%的模块,甚至,要想领悟文件系统的精髓,你要读page-cache,要读block层,甚至要理解存储芯片的读/写/擦除特性,真是a long long

Linux操作系统结构、IO调度器在内核栈中的位置图

1.典型的Linux操作系统结构 2.IO调度器在内核栈中所处的位置 原文地址:https://blog.51cto.com/10627336/2356793

Linux 调度器发展简述

引言 进程调度是操作系统的核心功能.调度器只是是调度过程中的一部分,进程调度是非常复杂的过程,需要多个系统协同工作完成.本文所关注的仅为调度器,它的主要工作是在所有 RUNNING 进程中选择最合适的一个.作为一个通用操作系统,Linux 调度器将进程分为三类: 交互式进程 此类进程有大量的人机交互,因此进程不断地处于睡眠状态,等待用户输入.典型的应用比如编辑器 vi.此类进程对系统响应时间要求比较高,否则用户会感觉系统反应迟缓. 批处理进程 此类进程不需要人机交互,在后台运行,需要占用大量的系

块设备驱动之I/O调度层之调度器

通过generic_make_request提交请求给I/O调度层,这个函数最后调用到q->make_request_fn(q, bio),那么对于这个函数的调用就是I/O调度层的入口点,首先来看看这个make_request_fn在哪被赋于能量的 void blk_queue_make_request(struct request_queue *q, make_request_fn *mfn) { /* * set defaults */ q->nr_requests = BLKDEV_MA

Linux调度器 - 进程优先级

一.前言 本文主要描述的是进程优先级这个概念.从用户空间来看,进程优先级就是nice value和scheduling priority,对应到内核,有静态优先级.realtime优先级.归一化优先级和动态优先级等概念,我们希望能在第二章将这些相关的概念描述清楚.为了加深理解,在第三章我们给出了几个典型数据流过程的分析. 二.overview 1.蓝图 2.用户空间的视角 在用户空间,进程优先级有两种含义:nice value和scheduling priority.对于普通进程而言,进程优先级

KVM虚拟机IO处理过程(二) ----QEMU/KVM I/O 处理过程

接着KVM虚拟机IO处理过程中Guest Vm IO处理过程(http://blog.csdn.net/dashulu/article/details/16820281),本篇文章主要描述IO从guest vm跳转到kvm和qemu后的处理过程. 首先回顾一下kvm的启动过程(http://blog.csdn.net/dashulu/article/details/17074675).qemu通过调用kvm提供的一系列接口来启动kvm. qemu的入口为vl.c中的main函数,main函数通过

Linux noop io 调度算法分析

定义了一个elevator_noop的调度器类型: static struct elevator_type elevator_noop = { .ops = { .elevator_merge_req_fn = noop_merged_requests,//查询一个request,用于将bio并入 .elevator_dispatch_fn = noop_dispatch,//将noop调度器链表中最前面的请求取出,分派给块设备的请求队列 .elevator_add_req_fn = noop_