原创 Linux2.6.28中Scsi Disk驱动IO回调路径分析

2009-4-12 02:13 5670 10 13 分类: 软件与OS

       Scsi Disk设备驱动通过Scsi middle level层向scsi host提交请求,scsi disk driver是一个块设备驱动,其调用块设备层的unplug_fn函数处理scsi disk的请求队列。在处理scsi disk请求队列过程中会调用scsi middle level层注册的scsi_request_fn函数实现具体的操作。Scsi_request_fn函数会从io调度队列中获取一个请求,然后将该请求转换成scsi command,最后直接调用scsi_dispatch_cmd函数将scsi命令提交给scsi hostScsi hostscsi middle level层的接口是queue_command函数,每个scsi host驱动都会向scsi middle level层注册具体的queue_command方法。由于Queue_command函数在不可睡眠的上下文中执行,所以其不能处理复杂的操作,通常的操作是将接收到的scsi命令放置到scsi host维护的处理队列中。如果一个真是的scsi host,而不是一个虚拟的host时,那么在scsi host层可以将scsi command通过DMA的方式传输到scsi disk。上述过程完成了一个io请求的提交过程,对于诸如磁盘这样的设备,在这一过程中需要考虑到存储介质的特性以及应用访问模式的特性,所以需要做一些IO调度的策略,使得scsi磁盘的读写更加满足存储介质的特性。当然也可以在scsi disk的上层实现更加高级的IO管理策略。IO请求的提交可以理解为整个IO过程的前半部,那么后半部就是IO完成的回调过程,下文分析LinuxIO回调路径的具体实现。


<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 


       当一个IO事件完成之后,scsi disk会采用中断的方式通知scsi host驱动。当scsi host的中断事件发生之后,CPU会执行host的中断服务程序,通常实际的scsi host都会以PCI设备的形式存在,考虑到中断共享问题,在中断服务程序中首先需要进行中断事件的判断,然后根据scsi host的状态寄存器进行具体中断任务的处理。对于读写IO请求,当数据DMAscsi disk之后会产生DMA结束中断信号,在DMA过程中可以采用聚散DMAscatter-gather DMA)的技术,因此这一过程不会涉及到数据的内存拷贝,也就是说在读写IO过程中,数据一直处于bioPage页中(写数据过程中会直接将Page页中的数据DMA到磁盘,读数据过程中直接将磁盘中的数据DMAbioPage中,这样的处理机制效率较高)。当host确定完成请求之后,会调用scsi middle level的回调函数,该回调函数就是著名的scsi_doneScsi_donequeue_command的过程中被提交到scsi host层。在scsi_done函数中直接调用了blk_complete_request函数,该函数通过raise_softirq_irqoff(BLOCK_SOFTIRQ)触发了scsi的软中断。到目前为止,上述过程都在scsi host的中断上半部中执行。中断上半部运行时间不能过长,否则会导致中断事件的丢失。触发软中断之后,中断上半部就可以退出了。在退出上半部之后,CPU将会交给已经触发的scsi软中断服务程序,此时可以看到软中断的服务程序仍然运行在中断上下文,并不是一个可以调度的context


 


       软中断的执行函数是blk_done_softirq,由于是scsi command引发的中断事件,因此会调用事先注册到请求队列上的scsi_softirq_done函数,完成具体的scsi软中断下半部事件处理。在该函数中会进行一些scsi command执行的正确性判断,如果命令执行错误,那么可以采用重试的方法进行命令的requeue处理,当重试到一定程度之后会将执行错误的scsi命令交给scsi错误处理内核守护进程,进行最后的判决;如果执行成功,那么调用scsi_finish_command函数结束掉scsi命令。在scsi_finish_command函数中调用scsi_io_completion函数结束块级的io request,具体会调用scsi_end_request函数,然后调用blk_end_request函数,最后调到blk_end_io函数。在blk_end_io函数中会结束掉request上的所有bio,结束bio的过程可以调用bio_endio函数。Request中的所有bio都结束之后释放request资源。至此,一个bio所在的requestscsi disk处理完毕之后,通过中断上半部和下半部已经全部处理完毕。这里需要注意的是,IO的所有回调过程都是在中断上下文中处理的,所以在编写IO的回调函数时需要注意睡眠问题,需要考虑内存分配可能带来的睡眠,信号量的使用会导致睡眠,从而使系统崩溃。


 


       通过上述分析,scsi disk的正常IO回调路径涉及的函数描述如下:scsi_doneàblk_done_softirqàscsi_softirq_doneàscsi_finish_commandàscsi_io_completionàscsi_end_requestàblk_end_ioàbio_endio


 


       最近LinuxScsi middle level方面变化比较大,上述的分析基于较新的Linux-<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />2.6.28版本,和前面的2.6.18版本相比IO回调流程也发生了一定变化。

文章评论3条评论)

登录后参与讨论

用户411565 2009-6-25 11:59

scsi host就是scsi控制器,queue command将scsi命令提交给scsi host,每个scsi host可以接收多个命令,所以维护了一个请求命令队列,scsi host会处理这个请求队列,通过DMA的方式读写数据。

用户193005 2009-6-24 12:00

”queuecommand应该就是把命令写入disk“ 严格说应该是写入scsi controller。

用户193005 2009-6-24 11:36

我的理解queuecommand应该就是把命令写入disk,然后配置,启动dma就可以了。(如果是用CPU负责读写数据,而非dma。那读时具体的数据操作是在中断处理程序进行中,而写数据得在这里完成)。 这里博主说的queuecommand将接收到的scsi命令放置到scsi host维护的处理队列中。 是什么情况。 谢谢
相关推荐阅读
用户411565 2012-12-18 12:58
我的存储之道博客
大家好,最近一直在做存储方面的工作,所以我在51CTO上专门开辟了一个空间讨论存储相关的问题,喜欢存储的朋友可以可以访问我的存储博客: 存储之道 (http://alanwu.blog.51cto...
用户411565 2012-04-06 21:39
SAS Cable可以有多长?
SAS接口是高端硬盘的主流接口,是存储系统的理想选择。我们知道高速信号的传输距离和传输线相关的,那么SAS作为外部通信接口,其Cable线具体可以有多长呢? 我在网上找到上图所示的眼图测...
用户411565 2012-04-06 21:38
对TRIM SCSI命令的一些分析
前一段时间做了一些对SSD方面进行优化的工作,SSD最大的问题在于长时间使用之后,IO性能会急剧下降。其主要问题在于为了防止“写放大”问题的产生,SSD的firmware采用了类似于log方式的算...
用户411565 2012-04-06 21:35
惊叹!我们的跨洋网络
  每次地质自然灾害的时候,总会伴随着网络的问题,这是由于我们的越洋光纤网络出了故障,受到自然力的破坏而导致断裂。越洋光纤,听起来的确是件非常不可思议的事情,工程量非常的巨大,但正是如此伟大的...
用户411565 2012-04-06 21:33
科学仪器网络模型
科学仪器概述     科学仪器发展趋势 科学是从测量开始的,科学仪器是信息技术的源头,是信息产业的重要组成部分,是现代科学与工业的基石。科学仪器产业的发展关系到国家科学研究实力、生...
用户411565 2012-04-06 21:16
谈谈RAID产品与技术
说起RAID,学计算机的同学马上会说RAID技术简单啊,就是将数据条带化,然后计算一些冗余数据,一并写入磁盘。通过RAID技术一方面提高系统的IO性能;另一方面提高系统的可靠性。单纯从RAID的原...
我要评论
3
10
关闭 站长推荐上一条 /2 下一条