1.深入了解iommu系列二:iommu 工作原理解析之dma remapping
2.多卡运行分布式训练卡死
3.AMD 处理器优化手册
4.深入了解iommu系列一:iommu硬件架构和驱动初始化
5.IOMMU(三)-初始化
深入了解iommu系列二:iommu 工作原理解析之dma remapping
深入了解iommu系列二:iommu工作原理解析之dma remapping
序言
上一篇文章主要介绍了iommu硬件架构以及驱动层的初始化流程,本文将深入探讨iommu在虚拟化和非虚拟化场景下dma remapping的工作原理。
非虚拟化场景
非虚拟化场景下,除非在cmdline中明确设置iommu为disabled,否则一般默认启用iommu硬件。iommu=pt的有米赚源码设置会提前建立静态映射。我们将通过内核代码片段分析iommu的dma工作机制。
取自内核e网卡驱动的代码片段,核心逻辑是将skb地址进行dma映射,以便硬件直接进行dma操作。pci_map_single函数最终调用intel_map_page。当iommu硬件存在(以intel iommu为例)时,它会引导到intel_map_page函数。
我们深入分析这个函数的核心逻辑。首先判断是否为iommu_no_mapping,如果是,则直接返回paddr(物理地址)。接着查看iommu_no_mapping函数的具体实现。从实现来看,首先判断iommu_identity_mapping是否为空(在iommut=pt的情况下不为空)。如果为空则返回false。在不为空的情况下,函数走到identity_mapping,实现如下:
函数首先判断iommu_identity_mapping是否为空,iommut=pt时非空。接着检查设备的domain是否为si_domain,答案肯定。函数返回true,新幽冥源码然后走到iommu_should_identity_map(dev, 0),主要判断如下:如果返回false,则从si_domain中删除设备的映射;反之,直接返回物理地址。总结,iommu=pt场景下,由于静态映射的存在,直接返回paddr。为什么直接返回物理地址而不是iova?我们详细解释。
在iommu=pt且硬件支持paasthrough翻译模式下,硬件的DMA到iommu后无需走页表翻译,直接与memory controller交互。但问题来了,iommu硬件如何区分哪些设备的DMA需要页表转换,哪些不需要?为了解决这个问题,我们回顾一下DMA页表的确定过程。
通过分析,iommu通过contex_entry的TT字段来区分。TT为b表示不需要页表转换,从而iommu通过此字段进行区分。
iommu=pt、hw为true的情况已经解释,如果hw为false,逻辑从init_dmars函数开始。在这种情况下,不会提前创建si_domain(即提前做好iova映射)。设备在DMA映射时创建,遮天源码逻辑在__intel_map_single函数中,部分核心逻辑如下。
虚拟化场景
iommu在虚拟化场景中扮演重要角色,尤其在设备直通场景。虚拟机中没有iommu,guest中使用的dma_ops走noiommu。当guest使用dma_map等API时,返回gpa。在完全模拟设备(如virtio-net或virtio-blk)场景下,内存转换还在mmu层。但在直通设备场景,外设无法直接dma gpa,需要一层转换。接下来我们分析虚拟化场景下iommu的工作。
设置iommu=pt和intel_iommu=on,将vf或pf从原驱动unbind,bind到vfio_pci,初始化vfio层面,对guest内存vfio_dma_map。iommu=pt已解释,我们关注设备unbind和bind到vfio_pci的相关操作。
设备从原驱动unbind时,如果已有si_domain(pt场景下的静态映射),则从si_domain中移除设备。将设备bind到vfio-pci driver时,核心逻辑在vfio_pci_probe函数中。
qemu侧的标王翻倍 源码vfio设备初始化函数vfio_realize,核心逻辑涉及设备所属的vfio_group和container的创建与关联。
vfio_realize中完成与vm dma相关数据结构初始化,并处理dma页表初始化。qemu通过注册memory region listener callback将vm内存映射起来,具体调用逻辑如下。
总结
结合分析,回答了非虚拟化场景下iommu=pt与disabled的区别,虚拟机中dma如何进行,以及不同intel iommu硬件下两个pci设备如何实现直通给同一vm的问题。
多卡运行分布式训练卡死
遇到多卡运行分布式训练任务卡死的问题,发现设置export NCCL_P2P_DISABLE=1后情况改善。深入研究后确定原因在于IO虚拟化(VT-d或IOMMU)中的ACS功能被启用。查阅文档后,可发现解决方法需在BIOS中关闭ACS功能。
解决步骤如下:
首先,确认ACS是否已启用。通过运行命令lspci -vvv | grep -I acsctl检查。如果结果显示SrcValid+,表明ACS已开启。
接着,修改引导参数。编辑/etc/default/grub文件以添加iommu=pt参数,并通过执行update-grub命令更新文件。
然后,在BIOS中关闭ACS功能。重启操作系统后,进入BIOS路径:Path: Advanced > Chipset Configuration > North Bridge > IIO Configuration > Intel VT for Directed I/O (VT-d) > ACS Control,财神指路源码关闭ACS功能,同时保持VT-d功能开启。
再次执行lspci -vvv | grep -I acsctl命令确认ACS是否已关闭。结果显示全显示SrcValid-,表示ACS已成功禁用。
接下来,使用CUDA测试工具以验证问题已解决。首先,通过git命令下载工具。注意根据计算卡类型调整安装参数。随后使用bandwidthTest进行内存拷贝和跨PCI-e内存带宽测试,进一步检查设备间通信效能。p2pBandwidthLatencyTest工具则用于具体测试多卡之间的P2P通信带宽。
通过以上步骤进行调整与测试,分布式训练卡死问题得到解决,确保系统稳定运行并提高整体性能。
AMD 处理器优化手册
硬件安装需注意CPU插座的3个螺丝力度均匀,避免内存、PCIe设备识别异常。BIOS设置中,将Cpre performance Boost设置为Enable以发挥处理器最高性能,关闭Golbal C-state Control以节能,但开启后会自动调整CPU功耗,影响EPYC性能,需根据需求调整。手动设置cTDP功耗限制,根据CPU最大TDP标设定,以实现更高的功率运行和更强性能。Efficiency Optimized Mode模式应关闭,以获得更强性能。Determinism Slider设置为power以允许处理器运行在最强性能状态,适合Benchmark测试,实现系统性能一致性则选择performance。Memory interleaving设置根据应用类型和内存数量设定NUMA node个数,以优化内存访问。BIOS中启用IOMMU选项,提升数据性能,尤其是在运行虚拟化软件时。
系统设置时,在Grub文件中加入iommu=pt启用Pass-through模式,并重启服务器。当服务器有SR-IOV设置时,通过Pass-through模式,无需内存数据中转,直接将设备交由终端调用。命令“cpupower frequency-set –r –g performance”将处理器设置为性能模式,发挥服务器最强性能。
进行Numa绑定以优化资源分配。使用lstopo-no-graphics查看CPU、NUMA、CPU核以及dpdk网卡的分布情况和关系。Numactl –H查看NUMA节点数和每个节点内存容量。使用watch –d –n 1 ‘cpupower monitor’监控CPU频率。lspci |grep Eth查看网卡信息。lspci –s 0:.0 –vvv查看设备号信息。dmidecode –t memory查看内存信息。
在Naples CPU中,一个CPU有4个Die,每个Die由2个CCX组成,共享一个三级缓存。通过numactl -C 0,1,2,3 -m 0,1,2,3 ./app_start绑定CPU核心和NUMA节点,提高性能。使用numactl命令查看帮助信息,了解如何使用其参数优化系统配置,如memory policy、--interleave、--preferred等。确保合理配置以实现最佳性能。
深入了解iommu系列一:iommu硬件架构和驱动初始化
深入探索iommu系列:硬件架构、驱动初始化与虚拟化应用的集成
iommu:内存隔离与DMA操作的守护者iommu,即DMA Remapping Unit,是服务器中的关键组件,它负责协调PCIe设备与IOAPIC/HPET之间的数据传输,确保在虚拟化环境中提供内存隔离,防止跨虚拟机的DMA访问。启动时,BIOS通过DMAR ACPI表进行iommu的检测和配置,其中的drhd结构描述了硬件的复杂布局,包括PCI domain的划分、关联设备以及注册基地址的管理。
硬件架构与流程图解图一、图二和图三揭示了iommu的精密架构,从DMA操作的流程到BIOS的检测机制。iommu的早期版本主要针对位系统,如今扩展到支持连续DMA和隔离功能,尤其在虚拟化环境中,它强化了PCIe协议,为虚拟机内存提供了更严格的隔离。
ACPI DMAR头与初始化关键组件ACPI DMAR header结构包含了iommu硬件抽象的详细信息,如内存映射和注册区域。iommu的初始化始于detect_intel_iommu函数,通过DMAR表的检测与验证启动。其中,dmar_domain和root_entry在地址转换中扮演核心角色,它们指导从Bus-Device-Function (BDF) 到物理内存地址(IOVA)的转换过程。
关键代码片段struct acpi_dmar_header{ ... struct intel_iommu*iommu; ... }
struct intel_iommu{ ... void __iomem*reg; ... struct dmar_domain*dmar_domain; struct root_entry*root_entry; ... } ... detect_intel_iommu{ ... dmar_table_detect; iommu_detected= 1; ... }这段代码展示了iommu初始化的核心组件,包括iommu硬件结构的定义,以及检测函数中的关键步骤。
初始化流程详解初始化过程中,iommu为每个设备分配domain_ids和dmar_domains,同时设置root_entry。直通能力通过iommu硬件的ecap字段判断,或者通过kernel启动参数iommu_pass_through=pt启用。系统构建全局si_domain,负责地址转换页表,为每个节点内存建立IOVA与HPA间的映射。接着,设备与iommu_domain相关联,通过设备bus号定位root_table并创建context_entry,同时更新si_domain的pgd。
最后,pci_bus通过iommu_ops进行设置,初始化回调和iommu_group,调用pci_device_group分配设备到特定的iommu_group。后续章节将深入探讨虚拟化场景下iommu如何处理DMA操作,iommu_pass_through=pt与disabled模式的差异,以及不同硬件平台上的直通策略,以及iommu中断remapping的具体实现。通过以上描述,我们全面理解了iommu在服务器架构中的角色和初始化过程,以及它如何在虚拟化环境中确保数据安全和性能优化。
IOMMU(三)-初始化
BIOS负责收集并组织IOMMU相关信息,放置在内存中。操作系统接管硬件后,加载驱动进行详细解析。在解析过程中,首先关注DMA Remapping Reporting Structure,这是IOMMU相关的重要结构,后面紧随DRHD(IOMMU硬件单元)和DeviceScope(处理的PCI设备)。若DRHD支持device iotlb,则还需上报ATSR(Address Translation Structure Report)。尤其在HP ProLiant DL Gen9服务器DPDK开发中,遇到了因平台RMRR(Remapped Memory Region Requirement)要求导致的设备绑定问题。HP服务器的带外管理与正常流量共用一个网卡,该网卡只能将流量DMA到一个firmware规定区域,否则firmware无法获取流量。升级firmware或在BIOS中禁用共享内存功能可解决此问题。
内核编译时生成IOMMU相关数据结构,IOMMU厂商注册检测函数,Intel注册detect_intel_iommu进行检测。内核启动后从ACPI获取DMAR table,并调用detect_intel_iommu,仅检测ACPI_DMAR_TYPE_HARDWARE_UNIT数据类型。尝试读取IOMMU硬件的capability和extended capability后,若成功,给iommu_init赋值intel_iommu_init。此函数执行时memory allocator已就绪,大量分配内存建立IOMMU数据结构。
init_dmars函数处理四种IOMMU domain,包括只用于kvm和dpdk的IOMMU_DOMAIN_IDENTITY,以及根据内核参数选择的domain,如iommu=pt时为IOMMU_DOMAIN_IDENTITY,iommu=nopt时为IOMMU_DOMAIN_DMA,未设置iommu参数则默认为IOMMU_DOMAIN_IDENTITY。此初始化工作为设备动态运行时准备了所需数据和函数,后续需分析动态运行时的操作和调用的函数。
参考文献
liujunming.top///...
support.hpe.com/hpesc/p...
lists.linuxfoundation.org...