专栏首页虚拟化笔记IOMMU(二)-从配置说起
原创

IOMMU(二)-从配置说起

惠伟:DMA和IOMMU(一)-简单介绍​zhuanlan.zhihu.com

做过DPDK/SPDK开发或者用kvm做过pci passthrough的一定知道以下的配置:

BIOS中enable vt-d,内核参数配置intel_iommu=on iommu=pt

好多人对这些配置很疑惑,不知道这些配置的是做什么的,配或者不配对性能有什么影响。

包括我自己曾经也一知半解,今天整理一下,争取让大家柳暗花明。

enable vt-d

意思很明确,BIOS收集IOMMU硬件相关的信息以及它和PCI设备连接关系的信息,通过ACPI的表上报给操作系统

intel_iommu=on

用intel_iommu驱动来驱动IOMMU硬件单元,IOMMU硬件有intel/amd/arm的等,我们一般用intel的硬件,当然用intel的iommu驱动了。

iommu=pt

我们先看内核中关于这个配置的注释

/*
 * This variable becomes 1 if iommu=pt is passed on the kernel command line.
 * If this variable is 1, IOMMU implementations do no DMA translation for
 * devices and allow every device to access to whole physical memory. This is
 * useful if a user wants to use an IOMMU only for KVM device assignment to
 * guests and not for driver dma translation.
 */

光看注释理解还不太深刻,下面分析一下代码加深理解。

早期kvm pci passthrough的实现,qemu用到的参数是-device pci-assign,host=01:00.0,kvm最终调用了iommu的代码domain_pfn_mapping。

kvm_iommu_map_pages
  └─iommu_map
      └─intel_iommu_map(domain->ops->map)
          └─domain_pfn_mapping

kvm也用了vfio-pci,qemu参数-device vfio-pci,host=b1:00.0,最终也调用了iommu的代码domain_pfn_mapping。

vfio_iommu_type1_ioctl
  └─vfio_dma_do_map
      └─vfio_pin_map_dma
          └─vfio_iommu_map
              └─iommu_map
                  └─intel_iommu_map(domain->ops->map)
                     └─domain_pfn_mapping

我们再看内核i40e的代码,它也调用到了domain_pfn_mapping。

i40e_alloc_mapped_page
  └─dma_map_page
      └─intel_map_page
          └─__intel_map_single
              ├─if(iommu_no_mapping) return paddr;
              ├─intel_alloc_iova
              └─domain_pfn_mapping

发现kvm/vfio/i40e都调用到了函数domain_pfn_mapping,相比于kvm和vfio,i40e多了一个if判断,条件是函数iommu_no_mapping的返回值。

/* Check if the dev needs to go through non-identity map and unmap process.*/
static int iommu_no_mapping(struct device *dev)
{
	int found;

	if (iommu_dummy(dev))
		return 1;

	if (!iommu_identity_mapping)
		return 0;

	found = identity_mapping(dev);
	if (found) {
		if (iommu_should_identity_map(dev, 0))
			return 1;
		else {
			/*
			 * 32 bit DMA is removed from si_domain and fall back
			 * to non-identity mapping.
			 */
			dmar_remove_one_dev_info(si_domain, dev);
			pr_info("32bit %s uses non-identity mapping\n",
				dev_name(dev));
			return 0;
		}
	} else {
		/*
		 * In case of a detached 64 bit DMA device from vm, the device
		 * is put into si_domain for identity mapping.
		 */
		if (iommu_should_identity_map(dev, 0)) {
			int ret;
			ret = domain_add_dev_info(si_domain, dev);
			if (!ret) {
				pr_info("64bit %s uses identity mapping\n",
					dev_name(dev));
				return 1;
			}
		}
	}

	return 0;
}

再回头看iommu初始化的代码

static int __init init_dmars(void)
{
	if (iommu_pass_through)
		iommu_identity_mapping |= IDENTMAP_ALL;
	if (iommu_identity_mapping) {
		ret = si_domain_init(hw_pass_through);
		if (ret)
			goto free_iommu;
	}

	if (iommu_identity_mapping) {
		ret = iommu_prepare_static_identity_mapping(hw_pass_through);
		if (ret) {
			pr_crit("Failed to setup IOMMU pass-through\n");
			goto free_iommu;
		}
	}
}

总结起来就是

配置了iommu=pt就identity mapping
if hw_pass_through==0
   hardware identity mapping
else
   software identity mapping

说明配置了iommu=pt上面的函数iommu_no_mapping返回1,那么i40e驱动就直接return paddr,并不会真正调用到domain_pfn_mapping,直接用了物理地址少了一次映射性能当然会高一些。

总结

iommu=pt并不会影响kvm/dpdk/spdk的性能,这三者本质上都是用户态驱动,iommu=pt只会影响内核驱动,能让内核驱动设备性能更高。

补充

kvm一定要用intel_iommu=on,DPDK/SPDK如果绑定vfio-pci那也一定要求intel_iommu=on,如果绑定uio/igb_uio那么就不需要intel_iommu=on,推荐都用vfio-pci,后面kvm中的pci-assign,DPDK/SPDK用到的igb_uio都得淘汰。

还有一个内核参数是nointremap,iommu实现了dma remapping和intr remaping,kvm二者都要用,但DPDK/SPDK用轮询模式,可以不用int remapping功能,那nointremap就派上用场了。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • IOMMU(三)-初始化

    BIOS收集IOMMU相关的信息,通过ACPI中的特定表组织数据,放置在内存中,等操作系统接管硬件后,它会加载驱动,驱动再详细解析ACPI表中的信息。

    惠伟
  • DMA和IOMMU(一)-简单介绍

    DMA全称Direct Memory Access,CPU访问外设内存很慢,如果由CPU给外设大量搬运数据,CPU会大量空转等待搬运数据完成,所以发明出DMA ...

    惠伟
  • ARM SMMU的原理与IOMMU

    如上图所示,smmu 的作用和mmu 类似,mmu作用是替cpu翻译页表将进程的虚拟地址转换成cpu可以识别的物理地址。同理,smmu的作用就是替设备将dma请...

    Linux阅码场
  • DPDK内存篇(一): 基本概念

    内存管理是数据面开发套件(DPDK)的一个核心部分,以此为基础,DPDK的其他部分和用户应用得以发挥其最佳性能。本系列文章将详细介绍DPDK提供的各种内存管理的...

    Linux阅码场
  • 一切都要从MyCat的配置说起

    用于定义逻辑库,name属性定义逻辑库的名字,sqlMaxLimit定义限制返回结果集的行数,如果-1表示关闭limit限制。

    用户7386338
  • IOMMU(四)-dma remapping

    DMA remapping就是在DMA的过程中IOMMU进行了一次转换,MMU把CPU的虚拟地址(va)转换成物理地址(pa),IOMMU的作用就是把DMA的虚...

    惠伟
  • openstack passthrough配置手册

    grep IOMMU /boot/config_3.10.0-957.27.2.el7.x86_64

    惠伟
  • IOMMU(五)-interrupt remmaping

    惠伟:IOMMU(四)-dma remapping​zhuanlan.zhihu.com

    惠伟
  • IOMMU(六)-post interrupt

    惠伟:IOMMU(五)-interrupt remmaping​zhuanlan.zhihu.com

    惠伟

扫码关注云+社区

领取腾讯云代金券