162306a36Sopenharmony_ci.. SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci.. include:: <isonum.txt> 362306a36Sopenharmony_ci.. include:: ../disclaimer-zh_CN.rst 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci:Original: Documentation/PCI/pci-iov-howto.rst 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci:翻译: 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci 司延腾 Yanteng Si <siyanteng@loongson.cn> 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci:校译: 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci.. _cn_pci-iov-howto: 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci========================== 1862306a36Sopenharmony_ciPCI Express I/O 虚拟化指南 1962306a36Sopenharmony_ci========================== 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci:版权: |copy| 2009 Intel Corporation 2262306a36Sopenharmony_ci:作者: - Yu Zhao <yu.zhao@intel.com> 2362306a36Sopenharmony_ci - Donald Dutile <ddutile@redhat.com> 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci概述 2662306a36Sopenharmony_ci==== 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci什么是SR-IOV 2962306a36Sopenharmony_ci------------ 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci单根I/O虚拟化(SR-IOV)是一种PCI Express扩展功能,它使一个物理设备显示为多个 3262306a36Sopenharmony_ci虚拟设备。物理设备被称为物理功能(PF),而虚拟设备被称为虚拟功能(VF)。VF的分 3362306a36Sopenharmony_ci配可以由PF通过封装在该功能中的寄存器动态控制。默认情况下,该功能未被启用,PF表 3462306a36Sopenharmony_ci现为传统的PCIe设备。一旦开启,每个VF的PCI配置空间都可以通过自己的总线、设备和 3562306a36Sopenharmony_ci功能编号(路由ID)来访问。而且每个VF也有PCI内存空间,用于映射其寄存器集。VF设 3662306a36Sopenharmony_ci备驱动程序对寄存器集进行操作,这样它就可以发挥功能,并作为一个真正的现有PCI设备 3762306a36Sopenharmony_ci出现。 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci使用指南 4062306a36Sopenharmony_ci======== 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci我怎样才能启用SR-IOV功能 4362306a36Sopenharmony_ci------------------------ 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci有多种方法可用于SR-IOV的启用。在第一种方法中,设备驱动(PF驱动)将通过SR-IOV 4662306a36Sopenharmony_ci核心提供的API控制功能的启用和禁用。如果硬件具有SR-IOV能力,加载其PF驱动器将启 4762306a36Sopenharmony_ci用它和与PF相关的所有VF。一些PF驱动需要设置一个模块参数,以确定要启用的VF的数量。 4862306a36Sopenharmony_ci在第二种方法中,对sysfs文件sriov_numvfs的写入将启用和禁用与PCIe PF相关的VF。 4962306a36Sopenharmony_ci这种方法实现了每个PF的VF启用/禁用值,而第一种方法则适用于同一设备的所有PF。此外, 5062306a36Sopenharmony_ciPCI SRIOV核心支持确保启用/禁用操作是有效的,以减少同一检查在多个驱动程序中的重 5162306a36Sopenharmony_ci复,例如,如果启用VF,检查numvfs == 0,确保numvfs <= totalvfs。 5262306a36Sopenharmony_ci第二种方法是对新的/未来的VF设备的推荐方法。 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci我怎样才能使用虚拟功能 5562306a36Sopenharmony_ci---------------------- 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci在内核中,VF被视为热插拔的PCI设备,所以它们应该能够以与真正的PCI设备相同的方式 5862306a36Sopenharmony_ci工作。VF需要的设备驱动与普通PCI设备的驱动相同。 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_ci开发者指南 6162306a36Sopenharmony_ci========== 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ciSR-IOV API 6462306a36Sopenharmony_ci---------- 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci用来开启SR-IOV功能: 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ci(a) 对于第一种方法,在驱动程序中:: 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn); 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_cinr_virtfn'是要启用的VF的编号。 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci(b) 对于第二种方法,从sysfs:: 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci echo 'nr_virtfn' > \ 7762306a36Sopenharmony_ci /sys/bus/pci/devices/<DOMAIN:BUS:DEVICE.FUNCTION>/sriov_numvfs 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci用来关闭SR-IOV功能: 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_ci(a) 对于第一种方法,在驱动程序中:: 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci void pci_disable_sriov(struct pci_dev *dev); 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci(b) 对于第二种方法,从sysfs:: 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci echo 0 > \ 8862306a36Sopenharmony_ci /sys/bus/pci/devices/<DOMAIN:BUS:DEVICE.FUNCTION>/sriov_numvfs 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci要想通过主机上的兼容驱动启用自动探测VF,在启用SR-IOV功能之前运行下面的命令。这 9162306a36Sopenharmony_ci是默认的行为。 9262306a36Sopenharmony_ci:: 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci echo 1 > \ 9562306a36Sopenharmony_ci /sys/bus/pci/devices/<DOMAIN:BUS:DEVICE.FUNCTION>/sriov_drivers_autoprobe 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci要禁止主机上的兼容驱动自动探测VF,请在启用SR-IOV功能之前运行以下命令。更新这个 9862306a36Sopenharmony_ci入口不会影响已经被探测的VF。 9962306a36Sopenharmony_ci:: 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci echo 0 > \ 10262306a36Sopenharmony_ci /sys/bus/pci/devices/<DOMAIN:BUS:DEVICE.FUNCTION>/sriov_drivers_autoprobe 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ci用例 10562306a36Sopenharmony_ci---- 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci下面的代码演示了SR-IOV API的用法 10862306a36Sopenharmony_ci:: 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci static int dev_probe(struct pci_dev *dev, const struct pci_device_id *id) 11162306a36Sopenharmony_ci { 11262306a36Sopenharmony_ci pci_enable_sriov(dev, NR_VIRTFN); 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci ... 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_ci return 0; 11762306a36Sopenharmony_ci } 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci static void dev_remove(struct pci_dev *dev) 12062306a36Sopenharmony_ci { 12162306a36Sopenharmony_ci pci_disable_sriov(dev); 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci ... 12462306a36Sopenharmony_ci } 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ci static int dev_suspend(struct device *dev) 12762306a36Sopenharmony_ci { 12862306a36Sopenharmony_ci ... 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci return 0; 13162306a36Sopenharmony_ci } 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci static int dev_resume(struct device *dev) 13462306a36Sopenharmony_ci { 13562306a36Sopenharmony_ci ... 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_ci return 0; 13862306a36Sopenharmony_ci } 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_ci static void dev_shutdown(struct pci_dev *dev) 14162306a36Sopenharmony_ci { 14262306a36Sopenharmony_ci ... 14362306a36Sopenharmony_ci } 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_ci static int dev_sriov_configure(struct pci_dev *dev, int numvfs) 14662306a36Sopenharmony_ci { 14762306a36Sopenharmony_ci if (numvfs > 0) { 14862306a36Sopenharmony_ci ... 14962306a36Sopenharmony_ci pci_enable_sriov(dev, numvfs); 15062306a36Sopenharmony_ci ... 15162306a36Sopenharmony_ci return numvfs; 15262306a36Sopenharmony_ci } 15362306a36Sopenharmony_ci if (numvfs == 0) { 15462306a36Sopenharmony_ci .... 15562306a36Sopenharmony_ci pci_disable_sriov(dev); 15662306a36Sopenharmony_ci ... 15762306a36Sopenharmony_ci return 0; 15862306a36Sopenharmony_ci } 15962306a36Sopenharmony_ci } 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_ci static struct pci_driver dev_driver = { 16262306a36Sopenharmony_ci .name = "SR-IOV Physical Function driver", 16362306a36Sopenharmony_ci .id_table = dev_id_table, 16462306a36Sopenharmony_ci .probe = dev_probe, 16562306a36Sopenharmony_ci .remove = dev_remove, 16662306a36Sopenharmony_ci .driver.pm = &dev_pm_ops 16762306a36Sopenharmony_ci .shutdown = dev_shutdown, 16862306a36Sopenharmony_ci .sriov_configure = dev_sriov_configure, 16962306a36Sopenharmony_ci }; 170