【88】SR-IOV

    这篇文章已经写完半年,最近半年一直在适配各种国产CPU,一直没有时间整理。最近总算是把所有的国产CPU都适配完了。

0、前言

    为了充分利用硬件资源,需要使用虚拟化技术。为了更准确地了解SR-IOV,我们来看一下SR-IOV产生的背景和研究历史。

1、传统的系统

传统的系统主要有下面的设备组成:

2、带有VI的系统

    后面提高硬件资源利用效率,在不修改硬件的前提,在hardware和SI之间引入了VI(virtualiztion Intermediary),由软件来模拟硬件行为,在VI之上就是很多虚拟机。

    VI独占下面的hardware资源,然后为每个SI抽象出硬件。由于IO操作需要通过VI处理,性能会受到显著影响,并且会增加系统资源开销。

    为了减少系统资源开销,引入了SR-IOV技术。

3、SR-IOV系统

    PF和VF都是被物理机的OS枚举的,VM访问VF BAR的时候使用的GVA (Guest Virtual Address), 这个IO操作会触发MMU把GVA翻译为GPA(Guest Physical Address), 这个GPA其实就是VM看到的VF的BAR地址空间,随后GPA会经过EPT(Expended Page Table)被翻译成HPA(Host Physical Address),这个HPA就是host上,或者说物理上的VF的BAR地址空间。

4、拥有SR-IOV的单PF设备

为了减少硬件资源,每个VF和PF share配置空间。

(1)VF使用和PF一样的配置header type。

(2)PF内的所有VF share VF BAR set,并且share SR-IOV寄存器的memory space enable(MSE)。

(3)InitialVFs和TotalVFs字段代表属于改PFVF的最大数量。如果不支持VF migration,那么TotalVFsInitialVFs应该一样。如果支持VF migration,那么TotalVFs代表可以被分配给该PF的数量,InitialVFs代表分配给该PF已经初始化的VF的数量。

    每个PF和VF会分配唯一的Routing ID(bus、device、function)。

    所有的PCIe和SR-IOV的配置访问只有VI或者SR-PCIM可以访问。

    VF包含的non-shared的物理资源(例如work queue,data buffer)等是SI直接访问的,不需要通过VI或者SR-PCIM的干预。

5、SR-IOV初始化和资源分配

5.1配置VF的BAR

    System Page Size字段定义了system映射VFmemory地址时的page size。如果system page size bit n1,那么属于该PF的所有VF支持2^(n+12)次方page size对齐。

    当system page size确定后,属于PFVF需要把BAR资源和system page size对齐

    写system page size时,VF enable bit应该为0。 

    iov.c

    在PF枚举的初始化PCIe各种cap的时候会调用sriov_init初始化SR-IOVcap

pci_device_add->pci_init_capabilities->pci_iov_init->sriov_init

    BARb VFv starting address = VF BARb + (v - 1) x (VF BARb aperture size)

    对于同一个PF下的不同VF的同一个BARnmemory空间上是连续的。因此,PFSR-IOV寄存器只需要记录第一个VFBAR的地址,其他VFBAR的地址,需要通过上面公式计算。

   我们找一个82599的网卡,enable 2VF后看看PCIe资源

    00:02.0 PCI bridge: Intel Corporation Xeon E5/Core i7 IIO PCI Express Root Port 2a (rev 07) (prog-if 00 [Normal decode])

    Memory behind bridge: f7c00000-f7ffffff

    Prefetchable memory behind bridge: 00000000f4000000-00000000f43fffff

    Root Port下面预留了4M的地址

 03:00.0 Ethernet controller: Intel Corporation 82599ES 10-Gigabit SFI/SFP+ Network Connection (rev 01)

  Capabilities: [160 v1] Single Root I/O Virtualization (SR-IOV)

    IOVCap: Migration-, Interrupt Message Number: 000

        IOVCtl: Enable+ Migration- Interrupt- MSE+ ARIHierarchy+

        IOVSta: Migration-

        Initial VFs: 64, Total VFs: 64, Number of VFs: 2, Function Dependency Link: 00

        VF offset: 128, stride: 2, Device ID: 10ed

        Supported Page Size: 00000553, System Page Size: 00000001

        Region 0: Memory at 00000000f4000000 (64-bit, prefetchable)

        Region 3: Memory at 00000000f4100000 (64-bit, prefetchable)

        VF Migration: offset: 00000000, BIR: 0

    PF0Initial VFs: 64表示归属PF0的已经初始化的VF个数是64

    Total VFs: 64, 表示归属PF0的最大VF的个数是64

    Number of VFs: 2表示归属PF0的可用的VF的个数是2

   VF offset: 128表示归属PF01VFrouting IDbus:device.functionoffset,用PF0routing ID+这个字段就是1VFroutingID

    stride: 2表示下1VFrouting ID到前1VFrouting IDoffset

    struct pci_dev *devPF(3:0.0)int vf_idVF的编号:

   

对于第2VF3:10.2)的bus=dev->bus->number + ((dev->dev_fun + dev->sriov->offset + dev->sriov->stride * vf_id) >>8) =3+((0+128+2*1)>>8)=3+0=32vfbus=0x3

    对于第2个VF(3:10.2)的devfun= (dev->dev_fun + dev->sriov->offset + dev->sriov->stride * vf_id) & 0xff = (0 + 128 + 2 * 1) & 0xff =0x822vfdevice=0x10, function=0x2

    Device ID: 10ed:表示SI看到的VFdeviceid

    PF0SR-IOV显示VFBAR0的起始地址是f4000000BAR3的起始地址是f4100000

VFBARVF0,VF1BAR0BAR3都是16K64bit prefetchable的,也就是说PF0VF0- PF0VF63BAR0占用64*16K=1M的大小,地址是f4000000f4000000+64*16K -1= f400 0000+0x10 0000-1= f4000000~F40F FFFF

  PF0VF0- PF0VF63BAR3占用64*16K=1M的大小,PF0VF1的地址是f4100000f4100000+64*16K -1= f4100000+0x10 0000-1= f4100000~F41F FFFF

  03:00.1 Ethernet controller: Intel Corporation 82599ES 10-Gigabit SFI/SFP+ Network Connection (rev 01)

    Capabilities: [160 v1] Single Root I/O Virtualization (SR-IOV)

        IOVCtl: Enable- Migration- Interrupt- MSE- ARIHierarchy-

        Initial VFs: 64, Total VFs: 64, Number of VFs: 0, Function Dependency Link: 01

        Region 0: Memory at 00000000f4200000 (64-bit, prefetchable)

        Region 3: Memory at 00000000f4300000 (64-bit, prefetchable)

    PF1VF虽然没有使能,但是地址还是预留的。

   PF1VF0- PF0VF63BAR0占用64*16K=1M的大小,地址是f4200000f4200000+64*16K -1= f4000000+0x10 0000-1= f4200000~F42F FFFF

    PF1VF0- PF0VF63BAR3占用64*16K=1M的大小,地址是f4300000f4300000+64*16K -1= f4300000+0x10 0000-1= f4300000~F43F FFFF

    说明不管VF使能与否,RootPort都预留了对应的资源的

     只有当SR-IOVVF EnableVF MSE都为1时,VFmemory空间才可以访问。修改System Page Size会影响VF BAR aperture

6、SR-IOV Reset机制

6.1 SR-IOV Conventional Reset

    Conventional reset将会导致PF和VF回到初始值。Conventional reset会导致PF的SR-IOV Control寄存器的VF Enable比特丢失,因此,Conventional reset后VF就不存在了。

6.2 VF的FLR

    VF的FLR只影响VF的state,不影响配置空间和PCI bus address space。PF的SR-IOV寄存器的VF的BAR和VF memory space enable不受影响,VF Resizable BAR capability 值也不受影响。

    VF一定要支持FLR的,因为VM在probe VF的是会调用FLR(猜测这么做的原因是,VM不知道物理机是否曾经使用过VF,在自己用之前FLR一下,保证VF是初始状态)

vfio_pci_open_device->vfio_pci_core_enable-> pci_try_reset_function-> __pci_reset_function_locked-> pci_reset_fn_methods[m].reset_fn-> pcie_reset_flr-> pcie_flr

cat /sys/bus/pci/devices/0000\:04\:00.0/reset_method 可以查看function支持哪些reset方式。

6.3 PF的FLR

    PF的FLR会影响PF的state,并且SR-IOV寄存器的VF enable也会被影响。也就是说PF发生FLR,对应的VF 不存在了。

    如果VF enable从1变成0,那么PF下面的所有VF都不存在了,VF不能发出PCIe transaction,也不能响应配置空间和memory空间的访问。VF也不会保存任何state(包括sticky的bit)

7、Linux对SR-IOV的支持

3. PCI Express I/O Virtualization Howto — The Linux Kernel documentation

    有多种方式可以使能SR-IOV。

    方式1:PF调用SR-IOV 的API(pci_enable_sriov / pci_disable_sriov)控制使能或者禁止。如果hardware有SR-IOV的cap,loading PF driver可以使能PF和归属于PF的所有VF。有些PF driver需要模块参数来设置enable VF的数量。

  方式2:写sysfs文件系统sriov_numvfs 来使能或者禁止PF归属的VFstruct pci_driver.sriov_configure

echo 'nr_virtfn' > /sys/bus/pci/devices/<DOMAIN:BUS:DEVICE.FUNCTION>/sriov_numvfs

7.1 枚举的PF时候初始化PF的SR-IOV capability

pci_device_add->pci_init_capabilities->pci_iov_init->sriov_init

  1. 读取PCI_SRIOV_CTRL,如果VF enable已经置1,则disable,并sleep 1秒
  2. 遍历dev->bus上的所有devcie,赋值给pdev,如果是PF,则跳转到found
  3. 读取PCI_SRIOV_TOTAL_VF,获取total的数量
  4. 设置page size
  5. 遍历SR-IOV的6个bar: PCI_SRIOV_NUM_BARS,赋值给iov的数据结构
  6. 读取PF SR-IOV的PCI_SRIOV_VF_DID,赋值给iov->vf_device
  7. 调用compute_max_vf_buses,计算pf需要消耗的bus数量

7.2 方式一:PF的probe函数使能SR-IOV(PF的probe调用pci_enable_sriov

PF的probe->pci_enable_sriov->sriov_enable->sriov_add_vfs->pci_iov_add_virtfn

7.3 方式一:PF的remove函数disable SR-IOV

PF的remove->sriov_disable->sriov_del_vfs->pci_iov_remove_virtfn

7.4 方式二:使用sys文件系统使能SR-IOV

echo 'nr_virtfn' > /sys/bus/pci/devices/<DOMAIN:BUS:DEVICE.FUNCTION>/sriov_numvfs

sriov_numvfs_strore->struct pci_driver.sriov_configure-> pci_enable_sriov->sriov_enable-> sriov_add_vfs->pci_iov_add_virtfn

比如82599的网卡,一开始没有vf的,我们使能2个VF

echo 2 > /sys/bus/pci/devices/0000\:04\:00.0/sriov_numvfs

  • 4
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Promox SR-IOV是一种技术,它用于在虚拟化环境中实现更高的性能和更低的延迟。SR-IOV代表单根输入/输出虚拟化,它允许虚拟机直接访问物理设备,而无需通过主机操作系统的干扰。 通常情况下,在虚拟化环境中,虚拟机通过主机操作系统来访问物理设备,这就导致了一定的性能损失和延迟。但是,Promox SR-IOV技术通过直接将物理设备的功能划分为虚拟功能,然后分配给虚拟机来解决这个问题。这使得虚拟机可以直接访问分配给它的物理设备,绕过主机操作系统的干扰。 Promox SR-IOV技术的一个重要优势是可以提供更低的延迟和更高的网络吞吐量。这对于需要高性能网络连接的应用程序非常重要,例如大规模数据传输和实时数据处理。此外,通过减少主机操作系统对网络流量的处理,SR-IOV还可以减少CPU消耗,提高整个系统的效率。 然而,Promox SR-IOV也存在一些限制。例如,由于物理设备的功能被划分为虚拟功能,因此每个虚拟机只能直接访问分配给它的特定功能。此外,SR-IOV还要求物理设备必须支持SR-IOV技术才能使用。这意味着,在实施Promox SR-IOV之前,需要对硬件进行适当的支持和配置。 总之,Promox SR-IOV是一种提高虚拟化环境性能和降低延迟的技术。通过直接将物理设备的功能划分为虚拟功能,并分配给虚拟机来实现,SR-IOV可以提供更低的延迟和更高的网络吞吐量。然而,SR-IOV也有一些限制,包括对硬件的特定支持和配置要求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

linjiasen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值