用户态驱动的两种方式-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年春季学期这…...
【kafka】Golang实现分布式Masscan任务调度系统
要求: 输出两个程序,一个命令行程序(命令行参数用flag)和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽,然后将消息推送到kafka里面。 服务端程序: 从kafka消费者接收…...
centos 7 部署awstats 网站访问检测
一、基础环境准备(两种安装方式都要做) bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats࿰…...
Python实现prophet 理论及参数优化
文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候,写过一篇简单实现,后期随着对该模型的深入研究,本次记录涉及到prophet 的公式以及参数调优,从公式可以更直观…...
JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...
IT供电系统绝缘监测及故障定位解决方案
随着新能源的快速发展,光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域,IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选,但在长期运行中,例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...
ABAP设计模式之---“简单设计原则(Simple Design)”
“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...
Python ROS2【机器人中间件框架】 简介
销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...
R语言速释制剂QBD解决方案之三
本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...
排序算法总结(C++)
目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指:同样大小的样本 **(同样大小的数据)**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...
云原生安全实战:API网关Kong的鉴权与限流详解
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关(API Gateway) API网关是微服务架构中的核心组件,负责统一管理所有API的流量入口。它像一座…...
