DMA全称Direct Memory Access,CPU访问外设内存很慢,如果由CPU给外设大量搬运数据,CPU会大量空转等待搬运数据完成,所以发明出DMA engine,把搬运数据的任务由DMA engine来完成,CPU只要告诉DMA engine从什么地方开始搬运多大数据就行了,然后就可能干其它有意义的工作,DMA engine搬运完数据就打断CPU说搬运完了,接着搬运哪的数据手动多大。
这是一篇指导驱动工程师如何使用DMA API的文档,为了方便理解,文档中给出了伪代码的例程。另外一篇文档dma-api.txt给出了相关API的简明描述,有兴趣也可以看看那一篇,这两份文档在DMA API的描述方面是一致的。
Leo Hou,目前就职于IC行业某硬件数据加速独角兽企业,从事虚拟化方向,聚焦于基于QEMU/KVM的IO虚拟化和系统虚拟化,主要负责虚拟化相关方案和团队建设。
DPU卸载/加速, 或AI云中, 大量使用的RDMA技术中, 比较重要的操作当属于DMA, 不管是e810, e1000, mlx5等网卡驱动, 或是刚玉项目(Corundum: https://github.com/corundum/corundum)中, 都大量使用DMA, 今天咱们跟随大佬一起深入分析动态DMA映射原理及API
NIC 在接收到数据包之后,首先需要将数据同步到内核中,这中间的桥梁是 rx ring buffer。它是由 NIC 和驱动程序共享的一片区域,事实上,rx ring buffer 存储的并不是实际的 packet 数据,而是一个描述符,这个描述符指向了它真正的存储地址,具体流程如下:
区别与直接调度片上资源/使用物理平台,使用虚拟化技术对于资源的调度会更加灵活和高效,而且可以达到硬隔离的目的;
如上图所示,smmu 的作用和mmu 类似,mmu作用是替cpu翻译页表将进程的虚拟地址转换成cpu可以识别的物理地址。同理,smmu的作用就是替设备将dma请求的地址,翻译成设备真正能用的物理地址,但是当smmu bypass的时候,设备也可以直接使用物理地址来进行dma;
使用过虚拟机pci passthrough或者做过DPDK/SPDK开发的同学一定很熟悉下面的配置:
DMA:((Direct Memory Access),直接内存存取, 是一种外部设备不通过CPU而直接与系统内存交换数据的接口技术 。外设可以通过DMA,将数据批量传输到内存,然后再发送一个中断通知CPU取,其传输过程并不经过CPU, 减轻了CPU的负担。但由于DMA不能像CPU一样通过MMU操作虚拟地址,所以DMA需要连续的物理地址。
在上期,大家了解了虚拟机中的纯虚拟化设备(Emulation)和半虚拟化(Para-virtualiazation)是如何工作的。
DMA(Direct Memory Access) 即直接存储器访问, DMA 传输方式无需 CPU 直接控制传输,通过硬件为 RAM 、I/O 设备开辟一条直接传送数据的通路,能使 CPU 的效率大
这是向MIPS架构移植软件的问题系列之第二篇。上一篇《MIPS架构深入理解8-向MIPS架构移植软件之大小端问题》中,我们讨论了大小端对于移植代码的影响。那么本文,我们再从Cache理解一下对于移植代码的影响,尤指底层代码或操作系统代码。
在前两期,我们讲述了X姐利用缓存一致性原理,晋升P9并且设法避免了被老板毕业的故事,链接在此:
我们知道外设访问内存需要通过DMA进行数据搬移,关于cpu, cache, device, dma, memory的关系可以通过下图说明:
DMA remapping就是在DMA的过程中IOMMU进行了一次转换,MMU把CPU的虚拟地址(va)转换成物理地址(pa),IOMMU的作用就是把DMA的虚拟地址(iova)转换成物理地址(pa),MMU转换时用到了pagetable,IOMMU转换也要用到io pagetable,两者都是软件负责创建pagetable,硬件负责转换。IOMMU的作用就是限制DMA可操作的物理内存范围,当一个PCI设备passthrough给虚拟机后,PCI设备DMA的目的地址是虚拟机指定的,必须要有IOMMU限制这个PCI设备只能操作虚拟机用到的物理内存。
在上期,我们遗留了另一个问题:在ARM Cortex-A 体系架构下,应当如何让让虚拟机的OS能够访问到PCI-E设备的配置空间,IO BAR空间和DMA缓冲区?
上一节内容的学习我们知道了CPU是如何访问内存的,CPU拿到内存后就可以向其它人(kernel的其它模块、内核线程、用户空间进程、等等)提供服务,主要包括: 以虚拟地址(VA)的形式,为应用程序提供远大于物理内存的虚拟地址空间(Virtual Address Space) 每个进程都有独立的虚拟地址空间,不会相互影响,进而可提供非常好的内存保护(memory protection) 提供内存映射(Memory Mapping)机制,以便把物理内存、I/O空间、Kernel Image、文件等对象映射到相应进
上一节内容的学习我们知道了CPU是如何访问内存的,CPU拿到内存后就可以向其它人(kernel的其它模块、内核线程、用户空间进程、等等)提供服务,主要包括:
虚拟化是一种广泛使用的技术,支撑了几乎所有现代云计算和企业基础设施。开发人员基于虚拟化功能可以在单台机器上运行多个操作系统,从而完成软件测试而不会存在破坏主计算环境的风险。虚拟化为芯片和基础设施带来了许多特性,包括良好的隔离性、不同资源的可及性、同一资源的工作负载平衡、隔离保护等。
传统数据中心中硬件服务器上运行linux,linux用硬件网卡收发包,硬件网卡有broadcom的有mellanox的有intel的等各式各样的,硬件网卡连接到硬件交换机上,硬件交换机有H3C的有cisco的,交换机进行包转发实现服务器之间互通。在云计算环境下,对计算资源进行了切分,服务器上运行的是一个个虚拟机,虚拟机也要有网卡实现互连互通,但虚拟机的网卡不是物理的,是虚拟的网卡,虚拟的网卡连接到虚拟的交换机上,虚拟的交换机对同一个服务器上的虚拟机之间流量进行转发,如果虚拟交换机再连接到服务器的硬件网卡,那么虚拟机就可以和服务器外面通信了。
我们先从计算机组成原理的层面介绍DMA,再简单介绍Linux网络子系统的DMA机制是如何的实现的。
这里的consistent实际上是coherent的概念,不能保证consistent,也就是说需要memory barrier来保证memory order。
应用程序和驱动程序之间传递数据时,可以通过read、write函数进行。这涉及在用户态buffer和内核态buffer之间传数据,如下图所示:
There are only two hard things in Computer Science: cache invalidation and naming things.
内存管理是数据面开发套件(DPDK)的一个核心部分,以此为基础,DPDK的其他部分和用户应用得以发挥其最佳性能。本系列文章将详细介绍DPDK提供的各种内存管理的功能。
本文介绍了如何通过Linux内核模块编程,实现USB设备驱动,特别是针对键盘、鼠标等输入设备的驱动开发。通过分析具体的实现过程,作者让读者了解如何通过Linux内核模块编程,实现USB设备驱动,特别是针对键盘、鼠标等输入设备的驱动开发。
我们接着看linux初始化内存的下半部分,等内存初始化后就可以进入真正的内存管理了,初始化我总结了一下,大体分为三步:
这是 os summer of code 2020 项目每日记录的一部分: 每日记录github地址(包含根据实验指导实现的每个阶段的代码):https://github.com/yunwei37/os-summer-of-code-daily
一、内存管理架构 二、虚拟地址空间布局架构 三、物理内存体系架构 四、内存结构 五、内存模型 六、虚拟地址和物理地址的转换 七、内存映射原理分析 一、内存管理架构 内存管理子系统架构可以分为:用户空间、内核空间及硬件部分3个层面,具体结构如下所示:1、用户空间:应用程序使用malloc()申请内存资源/free()释放内存资源。2、内核空间:内核总是驻留在内存中,是操作系统的一部分。内核空间为内核保留,不允许应用程序读写该区域的内容或直接调用内核代码定义的函数。3、硬件:处理器包含一个内存管理单元(Memo
VFIO的全称是Virtual Function IO,但这个名字并不能反应它的特点,以下两个假名字更能反应VFIO的特点:
一、分布位置上的区别: kmalloc()和__get_free_pages()函数申请的内存位于物理内存的映射区域,而且在物理上也是连续的,它们与真实的物理地址只有一个固定的偏移,因此存在简单的线性关系;(3G+896M)(低端内存); vmalloc函数申请的虚拟内存与物理内存之间也没有简单的换算关系;(高端内存)(3G+896M以上的内存); 二、特性上的区别: 1、kmalloc() void *kmalloc(size_
这篇文章是对 Linux 内存相关问题的集合,工作中会有很大的帮助。关注公号的朋友应该知道之前我写过从内核态到用户态 Linux 内存管理相关的基础文章,在阅读前最好浏览下,链接如下:
1)物理地址:CPU地址总线传来的地址,由硬件电路控制其具体含义。物理地址中很大一部分是留给内存条中的内存的,但也常被映射到其他存储器上(如显存、BIOS等)。在程序指令中的虚拟地址经过段映射和页面映射后,就生成了物理地址,这个物理地址被放到CPU的地址线上。
内存管理子系统可能是linux内核中最为复杂的一个子系统,其支持的功能需求众多,如页面映射、页面分配、页面回收、页面交换、冷热页面、紧急页面、页面碎片管理、页面缓存、页面统计等,而且对性能也有很高的要求。本文从内存管理硬件架构、地址空间划分和内存管理软件架构三个方面入手,尝试对内存管理的软硬件架构做一些宏观上的分析总结。
RIFFA 是一种开源通信架构,它允许通过 PCIe 在用户的 FPGA IP 内核和 CPU 的主存储器之间实时交换数据。为了建立其逻辑通道,RIFFA 在 CPU 端拥有一系列软件库,在 FPGA 端拥有 IP 核。本文主要针对其中的DMA性能(Scatter-Gather DMA)进行测试。
linux 内存是后台开发人员,需要深入了解的计算机资源。合理的使用内存,有助于提升机器的性能和稳定性。本文主要介绍 linux 内存组织结构和页面布局,内存碎片产生原因和优化算法,linux 内核几种内存管理的方法,内存使用场景以及内存使用的那些坑。从内存的原理和结构,到内存的算法优化,再到使用场景,去探寻内存管理的机制和奥秘。
我们知道DMA通常需要访问连续的物理内存,除非设备支持iommu,当设备不支持iommu的话可以用以下方式:
导语 linux 内存是后台开发人员,需要深入了解的计算机资源。合理的使用内存,有助于提升机器的性能和稳定性。本文主要介绍 linux 内存组织结构和页面布局,内存碎片产生原因和优化算法,linux
USB设备控制器(UDC)驱动的框图如下图所示,由三部分组成。第一部分是UDC驱动核心层,在drivers/usb/gadget/udc/core.c文件中实现,该层是一个兼容层,将USB Function驱动和具体的USB gadget驱动隔离开,抽象了统一的接口和数据结构,向USB Function驱动提供了统一且稳定的接口,同时完成USB Function驱动和USB gadget驱动的匹配。第二部分是gadget driver层,负责驱动硬件工作,和具体的USB设备控制器硬件相关,dwc3的gadget driver驱动在drivers/usb/dwc3/gadget.c文件中实现。第三部分是USB设备控制器硬件。
我们之前的文章提到了操作系统的三个抽象,它们分别是进程、地址空间和文件,除此之外,操作系统还要控制所有的 I/O 设备。操作系统必须向设备发送命令,捕捉中断并处理错误。它还应该在设备和操作系统的其余部分之间提供一个简单易用的接口。操作系统如何管理 I/O 是我们接下来的重点。
点击上方“芋道源码”,选择“设为星标” 管她前浪,还是后浪? 能浪的浪,才是好浪! 每天 10:33 更新文章,每天掉亿点点头发... 源码精品专栏 原创 | Java 2021 超神之路,很肝~ 中文详细注释的开源项目 RPC 框架 Dubbo 源码解析 网络应用框架 Netty 源码解析 消息中间件 RocketMQ 源码解析 数据库中间件 Sharding-JDBC 和 MyCAT 源码解析 作业调度中间件 Elastic-Job 源码解析 分布式事务中间件 TCC-Transaction
零拷贝经常在各个框架使用,比如kafka,rocketmq,都起到了很好的作用,首先我们要知道零拷贝不是没有一次拷贝,是尽可能的减少拷贝。
到目前为止,内存管理是unix内核中最复杂的活动。我们简单介绍一下内存管理,并通过实例说明如何在内核态获得内存。
BIOS收集IOMMU相关的信息,通过ACPI中的特定表组织数据,放置在内存中,等操作系统接管硬件后,它会加载驱动,驱动再详细解析ACPI表中的信息。
对于精通 CURD 的业务同学,内存管理好像离我们很远,但这个知识点虽然冷门(估计很多人学完根本就没机会用上)但绝对是基础中的基础。
领取专属 10元无门槛券
手把手带您无忧上云