浅析Linux SCSI子系统:IO路径

news2024/11/14 2:58:18

文章目录

    • 概述
    • scsi_cmd:SCSI命令
      • result字段
      • proto_op字段
      • proto_type字段
    • SCSI命令下发
      • scsi_request_fn
        • scsi_dev_queue_ready
        • scsi_host_queue_ready
    • SCSI命令响应
      • 命令请求完成的软中断处理
    • 相关参考

概述

SCSI子系统向上与块层对接,由块层提交的对块设备的IO请求,会由SCSI子系统转换成SCSI协议的标准命令,然后调用Scsi_Host结构的queuecommand回调下发到低层驱动执行;低层驱动会将SCSI命令和数据发送给真实的设备,并在请求完成后,调用scsi_cmd结构中的scsi_done回调,将请求响应信息返回给SCSI中层,SCSI中层完成请求响应的解析后,将结果返回给块层。

scsi_cmd:SCSI命令

struct scsi_cmnd {
	struct scsi_request req;
	struct scsi_device *device;
	struct list_head list;     // 用于链入到关联SCSI设备的SCSI命令链表中
	struct list_head eh_entry;     // 用于链入到SCSI Host的错误恢复链表中
	struct delayed_work abort_work;

	struct rcu_head rcu;

	int eh_eflags;
	unsigned long serial_number;

	unsigned long jiffies_at_alloc;

	int retries;   // SCSI命令已重试的次数
	int allowed;   // SCSI命令允许重试的次数

	unsigned char prot_op;     // DIF操作类型
	unsigned char prot_type;   // DIF保护类型
	unsigned char prot_flags;

	unsigned short cmd_len;
	enum dma_data_direction sc_data_direction;

	unsigned char *cmnd;

	struct scsi_data_buffer sdb;  // SCSI命令的数据缓冲区
	struct scsi_data_buffer *prot_sdb;     // SCSI命令的保护数据缓冲区

	unsigned underflow;	
	unsigned transfersize;

	struct request *request;

	unsigned char *sense_buffer;   // 存放sense信息的缓冲区
				
	void (*scsi_done) (struct scsi_cmnd *);    // 底层驱动完成IO请求后,调用scsi_done将结果返回给SCSI

	unsigned char *host_scribble;	

	int result;    // 存放低层驱动返回的IO状态信息
	int flags;
};

result字段

result携带了驱动或SCSI中层在完成SCSI命令处理后返回的一些结果信息,一共包含4个字段。
在这里插入图片描述

  • driver_byte:由SCSI中层进行设置;
  • host_byte:存放底层驱动返回的状态信息;
  • msg_byte:存放主机适配自身的一些信息;
  • status_byte:存放目标设备返回的状态信息,由SCSI协议定义。

proto_op字段

proto_op字段描述了SCSI命令的DIF操作类型,由scsi_prot_operations枚举类型定义:

enum scsi_prot_operations {
	SCSI_PROT_NORMAL = 0,

	SCSI_PROT_READ_INSERT,
	SCSI_PROT_WRITE_STRIP,
	
	SCSI_PROT_READ_STRIP,
	SCSI_PROT_WRITE_INSERT,

	SCSI_PROT_READ_PASS,
	SCSI_PROT_WRITE_PASS,
}

proto_type字段

proto_type字段描述了SCSI命令支持的DIF保护类型,由t10_dif_type枚举类型定义:

enum t10_dif_type {
	T10_PI_TYPE0_PROTECTION = 0x0,
	T10_PI_TYPE1_PROTECTION = 0x1,
	T10_PI_TYPE2_PROTECTION = 0x2,
	T10_PI_TYPE3_PROTECTION = 0x3,
}

SCSI命令下发

scsi_request_fn

在这里插入图片描述

scsi_dev_queue_ready

scsi_dev_queue_ready检查SCSI设备运行IO情况,确认是否允许下发新的IO。函数检查的维度有两个:

  • 检查SCSI设备的IO请求队列是否已满。若满,则不允许下发新的IO;
  • 检查SCSI设备是否设置了device_blocked。若设置,则需要等待device_blocked计数减为0时,才允许下发IO。

在这里插入图片描述

scsi_host_queue_ready

scsi_host_queue_ready检查主机适配器能否下发新的IO,检查逻辑与scsi_dev_queue_ready类似。
在这里插入图片描述

SCSI命令响应

SCSI中层在将SCSI命令请求下发给驱动时,会设置scsi_cmnd结构中的done回调函数,驱动在完成IO请求时,通过调用done回调,将IO响应信息返回给中层。
在这里插入图片描述

命令请求完成的软中断处理

IO请求完成的处理流程前半部分在硬中断上下文处理,后半部分的工作回切换到软中断进行处理,SCSI提供的软中断处理入口是scsi_softirq_done函数。scsi_softirq_done的工作如下:

  1. 调用scsi_decide_disposition解析scsi_cmd的返回信息,包括驱动返回状态、sense数据等,确定如何进一步处理scsi_cmd;
  2. 根据scsi_decide_disposition返回的动作,处理scsi_cmnd,分为几种情况:
    • SUCCESS:IO成功完成,将结果返回上层;
    • NEEDS_RETRY/ADD_TO_MLQUEUE:IO重试。把scsi_cmnd重新加入到块设备请求队列处理;
    • 默认情况:IO错误处理。调用scsi_en_scmd_add把scsi_cmnd加入到错误处理队列中,等待错误恢复。

scsi_softirq_done流程示意如下:
在这里插入图片描述

相关参考

  • 《存储技术原理分析:基于Linux 2.6内核源代码分析》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/936052.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

桌面图标不显示

问题 桌面图标不显示 解决办法 鼠标 右击->选择-查看->显示桌面图标

学习创建第一个 React 项目

目标 本篇的目标是配置好基础的环境并创建出第一个 React 项目。 由于之前没接触过相关的知识,所以还需要了解其依赖的一些概念。 步骤主要参考First React app using create-react-app | VS code | npx | npm - YouTube 0. 简单了解相关概念 JavaScript 一种语…

基于未来搜索算法优化的BP神经网络(预测应用) - 附代码

基于未来搜索算法优化的BP神经网络(预测应用) - 附代码 文章目录 基于未来搜索算法优化的BP神经网络(预测应用) - 附代码1.数据介绍2.未来搜索优化BP神经网络2.1 BP神经网络参数设置2.2 未来搜索算法应用 4.测试结果:5…

MLCC产生噪音的原因及解决方案

1.内部构造及工作原理 MLCC是Multilayer Ceramic Capacitor多层片式陶瓷电容 决定电容容值大小的主要参数: 真空介电率 相对介电常数K:和MLCC使用材料有关的常数 有效面积S 介电层厚度d 堆叠层数N 所以面积越大堆叠层数越多的MLCC容值越高 2.MLCC产生啸…

shell数据结构

less可以创建一个文件分页 3次a,是不是连续的 重定向输出>会清空文件内容 cp一份新的,或者新建一个 journalctl 查看启动日志 将前面id传给 xargs 通过journalctl -b 查找对应的日志, pi好像的地址 ??&#xff1f…

用Cmake build OpenCV后,在VS中查看OpenCV源码的方法(环境VS2022+openCV4.8.0) Part III

用Cmake build OpenCV后,在VS中查看OpenCV源码的方法(环境VS2022openCV4.8.0) Part III 用Cmake build OpenCV后,在VS中查看OpenCV源码的方法(环境VS2022openCV4.8.0) Part I_松下J27的博客-CSDN博客 用Cmake build OpenCV后&…

C++设计模式_01_设计模式简介(多态带来的便利;软件设计的目标:复用)

文章目录 本栏简介1. 什么是设计模式2. GOF 设计模式3. 从面向对象谈起4. 深入理解面向对象5. 软件设计固有的复杂性5.1 软件设计复杂性的根本原因5.2 如何解决复杂性 ? 6. 结构化 VS. 面向对象6.1 同一需求的分解写法6.1.1 Shape1.h6.1.2 MainForm1.cpp 6.2 同一需求的抽象的…

时序预测 | MATLAB实现基于TSO-XGBoost金枪鱼算法优化XGBoost的时间序列预测(多指标评价)

时序预测 | MATLAB实现基于TSO-XGBoost金枪鱼算法优化XGBoost的时间序列预测(多指标评价) 目录 时序预测 | MATLAB实现基于TSO-XGBoost金枪鱼算法优化XGBoost的时间序列预测(多指标评价)预测效果基本介绍程序设计参考资料 预测效果 基本介绍 Matlab实现基于TSO-XGBoost金枪鱼算…

Android学习之路(11) ActionBar与ToolBar的使用

自android5.0开始,AppCompatActivity代替ActionBarActivity,而且ToolBar也代替了ActionBar,下面就是ActionBar和ToolBar的使用 ActionBar 1、截图 2、使用 2.1、AppCompatActivity和其对应的Theme AppCompatActivity使用的是v7的ActionBa…

数据分析基础(1)——超实用‼️Excel 常用函数和实用技巧

学习教程:☑️ 懒人Excel - Excel 函数公式、操作技巧、数据分析、图表模板、VBA、数据透视表教程 目录 一、Excel知识体系✨ 二、Excel 常用函数💡 三、Excel 技巧 🤔 补充: 1、自学数据分析学习路线 2、数据查询网站 一、…

服务器安全-增加clamav杀毒

1.安装epel源 yum install epel-release 2.安装 clamav yum install clamav clamav-server clamav-data clamav-update clamav-filesystem clamav-scanner-systemd clamav-devel clamav-lib clamav-server-systemd pcre* gcc zlib zlib-devel libssl-devel libssl openssl …

代码随想录第32天|122.买卖股票的最佳时机 II,55. 跳跃游戏 ,45. 跳跃游戏 II

122.买卖股票的最佳时机 II 122. 买卖股票的最佳时机 II 思路比较简单 class Solution {public int maxProfit(int[] prices) {int res0,sum0;for(int i0;i<prices.length-1;i){if(prices[i1]-prices[i]>0){sumprices[i1]-prices[i];}ressum>res?sum:res;}return …

比较重合点的排斥能

( A, B )---3*30*2---( 1, 0 )( 0, 1 ) 让网络的输入只有3个节点&#xff0c;AB训练集各由5张二值化的图片组成&#xff0c;让A中有2个1&#xff0c;B中有1个1&#xff0c;有一个点重合&#xff0c;排列组合&#xff0c;统计迭代次数并排序。 得到数据 构造平均列A 构造平均列…

JDK介绍

JDK,JRE和JVM之间的关系 JVM是运行环境&#xff0c;JRE是含运行环境和相关的类库&#xff0c;跟node环境是一个意思 JDK目录介绍 目录名称说明bin该路径下存放了JDK的各种工具命令。javac和java就放在这个目录。conf该路径下存放了JDK的相关配置文件include该路径下存放了一些…

DevOps系列文章 之 Python基础

流程控制和循环 if语句 它由三部分组成: 关键字本身, 用于判断结果真假的条件表达式, 以及当表达式为真或者非零时执行的代码块 可支持else和elif;条件表达式并不需要用括号括起来 1、标准if 条件语句的语法如下&#xff1a; if expression:expr_true_suite 如果表达式的值…

Java获取环境变量和运行时环境信息和自定义配置信息

System.getenv() 获取系统环境变量 public static void main1() {Map<String, String> envMap System.getenv();envMap.entrySet().forEach(x-> System.out.println(x.getKey() "" x.getValue())); } System.getenv() 获取的是操作系统环境变量列表&…

nginx-获取客户端IP地址

上有服务器与客户端中间是有nginx代理服务器的&#xff0c;上游服务器如何获取客户端真实ip地址&#xff1f; nginx代理服务器设置X-Forwarded-For的header参数&#xff0c;代理服务器通过remote_addr获取客户端ip地址&#xff0c;将ip地址写入nginx代理服务器的X-Forwarded-Fo…

激活函数总结(二十一):激活函数补充(APL、Inverse Cubic)

激活函数总结&#xff08;二十一&#xff09;&#xff1a;激活函数补充 1 引言2 激活函数2.1 Adaptive piecewise linear&#xff08;APL&#xff09;激活函数2.2 Inverse Cubic激活函数 3. 总结 1 引言 在前面的文章中已经介绍了介绍了一系列激活函数 (Sigmoid、Tanh、ReLU、…

JS-this知识点、面试题

一、this指向什么 1.简介 2.规则一&#xff1a;默认绑定 3.规则二&#xff1a;隐式绑定 4.规则四&#xff1a;new绑定 5.规则三&#xff1a;显式绑定 call、apply、bind 6.内置函数的绑定 7.规则优先级 8.this规则之外--es6剪头函数 9.ES6剪头函数this 二、This面试题 面试题…

哔哩哔哩 B站 bilibili 视频视频音效调节 清澈人声

视频音效调节方式&#xff1a;直接视频播放内容界面内鼠标右键点击视频音效调节 注意&#xff1a;需要使用的是谷歌浏览器&#xff0c;我的火狐浏览器试了不行&#xff0c;都没选项&#xff0c;火狐的出来的界面是这样的&#xff1a; 目录 具体操作如下&#xff1a; 1、谷歌…