BLOCK层代码分析(0)存储IO框架介绍

BLOCK层代码分析(0)存储IO框架介绍

BLOCK层代码分析(1)数据的组织BIO

BLOCK层代码分析(2)BLOCK MQ基本原理

BLOCK层代码分析(3)IO下发概述

BLOCK层代码分析(4)IO下发之BIO的切分和合并

BLOCK层代码分析(5)IO下发之BIO bounce过程

BLOCK层代码分析(6)IO下发之SGL聚散列表

BLOCK层代码分析(7)IO下发之request的分配和获取

BLOCK层代码分析(8)IO下发之plug/unplug机制

BLOCK层代码分析(9)IO下发之IO下发

BLOCK层代码分析(10)IO下发之IO下发函数总结

BLOCK层代码分析(11)IO完成

         更新了BLOCK层代码分析(1)(2)后,觉得有必要对存储IO框架层次做介绍,因此增加了本小节。

1. 存储IO框架

        存储IO内核框架如下图所示:

BLOCK层代码分析(0)存储IO框架介绍_第1张图片

        以上列出几种驱动的存储软件框架,包含NVME驱动/SAS驱动/SATA驱动。IO依次经过系统调用层、文件系统层、BLOCK层、SCSI层、LIBSAS/LIBATA层以及LLDD。但并不是所有的这些层都经过,比如对于NVME驱动,对接BLOCK层,并不会经过SCSI层等。并且上图只是简单的描述,每层又可以细分,这里不做详细描述。

        对于每一层,作用描述如下:

  1. 系统调用:处理系统调用;
  2. 文件系统层:建立硬盘和内存数据的映射,存储和组织数据,以便查询和访问;
  3. BLOCK层:下发/完成文件系统传输过来的数据,同时可能做合并/切分和排序(IO调度层);
  4. SCSI层:下发/完成数据,对SCSI硬盘进行识别;
  5. LIBSAS/LIBATA层:下发/完成数据,识别设备拓扑;
  6. LLDD: 下发/完成数据,对特定的硬件进行适配;

        上面只是对每一层的功能做最简单的介绍,后面有机会会分别对每层做详细的描述。

2. IO发送和完成过程简述

        可以看出从BLOCK到LLDD层,每层都需要下发和完成IO。对于每一层,在下发时都会注册相应的完成函数,当完成时就会调用对应的完成函数一层层向上传递(这里描述的是正常完成过程,除了正常完成过程还存在异常完成即超时机制(如果在N秒内,IO没有完成,就会进入超时流程处理IO完成))。

BLOCK层代码分析(0)存储IO框架介绍_第2张图片

        如上图为hisi_sas驱动的发送完成过程的简化(实际在下发过程中还有SAS盘和SATA盘不同路径下发和完成,这里暂时忽略),block层暂时不介绍,后续章节会重点介绍block层。

        SCSI层使用函数scsi_queue_rq()下发IO时注册对应的完成函数scsi_done()。LIBSAS层使用函数sas_queuecommand()下发IO时注册对应的完成函数sas_scsi_task_done()。底层驱动使用hisi_sas_queue_command()下发IO时注册对应的完成函数slot_complete_vx_hw()。

        当硬件完成数据的处理后,一般会产生中断通知软件开始完成过程。软件依次会调用slot_complete_vx_hw()-> sas_scsi_task_done() -> scsi_done()完成IO,此过程一般会放在中断下半部执行。当然并不是所有的完成都是通过中断通知软件的,也可以软件进行轮询硬件是否完成(当前IO_URING支持poll)。

3. IO在各层的表示

        IO在每层使用不同的结构体来表示,下图hisi_sas驱动所涉及的各层IO的结构体表示,以及相互之间的关系。

BLOCK层代码分析(0)存储IO框架介绍_第3张图片

        BLOCK层处理之前提到的bio外,主要使用request。SCSI层使用scsi command。LIBATA层使用ata_queued_cmd。LIBSAS使用sas_task。hisi_sas驱动使用hisi_sas_slot。

NOTE:本节以及后面章节的分析都是基于当前最新内核(比如目前为5.16-rc1),内核变动可能会有小的差异。另相应可能涉及的代码在内核中的位置为:

BLOCK层代码:block/

SCSI层代码: drivers/scsi/

LIBSAS层代码:drivers/scsi/libsas/

hisi_sas代码:drivers/scsi/hisi_sas/

你可能感兴趣的:(BLOCK_SCSI,BLOCK,存储IO)