字体:  

关于SCSI I/O顺序

xiegang112 发表于: 2008-10-07 17:49 来源: DOIT博客

Hi,
在I/O多路径或者支持Tag queue时,不知道SCSI  I/O是否存在顺序问题?
比如在Linux中, I/O的SCSI命令通过queue_command函数加入SCSI控制器或适配器队列。此后,程序返回。该命令由SCSI控制器或适配器异步完成。完成后,通过中断返回命令执行结果。因此,如果对同一数据块的前后两次写,是否存在以下情况:
1.在多路径下,这两次写I/O被分发到不同的路径(即不同的SCSI适配器)。由此导致I/O失序的可能。
2.在单路径下,由于支持SCSI tag queue,在target端根据任务的tag属性对两次I/O任务reoder,导致失序。

个人认为,对于同步写,不会存在这个问题。因为文件系统和通过块层可以锁住写入的page cache和buffer head,直到SCSI中断返回命令执行结果。但是对于异步写呢?但是对于异步写,在上述两种情况下,似乎都有可能造成I/O失序。

谢谢

最新回复

冬瓜头 at 2008-10-07 18:23:06
我不是内行,只能猜测一下,楼主看看有没有道理。
底层io的乱序无关紧要,有两种情况,第二个io覆盖了第一个io,那么第一个io根本就没有必要写到磁盘,那么此时,控制器会丢弃发向同一段地址的sequence number小的命令。这种情况不会造成数据不一致,不管是从底层还是上层fs角度考虑。  第二种情况是两个io目标地址不同,此时就算乱序了,也不怕吧,虽说底层的乱序扰乱了上层逻辑,但是只要不崩溃,之前的io总会写进去的,就算突然崩溃了,那么也只能忍受不一致的风险,从fs角度甚至更高层角度比如数据库日志重放来恢复。并且,如果是大型设备,都有电池或者ups之类的保护,防止意外停电。
一家之言,请楼主指摘。
xiegang112 at 2008-10-07 21:26:57
对于楼上所说的两种情况,我有点不明白:
1.第一种情况所说的I/O覆盖问题,不知道楼上的意思是不是指的文件系统page cache的覆盖?如果是的话,我觉得只有在异步写时,才会出现这个问题。这个应该是用VFS的page cache来保证的。因为page cache和buffer head能保证某一文件系统的某一文件的某一具体块在缓存中只会有唯一份缓存。所以在异步写的时候,第二个I/O覆盖第一个I/O的内容是没有问题的。而在同步写时,则不存在覆盖问题。
2.在第二种情况中,楼上说的I/O目标地址不知道是指的什么?是指磁盘或者lun的逻辑块号吗?
冬瓜头 at 2008-10-07 21:39:44
1.针对楼上老兄说的,我也有点不明白。fs在进行flush动作的时候,对于新入写io,会暂挂,所以并不会覆盖到待flush的page吧?只在空闲时刻才会覆盖对应page。而我所指的全部都是针对磁盘的io覆盖。

2.是的,我指的就是底层磁盘或者lun。
rechardluo at 2008-10-08 23:51:12
要理解清楚,有2个方向要你去研究:
1. 有了应用和文件系统的缓冲,大大减少了对块设备的同一LBA地址频繁发送写请求的情况;同时,由于BIO这样的机制,把块设备的LBA地址和page关联,以及块缓冲机制,进一步减少甚至避免了这种情况的出现。
2. 即使不信出现了这种情况,SCSI底层的HBA卡驱动,会良好的处理queue_command调用,因为该函数最终使用的是底层HBA的驱动程序,它能够很好的支持SCSI TAG QUEUE,其中的TAG是保证顺序的关键,就像TCP/IP的保证顺序的机制那样。

至于你考虑的多路径情况,完全可以参考在TCP/IP的有多条通路的原理;
对于同步和异步机制,并不是你问题的关键。
冬瓜头 at 2008-10-09 00:56:29
rechardluo总是一语道破天机。
但是有个地方请赐教。对于存储网络,类比tcpip网络,后者如果ip包乱序了,接收端缓冲区内会有重排动作,而且必须重排,那么您是暗指对于scsi io指令也有这个重排动作了?也就是说最终到达磁盘边缘的io全部必须都是先来先入的么?
popgo at 2008-10-09 14:40:21
学习!
在Linux中, I/O的SCSI命令通过queue_command函数加入SCSI控制器或适配器队列