用户态驱动的两种方式-ixy学习
介绍
在Linux下有两种启用用户态驱动的子系统:一个是UIO,另一个是VFIO,ixy这两种都支持。 UIO通过虚拟文件系统sysfs下的内存映射文件来暴露所有必要的接口以完成用户态的驱动。这些基于文件的系统调用接口给了我们充足的权限来获取设备资源而不需要写任何内核代码。ixy要卸载到所给PCI设备的任何内核驱动以避免冲突,比如,当ixy正在运行时,NIC的任何驱动都不会被加载。
VFIO提供了更多的特性:IOMMU和中断,且这些只能由VFIO提供。然而,这些特性会带来额外的复杂度开销:它要求PCIe设备和通用的vfio-pci驱动绑定,然后它会在指定的文件上通过ioclt系统调用提供API。
第一个需要理解的是用户态驱动如何与设备打交道的,也就是理解驱动是如何写在用户态的。驱动能够与PCIe设备通信的两种途径:驱动能初始化到设备BAR的访问通道或设备能初始化DMA通道映射到任何的主存储区。BARs是由设备暴露配置信息给驱动,并给驱动来控制寄存器。这些寄存器可以通过内存映射IO方式(MMIO)获得,也可以通过依赖于设备的X86 独立IO获得,后者在PCIE设备上不推荐使用。
操作设备寄存器
MMIO将设备IO与内存空间映射起来,比如从这块内存区域读取或写入来完成向设备的接收或发送操作。UIO用虚拟文件系统暴露所有的BARs,这样有权限的程序就可以简单地把BARs映射到它自己的地址空间。VFIO提供了一个ioctl返回映射到这片区域的内存地址。设备通过这个接口暴露出它的配置寄存器,这样用户就可以用读写的方式来访问寄存器了。例如,ixgbe网卡设备通过BAR0地址空间暴露出所有的配置寄存器,状态寄存器和调试寄存器。这些映射的实现是在pci.c文件的pci_map_resource()函数和在libixy-vfio.c文件的vfio_map_region()函数里。不幸的是,VirtIO(在我们的实现与VirtualBox的兼容版本中)是基于PCI而不是在 PCIe ,其 BAR 是一个 IO 端口资源,必须使用古老的 IN 和 OUT x86 指令进行访问,这些指令需要IO 权限。
Linux能通过ioperm授予进程必要的权限,DPDK为他们的VirtIO驱动使用这样的通道。我们发现这种初始化工作太复杂,因为它需要解析 PCIe 配置空间或 procfs 和 sysfs 中的文本文件来初始化。Linux uio 通过sysfs的文件暴露出BAR空间,但与 MMIO 对应项不同,这些文件无法进行 mmap。这些文件能被打开,并通过通用的读写调用来访问,然后由内核转换为相应的 IO 端口命令。我们发现这样做更便于使用和理解,但由于所要求的系统调用而变得更慢。实现代码可见pci.c文件内的pci_open_resource()函数,device.h文件内的read/write_ioX()函数。
一个潜在的陷阱是读取和写入的确切大小很重要,例如,访问单个 32 位寄存器,用 2 个 16 位读取通常会失败,并且用一次大的读取来尝试读取多个小单位的寄存器通常是不支持的。确切的语义取决于设备,Intel的ixgbe NIC仅公开支持部分读取的 32 位寄存器(除了读取时清除寄存器),但不是部分写入。VirtIO 使用不同的寄存器大小,特别是,任何访问宽度应该是可以在我们正在使用的模式下工作的,事实上对齐且大小正确的访问可以可靠地工作的。
用户态的DMA
DMA是由PCIe设备初始化的,并允许它读写任意的物理地址。这被用来在驱动和网卡之间传输数据包和存放在DMA上的数据包描述符(指向数据包)。DMA需要在设备的PCI配置空间里显示地使能,我们在pci.c的enable_dma()函数里实现了这个使能,同样在libixy-vfio.c的vfio_enable_dma()函数为VFIO同样实现了这个使能。
DMA的内存分配在UIO和VFIO之间是不同的。
UIO的DMA内存分配
用于DMA的内存空间必须是常驻于物理内存区域。mlock(2)能用来禁用swapping。然后,这仅能保障页被内存保持支持,并不保障分配的内存物理地址保持始终一样。Linux的页迁移机制能在任何时间改变用户空间分配的任何页的物理地址,比如,来实现传输巨页和NUMA选项等。Linux 没有实现显式分配的大页(x86 上的 2 MiB 或1 GiB 页面)的页面迁移。因而ixy使用巨页来简单地分配连续的大的物理内存。在用户空间分配巨页被所有的用户态驱动采用,但他们经常是作为性能提升来使用,尽管可靠的DMA内存分配也至关重要。因为用户态驱动也需要能讲它的虚拟地址转换为物理地址,这可以通过procfs文件/proc/self/pagemap来实现,这种传输逻辑在memory.c文件的virt_to_phys()函数里实现。
VFIO的DMA内存分配
之前的DMA内存分配机制是X86平台上的Linux的特殊机制,而不是可移植的。VFIO的特点是,它是可移植的,他内部调用dma_alloc_coherent()函数来分配内存,就像其他的内核态驱动那样做。这个系统调用简化了所有的复杂细节并在我们的驱动里以libixy-vfio.c文件的vfio_map_dma()函数来实现。它需要一个IOMMU,并配置必要的映射来为物理设备使用虚拟地址。
DMA和缓存一致性
这两种实现都要求我们的CPU架构满足缓存一致的DMA访问。老式的CPU可能不支持这个功能,并要求在DMA数据能被设备读到之前把缓存上的数据同步到内存。现代的CPU没有这个问题。实际上,为实现高速数据IO的一个主流技术是DMA访问并不真的到内存,而是到新CPU架构的缓存上。
用户态的中断
VFIO的特点是对中断全支持,具体设置函数为libixy-vfio.c文件内的vfio_setup_interrupt()函数,为VFIO使能一个指定的中断,并将它与一个eventfd的文件描述符绑定。ixgbe.c里的enbale_msiz_interrupt()函数为设备上的一个队列配置中断。中断被映射到一个文件描述符上,被系统调用如epoll检测,一般进入睡眠状态,直到中断发生,请见libixy-vfio.c文件内的vfio_epoll_wait()函数。
相关文章:
用户态驱动的两种方式-ixy学习
介绍在Linux下有两种启用用户态驱动的子系统:一个是UIO,另一个是VFIO,ixy这两种都支持。 UIO通过虚拟文件系统sysfs下的内存映射文件来暴露所有必要的接口以完成用户态的驱动。这些基于文件的系统调用接口给了我们充足的权限来获取设备资源而…...
机器学习 | 线性回归(单变量)
前文回顾:机器学习概述📚线性回归概念我们要使用一个数据集,数据集包含俄勒冈州波特兰市的住房价格。在这里,我要根据不同房屋尺寸所售出的价格,画出我的数据集。比方说,如果你朋友的房子是 1250 平方尺大小…...
C++基础知识【3】控制语句
目录 前言 一、条件语句 1.1、if 语句 1.2、if-else 语句 1.3、switch 语句 二、循环语句 2.1、while 循环 2.2、do-while 循环 2.3、for 循环 三、跳转语句 3.1、break语句 3.2、continue语句 3.3、goto语句 四、一些新特性 4.1、if 语句和 switch 语句…...
ImportError: Can not find the shared library: libhdfs3.so解决方案
大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。喜欢通过博客创作的方式对所学的知识进行总结与归纳,不仅形成深入且独到的理…...
Qt插件开发总结5--主界面嵌入插件UI
文章目录一、前言二、效果展示三、嵌入插件UI1、插件接口文件添加UI指针2、插件子项目工程建立UI类3、插件类中创建UI类、使UI指针指向创建的UI类4、插件元信息中添加widget键值对,指示插件UI嵌入主界面中的位置5、主界面中预留接入点tabWidget6、插件管理器中元数据…...
一些关于linux process 和python process的记录
python mulprocess 主要用来生成另一个进程并运行 def func(i):print(helloworld)from multiprocessing import Process p Process(targetfunc,args(i, )) p.start()如果想要调用shell命令,可以采用os.popen 或者是 subprocess.run 但是前者只能执行命令并获取输…...
卡尔曼滤波——一种基于滤波的时序状态估计方法
文章目录1. Kalman滤波及其应用2. Kalman原理公式推导:Step 1:模型建立Step 2:开始Kalman滤波Step 3:迭代滤波本文是对 How a Kalman filter works, in pictures一文学习笔记,主要是提炼核心知识,方便作者快…...
什么是X6CrMo17-1
X6CrMo17-1X6CrMo17-1是在430的基礎上加入了鉬,提高鋼的耐點蝕、耐縫隙腐蝕性及強度等,比430鋼抗鹽溶液體性強。一、X6CrMo17-1對應牌號:1、國標GB-T標準:數字牌號:S11790、新牌號:10Cr17Mo、舊牌號&#x…...
软件测试是个人就能做?恕我直言,你可能是个“纯粹”的测试工具人,BUG收集器
作为过来人的我和你说说软件测试的真正情况。 前言 一个软件做出来,最不能少的是谁?毫无疑问是开发,开发是最了解软件运作的那个人,早期就有不少一人撸网站或者APP的例子,相当于一个人同时是产品、研发、测试、运维等…...
递归算法(recursion algorithm)
递归算法 什么是递归算法 在过程或者函数里调用自身的算法; 递归算法(recursion algorithm),通过重复将问题分解为同类的子问题而解决问题的方法, Java中函数可以通过调用自身来进行递归,大多数编程语句…...
VScode下 ESP32 下载程序
ESP32-S3 下载方式可以通过UART0 下载,USB 下载,JTAG下载,还可以使用WIFI进行远程OTA升级程序。插件底栏按键介绍:①选择串口端口号,如COM3; ②选择芯片型号; ③工程idf设置,相当于menuconfig; …...
黑苹果日历
黑果日历 2023/2/27 总结 安装流程 制作启动U盘2017年,本来去当兵,结果近视👓没验上。父母我还想学什么?我想到了黑客操作电脑的画面,感觉特别酷。 2017年有了第一台自己的笔记本,是小米游戏本࿰…...
python+pytest接口自动化框架(5)-requests发送post请求
在HTTP协议中,与get请求把请求参数直接放在url中不同,post请求的请求数据需通过消息主体(request body)中传递。且协议中并没有规定post请求的请求数据必须使用什么样的编码方式,所以其请求数据可以有不同的编码方式,服务端通过请…...
Linux 进程:进程控制
目录一、进程创建1.fork2.vfork二、进程终止三、进程等待四、进程替换1.理解程序替换2.子进程在程序替换中的作用Linux的进程控制分为四部分: 进程创建进程终止进程等待进程替换 一、进程创建 常见的创建进程的函数有两个: pid_t fork(void)pid_t vf…...
过滤器的创建和执行顺序
过滤器的创建和执行顺序 8.1.1创建并配置过滤器 P143 重点是如何创建并配置(xml) 1.创建 public class EncodingFilter implements Filter {Overridepublic void init(FilterConfig filterConfig) throws ServletException {}Overridepublic void doFil…...
JDK1.8 ConcurrentHashMap
数据结构锁sizeCtlconcurrencyLevelForwardingNode、ReservationNode扩容get、put、removehashmap:线程不安全 hashtable:通过synchronized保证线程安全但效率低。强一致性 ConcurrentHashMap:弱一致性 数据结构 ConcurrentHashMap为node数…...
参考 Promise/A+ 规范和测试用例手写 Promise
前言 这可能是手写promise较清晰的文章之一。 由浅至深逐步分析了原生测试用例,以及相关Promise/A规范。阅读上推荐以疑问章节为切入重点,对比Promise/A规范与ECMAScript规范的内在区别与联系,确定怎样构建异步任务和创建promise实例。然后开…...
yolov5数据集制作
yolov5 数据集的格式 每个图像的标注信息存储在一个独立的txt文件中每个txt文件的名称应该与其对应的图像名称相同,只是文件扩展名不同。例如: 对于名为“image1.jpg”的图像,其标注信息应存储在名为“image1.txt”的txt文件中。 在每个txt文件中,每一行表示一个对象的标注…...
主板EC程序烧写异常致无法点亮修复经验
主板型号:Gigabyte AB350M-Gaming3 官网上明确写着支持R5 5500,但按照如下步骤实践下来实际是不支持的 升级biosF31到F40版本的注意事项: 步骤: 1 使用Q-Flash先将bios升级到f31版本;2 然后下载提示中的ECFW Update To…...
【Java爬取赛事网站】命令行输出(仅供学习)
Java爬取赛事网站 Java爬取赛事网站Java爬取赛事网站参与社区的问题回答Gitcode项目地址PSP表格解题思路描述问题接口设计和实现过程编写中的测试关键代码展示性能改进单元测试异常处理心路历程与收获参与社区的问题回答 问题回答这个作业属于哪个课程软件工程-23年春季学期这…...
C++实现分布式网络通信框架RPC(3)--rpc调用端
目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中,我们已经大致实现了rpc服务端的各项功能代…...
day52 ResNet18 CBAM
在深度学习的旅程中,我们不断探索如何提升模型的性能。今天,我将分享我在 ResNet18 模型中插入 CBAM(Convolutional Block Attention Module)模块,并采用分阶段微调策略的实践过程。通过这个过程,我不仅提升…...
mongodb源码分析session执行handleRequest命令find过程
mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程,并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令,把数据流转换成Message,状态转变流程是:State::Created 》 St…...
[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...
(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...
select、poll、epoll 与 Reactor 模式
在高并发网络编程领域,高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表,以及基于它们实现的 Reactor 模式,为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。 一、I…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)
上一章用到了V2 的概念,其实 Fiori当中还有 V4,咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务),代理中间件(ui5-middleware-simpleproxy)-CSDN博客…...
【分享】推荐一些办公小工具
1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由:大部分的转换软件需要收费,要么功能不齐全,而开会员又用不了几次浪费钱,借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...
【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论
路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中(图1): mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...
