三种不同实现ublk的零拷贝I/O的方法

news2025/1/12 20:48:49

用户态块设备ublk,就是提供/dev/ublkbX这样的标准块设备给业务,业务读写这个块的实际IO处理由编写的用户态的代码决定。这就好比使用FUSE,所有对挂载于FUSE的目录的读写都是编写的IO handler来处理一样。使用用户态块设备,可以方便地向上层业务以块设备/dev/ublkbX的形式提供您的自定义存储系统(如ceph)的服务,上层业务只需要对块设备执行标准的读写操作即可。

ublk是社区提出的基于最新的、流行的io_uring passthrough机制实现的用户态块设备,目前已经在block社区引起广泛讨论,并进入到了内核主线。社区提供的代码包括内核态的ublk_drv.ko内核模块和用户态的ublksrv。

ublk子系统可以创建使用 io_uring 与内核通信的用户空间块驱动程序。使用这种方式实现的驱动程序在性能方面表现出一定的潜力,但存在一个瓶颈:内核和用户空间驱动程序之间存在数据复制。因此,实现 ublk 零拷贝 I/O 显得尤为重要。最近在内核邮件列表中提出三种不同的实现,介绍如何实现这一点。

1、使用 BPF

 

内核中几乎没有什么问题是无法通过将一些 BPF 混入其中来解决的,零拷贝 ublk I/O 似乎也不例外。 Xiaogang Wang 的这个补丁集添加了一个新的类型(BPF_PROG_TYPE_UBLK),它可以由 ublk 驱动程序加载,并随后注册到一个或多个特定的 ublk 设备。在这种情况下,内核生成的 I/O 请求将传递给该程序,而不是发送给用户空间驱动程序执行。有一个名为 bpf_ublk_queue_sqe() 的新 BPF 辅助函数(不是 kfunc,原因不明),它允许 BPF 程序向环中添加请求,可用于对满足原始块请求的 I/O 操作进行排队。

完全在内核中处理这些请求有一些优势,首先是能够消除与用户空间守护进程的切换。不过,最大的价值可能来自于这样一个事实,即 BPF 程序可以访问内核提供的缓冲区,并可以直接将它们用于满足每个请求所需的任何 I/O,从而消除该数据的副本。块驱动程序可以移动相当多的数据,因此极大的避免复制。目前这个补丁(像其他补丁一样)缺乏基准测试结果来显示它所带来的性能改进。

Patch:https://lwn.net/ml/linux-block/20230222132534.114574-1-xiaoguang.wang@linux.alibaba.com/

2、 Fused CMD

最初 ublk 补丁的作者 Ming Lei 有一种截然不同的方法。与 ublk 本身一样,这项工作的文档很少且难以阅读,因此此描述是逆向工程工作的结果,在某些方面很可能是错误的。

io_uring 环中的操作通常彼此完全分开。有一种方法可以将它们链接起来,这样一个操作必须在下一个操作被分派之前完成,否则每个操作都是不同的。 这个补丁集通过添加“FUSED”的概念,提供了一个相当紧密的链接——两个操作绑定在一起并且可以在它们之间共享资源。

当用户空间 ublk 驱动程序运行时,它将通过环接收来自内核的命令,其中包含诸如“从偏移量 O 处的设备 D 读取 N 个块”之类的指令。驱动程序将可以选择将该操作转换为FUSED命令,该命令将放回环中以在内核中执行。FUSED命令是两个绑定在一起的 io_uring 命令;它们必须作为一个整体提交。 “master”命令(Patch中的术语)是 IORING_OP_FUSED_CMD 类型;它包含足够的信息供 ublk 子系统将命令连接到发送到用户空间驱动程序的请求。相反,“slave”命令执行满足该请求所需的实际 I/O。

与 BPF 解决方案一样,这里的关键是 slave 命令可以访问与 master 关联的缓冲区;在这种情况下,slave 命令可以访问与原始块 I/O 请求关联的内核空间缓冲区。并且,这允许在不将数据复制到用户空间驱动程序或从用户空间驱动程序复制数据的情况下执行 I/O。一旦slave命令完成,用户空间驱动程序可以以通常的方式向内核发出原始块 I/O 请求的完成信号。

Fused命令功能是一种特殊用途,它在任何一般情况下都不起作用。接收Fused命令的子系统必须对它有特殊的支持,具体来说,它必须能够找到slave命令的内核空间缓冲区,并在slave执行之前调用新函数 io_fused_cmd_provide_kbuf() 建立连接,这是对 io_uring 子系统的相当大的更改,并且还不完全清楚任何其他子系统是否能够利用它。

Patch:https://lwn.net/ml/linux-block/20230314125727.1731233-1-ming.lei@redhat.com/

3、 使用 splice()

在 Lei 的补丁集(第2个版本 ) 发布后的讨论中,Pavel Begunkov 观察到“它看起来有点复杂且带有侵入性”。他认为也许可以重用 splice() 系统调用的机制。 io_uring“注册缓冲区”功能将用于促进零复制操作。此后不久,他发布了初步的概念验证实现,它展示了这种方法如何运作但并不完整。

Lei 对这种方法有很多疑问,主要集中在缓冲区管理的工作原理上。如果 I/O 需要在给定缓冲区上执行多次,则 splice() 方法的工作效果尚不清楚——例如,在写入镜像块设备时。问题不断涌现,Begunkov 尚未(截至撰写本文时)发布补丁的完整版本。 splice() 方法似乎不会走得更远,尽管意外总是会发生。

与此同时,Wang 表示,Fused命令方法似乎是“支持 ublk 零拷贝的正确方向”。

正如最初的 ublk 文章中指出的那样,阻碍操作系统设计微内核方法的关键实际问题之一是组件之间的通信成本。 ublk 已经设法大大降低了该成本,但如果可以消除在内核和用户空间之间复制数据的成本,还有更多的收获。因此,开发人员很可能会继续解决这个问题,直到找到某种可行的解决方案。

Patch:https://lwn.net/ml/linux-block/20230307141520.793891-1-ming.lei@redhat.com/

参考:

SPDK: ublk Target

ublk: add io_uring based userspace block driver [LWN.net]

Zero-copy I/O for ublk, three different ways [LWN.net]

Commits · ming1/ubdsrv · GitHub

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

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

相关文章

产品经理必读|用户研究方法总结①

众所周知,理解用户需求,识别用户痛点,是产品或功能成型之前绕不开的过程。而要获取到用户真实的需求和痛点,唯一的方法就是做用户调研。而用研的方法都有哪些呢?今天我就来给大家分享一下行业中常见的用研方法。 用研的…

ESP32设备驱动-VL53L0X飞行时间(激光测距)传感器驱动

VL53L0X飞行时间(激光测距)传感器驱动 文章目录 VL53L0X飞行时间(激光测距)传感器驱动1、VL53L0X介绍2、硬件准备3、软件准备4、驱动实现1、VL53L0X介绍 VL53L0X 是新一代飞行时间 (ToF) 激光测距模块,采用当今市场上最小的封装,与传统技术不同,无论目标反射率如何,都能提…

项目中开发固定表头和首列的表格【付代码】

前言 前段时间做移动端的项目,项目中需要一个固定表头和首列的表格,但由于是移动端的,组件库里没有类似的,于是,就去网上找看有没有类似的,结果越找越气,10个文章9个抄,抄也行&#…

安全狗入选网络安全行业全景图(第十版)多个细分领域

4月7日,安全牛正式发布第十版网络安全行业全景图。 作为国内云原生安全领导厂商,安全狗也凭借综合的安全能力脱颖而出入选全景图多个领域。 据悉,全景图报告调研基于企业自主申报,并对申报企业收录有严格要求,安全牛…

Zookeeper集群+Kafka集群

目录 一、Zookeeper Zookeeper 概述 定义 工作机制 Zookeeper特点 Zookeeper数据结构 ZooKeeper应用场景 统一命名服务 统一配置管理 统一集群管理 服务器动态上下线 软负载均衡 第一次启动选举机制 非第一次启动选举机制 二、部署Zookeeper集群 1、实验准备 2…

第60章 用户增、修、删的前端实现

1 \src\components\Users\AddUser.vue <template> <!-- elmentUI 子页面的渲染显示注意事项说明&#xff1a; 子页面的渲染显示必须的使用“<el-dialog></el-dialog>标签及其所包含的子标签&#xff0c;否则子页面将不会被渲染显示出来。” --> <…

Python学习笔记--判断语句

&#xff08;一&#xff09; 布尔类型和比较运算符 1. 布尔类型&#xff1a;判断结果 True&#xff1a;表示真&#xff08;是、肯定&#xff09; False&#xff1a;表示假&#xff08;否、否定&#xff09; """ 演示布尔类型的定义 以及比较运算符的应用 "…

BCM系统组成及控制原理

1 输入控制 由于负载能力、抗干扰能力等客观情况。许多信号量无法直接施加至MCU之上&#xff0c;须有适当的输入电路(Input circuit)将信号进行隔离、调理&#xff0c;方可安全可靠地传递给MCU。 下面以开关信号和脉冲信号2种来分述。 1)开关信号的输入。 即将系统与电源正…

高频算法:Leetcode53 最大子数组和

今天讲的是Leetcode第53题&#xff0c;最大子数组和 首先观察题目&#xff0c;题目需要我们找出具有最大和的连续子数组&#xff0c;直接拿题目中的示例来做一个演示&#xff0c;找一找什么规律下的连续子数组才能得到最大的和 先从-2开始&#xff0c;-2 1 -1 此时我们的和…

【Python】Python读写.xlsx文件(基本操作、空值补全等)

【Python】Python读写.xlsx文件&#xff08;Pandas&#xff09; 文章目录【Python】Python读写.xlsx文件&#xff08;Pandas&#xff09;1. 介绍2. Pandas读写xlsx文件2.1 基本操作2.1.1 实现任务2.1.2 代码2.1.3 结果2.2 进阶操作2.2.1 写操作2.2.2 查看数据表的基本信息2.2.2…

集中一个主题,密集学习几个月,突飞猛进

集中一个主题&#xff0c;密集学习几个月大长进 诺贝尔奖获得者西蒙发现 密集学习了几个月品牌营销的知识 长进明显 原来是有科学规律的 趣讲大白话&#xff1a;大力出奇迹 【趣讲信息科技132期】 **************************** 西蒙学习法&#xff1a;“对于一个有一定基础的人…

KANO模型-产品需求调研利器

最近要做一个项目&#xff0c;需要调研客户的真实需求&#xff0c;我们有一些可提供的功能&#xff0c;需要通过问卷调研出客户对功能的优先级需求。但问卷调研的结果能反映客户的真实需求和痛点吗&#xff1f;如何给这些需求排优先级&#xff0c;以及所占的权重&#xff1f;如…

【python】只需一段代码,剪辑一个视频——Moviepy详解

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录前言一、准备二、视频剪辑三、视频拼接四、逐帧变化四、导出GIF总结前言 知道吗&#xff0c;用moviepy一行代码就能够快速剪辑视频中某个区间的片段&#xff1a; cl…

mac m1系统安装安卓手机模拟器

背景&#xff1a;本人是一名开发人员&#xff0c;本地小程序上的需要地图导航到手机上&#xff0c;所以找到一个mac&#xff08;m1&#xff09;安装安卓模拟器的方案&#xff0c;这里记录分享一下。 废话不多说直接上步骤&#xff0c;很详细跟着步骤走就能完成&#xff01;&am…

【MySQL】delete和truncate的用法和区别

一、delete和truncate的用法 有如下数据表t_student 关键字delete和truncate都用来清除表中数据&#xff0c;语法结构为&#xff1a; delete from t_student;truncate table t_student; 两条SQL操作后的结果一样&#xff1a;删除了表中数据&#xff0c;但是会保留表的结构&a…

OpenAI Embedding:快速实现聊天机器人(一)

theme: orange 本文正在参加「金石计划」 上文 OpenAI Embedding&#xff1a;基于人工智能的搜索新篇章 有讲到Embedding的基础概念以及OpenAI Embedding 的能力和应用场景&#xff0c;这篇文章讲讲如何手把手构建聊天机器人。 聊天机器人介绍 聊天机器人作为一项重要的企业级服…

Qt 数据库SQL

Qt 数据库SQL用户接口层SQL接口层驱动层创建连接数据库查询两个数据库示例用户接口层、SQL接口层和驱动层是数据库系统中的三个重要组成部分&#xff0c;它们分别负责不同的功能。 用户接口层 用户接口层 用户接口层是用户与数据库系统交互的界面。它提供了一些简单易用的工具…

HDSF 简介

目录 一、HDFS 的设计特点是 二、什么零拷贝 2.1 传统情况&#xff1a; 2.2 零拷贝技术&#xff1a; 三、什么是DMA 四、HDFS 的关键元素 五、HDFS 运行原理 六、HDFS 数据合并原理 七、HDFS 写的原理 八、HDFS 读的原理 九、分块存储 十、 安全模式 十一、 MapRedu…

如何使用微服务架构?使用过程需要注意什么?

一、使用微服务架构的规范 1.1 服务拆分 微服务的服务拆分是根据业务领域和业务功能来划分的&#xff0c;目的是将复杂的单体应用程序分解为小型、自治的服务&#xff0c;每个服务都专注于处理一个特定的业务领域或功能。 以下是微服务拆分的一些常见策略&#xff1a; 领域…

JavaEE——volatile、wait、notify三个关键字的解释

文章目录一、volatile和内存可见性1.解释内存可见性问题2. volatile 的使用与相关问题二、wait 和 notify1.wait 方法2.notify() 方法3. 关于 notifyAll() 方法4. wait 和 sleep 之间的简单比较一、volatile和内存可见性 前面的文章&#xff0c;我们已经提及到了内存可见性问题…