二、预习下
由于我们在上一篇文章中,描述了比较高层的I/O stack的结构,接下来我们来讲讲底层的结构。
这一节,可能绝大多数的人在实际的工作中,并不是涉及到开发,但也是linux I/O中非常重要的。
那我们就一一列举,来讲讲它们都是什么。
1、Block Layer,在很多年前,我在看SCSI子系统的时候,我那时候就不是太确立Block Layer到底是什么,因为这其中要理解block device、BIO和一系列的request_fn。所以理解block layer应该不是什么简单的事情,因为它是一个很抽象的概念,更不能一言能概括,但是我们能够从图上看出一点,就是经过block layer的多个bio,最终都变成了有序的request,那么我们应该能看出来它可以排序合并bio,并且能够make request from bios。
2、I/O scheduler和blkmq,因为磁盘访问数据寻道和旋转延迟所导致出磁盘访问的一个特性,linux为磁盘设计了特殊的map bios to requests的方式,就叫做I/O scheduler,从这个function的结构来看,一个request从init到build之间的时差是用来map bios的,这个时差对于I/O scheduler是不可控的,linux i/o stack为此提供了一个专属的方法,被叫做blk_plug和blk_unplug,即从上层来派发bios的时候,上层是知道某些bios是需要并且可以做合并和排序的,那么就需要上层来plug这个bios seq,由unplug来触发build request,这个过程通常需要block device之间或和LIO/VFS配合实现。
blkmq:是linux为那些不需要做I/O scheduler的设备所设计的新的队列模型,具有高并发的特性,适用于新型的nvme ssd等具有高hardware queue depth的设备,由于几乎不再依赖blk_plug等增加latency的处理流程,这种I/O队列模型的性能会非常高。
3、scsi mid layer:scsi子系统一直是支持存储协议的big子系统,就连其内部也分为high layer、mid layer和low layer。这三层的特点就好像殖民地时期的殖民地结构,其中high layer扮演者那些殖民者,他们对当地并不熟悉,需要在当地建立傀儡政权,来保证其统治地位,也就是scsi子系统中的high layer用来实现的scsi disk,scsi tape,scsi cdrom,这种scsi高级特性的设备描述,他们是不管当地是什么情况,用同一的方式来发布scsi cmd。为了保证scsi high layer的命令得以执行,那么scsi subsystem中的傀儡政权,也就是scsi结构网络层,scsi mid layer构建了一个等级森严的拓扑方式:host:channel:target:lun,而且必须要所有的low layer都必须遵循这种拓扑方式,虽然说这种方式很残忍,甚至来说在一个host被注册的时候,它直接能和low layer通信的方式也显得很露骨(比如:slave_configure等),但是还有事一批的喜欢当slave的公司做出了无数的scsi low layer的产品,这其中比较著名的是:mpt3sas(lsi),pm8001(pmc),qla2xxx(qlogic)等吧,这些商品一般就是大家比较熟知的sas hba,raid card,fc hba等,所以没有谄媚就没有暴力,他们记住做硬件产品一定要抱个和scsi这样粗的大腿,做出来就不愁卖。但是这些年scsi也没有那么好过了,因为这充满等级森严的scsi mid layer的存储I/O,必须要求所有的scsi deivce去dispatch cmd都必须是一个接口到low layer,导致了单个scsi host没办法发挥新型介质nand flash的所有性能,让新的协议nvme大行其道,好比共产主义给殖民地同志们带来的希望,大家纷纷要突破scsi host的牢笼,那么scsi的命运如何,未来到底会不会被nvme所取代,我们拭目以待。
原文地址:http://blog.51cto.com/12580077/2310283