概述

前面讲到,iscsi initiator实现过程采用了多级的异步模式,通过异步模式使IO操作阶段能够批量处理。这种异步机制的存在主要为了提升系统的吞吐量。从设计的角度,考虑采用异步操作机制的任务往往至少满足以下几个条件:

  • 并发能明显提升系统的IO吞吐。作为iscsi服务,其瓶颈点往往在磁盘上。但是多块磁盘可以并行进行读写,因此,IO的并发可以充分利用多个磁盘的带宽。并发可以避免由于某个IO操作,而使其它本来可以不需要等待的IO被hang住了。

  • 各任务之间顺序无关。由于并发会使得顺序传递到系统的任务可能被打乱顺序执行。因此,这项必须保证。就iscsi服务而言,我们iscsi task任务的视角。由于前面已经保证了同一conn任务是顺序执行的,那么不同conn上面的任务必然顺序无关,即可以乱序执行。

  • 任务在执行过程中需要等待某个事件的达成。所谓异步,其概念与同步相对,表示任务被执行过程中,不能立该得到结果,需要等待某个状态或者事件发生。在等待的过程中,并发处理其他任务。也就是,单纯的异步操作不会产生价值。只有并发异步才会增大吐吞(此概念可以共同探讨)

采用异步IO的目的是充分利用各类资源(CPU、内存、磁盘IO),从而提升系统的吞吐,降低IO平均时间。如下图所示。如图所示:

假设4个任务,顺序的使用网络、CPU、硬盘三种硬件资源,使用的时间别为T1、T2、T3,为了分析方便,我们假设他们 $ T1=T2=T3=T $ ,当4个任务为串行时,其平均时间为

avg(4)=4∗3T4=3Tavg(4)=\frac {4*3T}{4}=3T avg(4)=44∗3T​=3T

我们可以看到,任务平均执行时间为:

avg(4)=6T4=1.5Tavg(4) = \frac{6T}{4}=1.5T avg(4)=46T​=1.5T

通常情况下,当调度合理时,即缩小了任务总体执行时间,也缩小了每个任务的响应时间。基于上述分析,在IO操作的流程中,Linux系统为充分利用所有的资源,通常采用异步操作的方式。

与上述案例不同,实际执行过程中,每个任务使用不同资源的时间并不相等,在程序设计中,我们只要让所有的资源同时在工作,即可使系统吞吐最大化,进而再解决某类资源不足成为瓶颈的问题,具体操作时,可以将一个任务根据使用资源的不同分成不同的阶段,CPU调度各个资源的使用,一旦CPU将任务发送到某类资源之后,继续执行下一个任务。

针对上述IO密集型场景,微软提出实现了IOCP(I/O Completion Port)模型。我们在此不讨论具体是Linux最先实现还是微软最先提出,总体上机制差不多。基本遵循以下流程:

1、CPU处理IO任务发现需要处理IO时,将其任务请求转到某个设备

2、CPU将任务置为等待IO处理完成状态

3、CPU继续处理其它任务

4、当设备处理完IO时,采用某种通知机制,如中断通知CPU

5、CPU接到IO处理完成事件后,继续处理IO中的其它逻辑

iscsi处理基本遵循上述流程。我们进行详细解读。在前面我提到解释了一个上层IO请求,如何封装成bio,放到请求中,进而作为一个scsi任务提交给iscsi层。本章主要分析iscsi处理完成之后的完成处理流程。

iscsi数据传输

iscsi传输层

iscsi设备与本地的设备不同,其scsi命令是通过网络传递到target端进行解析并执行,通常情况下,这些协议层次的处理都是由CPU完成的。如果使用专用的HBA卡,其处理流程有所简化,不在此讨论之列。特别提一句的是,在内核里面,为提供多种类型的iscsi传输层。假如为一个HBA卡写一个驱动,可以调用iscsi_register_transport注册自己的iscsi传输层处理函数。此函数进行一系列初始化后,并将其加到iscsi_transports中。

当一个会话被创建时,系统根据输出参数判断具体的传输层并将其初始化到session结构体的transport成员中,而在为会话创建链接时,再次将其指定到链接结构体的相应成员中。

对于通用网卡情景下,iscsi的transport被定义为iscsi_sw_tcp_transport。其各项内容具体说明如表所示:

成员 说明
owner THIS MODULE 指定该传递层是由谁来实现的
name “tcp” 指定传层的可读名称
create_session iscsi_sw_tcp_session_create 该回调在创建会话时被调用。
destroy_session iscsi_sw_tcp_session_destroy 该回调在删除会话时被调用
create_conn iscsi_sw_tcp_conn_create 该回调创建连接时被调用
bind_conn iscsi_sw_tcp_conn_bind 该回调处理连接绑定相关的操作,系统将传输前的初始化放在此回调中
destroy_conn iscsi_sw_tcp_conn_destroy 当连接被删除时调用
attr_is_visible iscsi_sw_tcp_attr_is_visible 用于设定sysfs文件相关属于访问权限
set_param iscsi_sw_tcp_conn_set_param 用于设定iscsi相关参数
get_conn_param iscsi_sw_tcp_conn_get_param 用于获取iscsi相关参数
start_conn iscsi_conn_start 该回调在连接过程中被调用
stop_conn iscsi_sw_tcp_conn_stop 该函数在连接终止时被调用
get_host_param iscsi_sw_tcp_host_get_param 用于获取与主机相关的参数
set_host_param iscsi_host_set_param 用于设定与主机关的参数
send_pdu iscsi_conn_send_pdu 用于将PDU发送给target
get_stats iscsi_sw_tcp_conn_get_stats 用于获取统计信息
init_task iscsi_tcp_task_init 在iscsi任务初化时被调用,主要用于SCSI_READ和SCSI_WRITE相关的任务的初始化工作
xmit_task iscsi_tcp_task_xmit 当传输任时被调用
cleanup_task iscsi_tcp_cleanup_task 清理任务时被调用
xmit_pdu iscsi_sw_tcp_pdu_xmit 传输PDU给target
init_pdu iscsi_sw_tcp_pdu_init 初始化PDU
alloc_pdu iscsi_sw_tcp_pdu_alloc 申请PDU内容
session_recovery_timedout iscsi_session_recovery_timeout 会话恢复相关操作

数据接收

iscsi连接是在用户空间执行的。用户空间接收连接请求时,通过netlink调用传递消息给内核模块,进而在内核进行绑定处理。处理完成之后,内核将接管连接所使用的socket的事件处理和信息传递。在open-iscsi的设计,系统将target发现、登录、参数商定等的处理均放在用户空间进行,而将数据传输阶段的处理放在内核层进行。此类设计的笔者认为主要是在性能和设计原则方面的权衡。一方面,内核空间不宜处理过多的非设核心处理;另一方面,iscsi将LUN呈现为一个虚拟的块设备,需要在内核空间实现。如若,将所有的网络处理都放在用户空间,势必需要进行不必要的内核空间到用户空间的通信。

内核接管操作主要由函数iscsi_sw_tcp_conn_bind完成,主要工作为:

  • 获取sock对象

在用户空间,创建socket时,返回的文件描述符是fd,且在进程范围内有效。而内核空间socket操作是使用struct socket结构体的实例。因此,内核接管socket首先做的是将通过fd找到对应的struct socket结构体。

  • 进行必要的赋值

iscsi实现中,在内核里维护了iscsi操作所必须的结构,比如iscsi通用的session、conn等结构,同时也维护了针对软件实现iscsi所必须的数据结构iscsi_sw_tcp_conn

  • 设置socket参数

在此步骤中,主要对socket接收前一些参数进行设置

  1. 将socket设置为可重用

  2. 设置发送超时时间为12s

  3. 设置内存申请标志GFP_ATOMIC|__GFP_MEMALLOC

4.调用sk_set_memalloc

  • 修改socket的回调函数,接管socket数据传递

  • 初始化iscsi接收数据状态机,以便进行处理

那么,数据如何传递给iscsi模块,并进行处理呢。关健点就是上述流程中对回调函数的设置,实现中,此操作是由iscsi_sw_tcp_conn_set_callbacks完成的,主要设定了sk_data_readysk_state_changesk_write_space三个回调。当有数据到达该连接时,sk_data_ready就会被激发。

sk_data_ready是在软中断上下文中被执行的。当数据到达网卡后,会给CPU产生一个硬中断。我们知道中断处理,通常设计中断处理分为上半部和下半部。上半部在中断上下文环境,为避免影响后续中断的产生,需要快速处理,而把更大量的工作放在下半部完成 [^1] 。下半部实现可以采用软中断或work_queue等模式。Linux网络设计中使用软中断的模式,即TCP/IP协议栈的处理在软中断中进行,直到将数据通过socket交付给用户层。在iscsi实现中,由于我们重设了sk_data_ready回调函数,数据不会交给用户层,而是直接在软中断上下文中处理iscsi数据接收的一些逻辑。iscsi中sk_data_ready函数设置为iscsi_sw_tcp_data_ready。当数据到达时,此函数直接在中断上下文中被执行。

[^1] https://blog.packagecloud.io/eng/2016/06/22/monitoring-tuning-linux-networking-stack-receiving-data/#irqs

iscsi:IO操作流程(五)——IO完成处理相关推荐

  1. iscsi:IO操作流程(四)

    系统构建SCSI指令后,将调用scsi_host的queucommand操作,将指令下移到LLD设备层进行处理. scsi_host在iscsi协议中的角色 scsi_host在系统中启动承上启下的作 ...

  2. iscsi:IO操作流程(一)

    从应用的视角,iscsi展现为一个块设备,即一块硬盘.在Linux操作系统中可以通过fdisk -l看到这块磁盘.iscsi协议所涉及的一系列的组件经过层层虚拟化,在多个层次上其操作与本地硬盘无异.这 ...

  3. 高级IO--1 ---(五种典型IO,阻塞IO,非阻塞IO,信号驱动IO,异步IO, IO多路转接)

    高级IO: 五种典型IO: 阻塞IO/非阻塞IO/信号驱动IO/异步IO/IO多路转接 IO多路转接模型:select/poll/epoll 五种典型IO 阻塞IO IO操作的流程:等待IO操作条件具 ...

  4. IO流 (五) ----- 对象数据的序列化与反序列化

    相关文章: <IO流 (一) ----- 基本概念和File类> <IO流 (二) ----- 文件流> <IO流 (三) ----- 字符流和字符缓冲流> < ...

  5. 程序员成长之旅——同步IO和异步IO(五种IO模型)

    程序员成长之旅--同步IO和异步IO(五种IO模型) 同步和异步 同步 异步 消息通知 场景比喻 阻塞和非阻塞 阻塞 非阻塞 事例 同步IO 阻塞IO 非阻塞IO 信号驱动IO 多路转接IO 异步IO ...

  6. 2. 彤哥说netty系列之IO的五种模型

    你好,我是彤哥,本篇是netty系列的第二篇. 欢迎来我的公从号彤哥读源码系统地学习源码&架构的知识. 简介 本文将介绍linux中的五种IO模型,同时也会介绍阻塞/非阻塞与同步/异步的区别. ...

  7. 18 操作系统第五章 设备管理 IO设备的基本概念和分类 IO控制器 IO控制方式 IO软件层次结构 IO核心子系统 假脱机技术 设备的分配与回收 缓冲区管理

    文章目录 1 IO设备的基本概念和分类 1.1 什么是I/O设备 1.2 I/O设备分类 2 IO控制器 2.1 I/O设备组成 2.2 I/O控制器功能 2.3 I/O控制器的组成 2.4 寄存器编 ...

  8. Java IO(五)——字符流进阶及BufferedWriter、BufferedReader

    一.字符流和字节流的区别 拿一下上一篇文章的例子: 复制代码 复制代码 1 package com.demo.io; 2 3 import java.io.File; 4 import java.io ...

  9. python 异步io_python之同步IO和异步IO

    linux操作系统基础知识 用户空间和内核空间 操作系统的核心是内核,独立于普通的应用程序,可以访问受保护的内存空间,也有访问底层硬件设备的所有权限.为了保证用户进程不能直接操作内核保证内核的安全,操 ...

  10. 5种网络IO模型:阻塞IO、非阻塞IO、异步IO、多路复用IO、信号驱动IO

    目录 前言 阻塞IO(blocking IO) 非阻塞IO(non-blocking IO) 多路复用IO(IO multiplexing) 异步IO(Asynchronous I/O) 模型间的区别 ...

最新文章

  1. 什么是事务的传播_这么漂亮的Spring事务管理详解,你不来看看?
  2. 十六、Redis三种特殊类型之三Bitmap
  3. 025_jdbc-mysql-Statement的sql注入问题
  4. 初步了解Telerik for WPF 控件
  5. 2022年全球及中国软包电池铝塑膜行业规模价值与竞争格局展望报告
  6. [Android开发] 启程
  7. easyui中获取getEditor为空情况
  8. Docker自动补全容器名
  9. 这项技术:华为、BAT要力捧!程序员:我彻底慌了... ​
  10. percona zabbix mysql_zabbix采用percona监控mysql主从
  11. php提交字符串中有加号(+)时会后台得到空格的问题
  12. 2017年美国大学生数学建模竞赛F题优秀论文解读
  13. python断言_Python断言
  14. 处理0x0000007E和0x0000000A蓝屏
  15. Win10有哪些方便快捷的操作小技巧?
  16. 卷积系列:Deconvolution(反卷积)/Transpose Convolution(转置卷积)/Fractional convolution
  17. 论文阅读笔记《Optimal Image-Based Guidance of Mobile Manipulators Using Direct Visual Servoing》
  18. Windows 去除桌面烦人的小箭头
  19. 微信小程序 —— 瀑布流简单写法(css3属性加wx:if判断轻松实现)
  20. c语言怎么将两个整数变量值交换,C语言如何利用异或进行两个值的交换详解

热门文章

  1. delphi tpanel 内凹效果_别墅装修公司前十名|别墅装修效果图|现代精致简约
  2. python爬虫之协程理解爬取照片的简单版
  3. energy in transition课文翻译_思迪软件科技 招聘 字幕翻译(远程兼职)
  4. python模拟按键_Python实现windows下模拟按键和鼠标点击的方法
  5. Python查找包含指定字符串的所有Office文档
  6. Python+django网页设计入门(14):使用中间件对抗爬虫
  7. 详解Python中的位运算符规则、原理与用法
  8. 排序算法 c++(思想+code)
  9. android中的多渠道打包,Android 多渠道打包简析
  10. 【caffe学习】caffe第二个比较典型的识别例子CIFAR_10的运行详解