1.. SPDX-License-Identifier: GPL-2.0 2.. include:: <isonum.txt> 3.. include:: ../disclaimer-zh_CN.rst 4 5:Original: Documentation/PCI/pci-iov-howto.rst 6 7:翻译: 8 9 司延腾 Yanteng Si <siyanteng@loongson.cn> 10 11:校译: 12 13 14 15.. _cn_pci-iov-howto: 16 17========================== 18PCI Express I/O 虚拟化指南 19========================== 20 21:版权: |copy| 2009 Intel Corporation 22:作者: - Yu Zhao <yu.zhao@intel.com> 23 - Donald Dutile <ddutile@redhat.com> 24 25概述 26==== 27 28什么是SR-IOV 29------------ 30 31单根I/O虚拟化(SR-IOV)是一种PCI Express扩展功能,它使一个物理设备显示为多个 32虚拟设备。物理设备被称为物理功能(PF),而虚拟设备被称为虚拟功能(VF)。VF的分 33配可以由PF通过封装在该功能中的寄存器动态控制。默认情况下,该功能未被启用,PF表 34现为传统的PCIe设备。一旦开启,每个VF的PCI配置空间都可以通过自己的总线、设备和 35功能编号(路由ID)来访问。而且每个VF也有PCI内存空间,用于映射其寄存器集。VF设 36备驱动程序对寄存器集进行操作,这样它就可以发挥功能,并作为一个真正的现有PCI设备 37出现。 38 39使用指南 40======== 41 42我怎样才能启用SR-IOV功能 43------------------------ 44 45有多种方法可用于SR-IOV的启用。在第一种方法中,设备驱动(PF驱动)将通过SR-IOV 46核心提供的API控制功能的启用和禁用。如果硬件具有SR-IOV能力,加载其PF驱动器将启 47用它和与PF相关的所有VF。一些PF驱动需要设置一个模块参数,以确定要启用的VF的数量。 48在第二种方法中,对sysfs文件sriov_numvfs的写入将启用和禁用与PCIe PF相关的VF。 49这种方法实现了每个PF的VF启用/禁用值,而第一种方法则适用于同一设备的所有PF。此外, 50PCI SRIOV核心支持确保启用/禁用操作是有效的,以减少同一检查在多个驱动程序中的重 51复,例如,如果启用VF,检查numvfs == 0,确保numvfs <= totalvfs。 52第二种方法是对新的/未来的VF设备的推荐方法。 53 54我怎样才能使用虚拟功能 55---------------------- 56 57在内核中,VF被视为热插拔的PCI设备,所以它们应该能够以与真正的PCI设备相同的方式 58工作。VF需要的设备驱动与普通PCI设备的驱动相同。 59 60开发者指南 61========== 62 63SR-IOV API 64---------- 65 66用来开启SR-IOV功能: 67 68(a) 对于第一种方法,在驱动程序中:: 69 70 int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn); 71 72nr_virtfn'是要启用的VF的编号。 73 74(b) 对于第二种方法,从sysfs:: 75 76 echo 'nr_virtfn' > \ 77 /sys/bus/pci/devices/<DOMAIN:BUS:DEVICE.FUNCTION>/sriov_numvfs 78 79用来关闭SR-IOV功能: 80 81(a) 对于第一种方法,在驱动程序中:: 82 83 void pci_disable_sriov(struct pci_dev *dev); 84 85(b) 对于第二种方法,从sysfs:: 86 87 echo 0 > \ 88 /sys/bus/pci/devices/<DOMAIN:BUS:DEVICE.FUNCTION>/sriov_numvfs 89 90要想通过主机上的兼容驱动启用自动探测VF,在启用SR-IOV功能之前运行下面的命令。这 91是默认的行为。 92:: 93 94 echo 1 > \ 95 /sys/bus/pci/devices/<DOMAIN:BUS:DEVICE.FUNCTION>/sriov_drivers_autoprobe 96 97要禁止主机上的兼容驱动自动探测VF,请在启用SR-IOV功能之前运行以下命令。更新这个 98入口不会影响已经被探测的VF。 99:: 100 101 echo 0 > \ 102 /sys/bus/pci/devices/<DOMAIN:BUS:DEVICE.FUNCTION>/sriov_drivers_autoprobe 103 104用例 105---- 106 107下面的代码演示了SR-IOV API的用法 108:: 109 110 static int dev_probe(struct pci_dev *dev, const struct pci_device_id *id) 111 { 112 pci_enable_sriov(dev, NR_VIRTFN); 113 114 ... 115 116 return 0; 117 } 118 119 static void dev_remove(struct pci_dev *dev) 120 { 121 pci_disable_sriov(dev); 122 123 ... 124 } 125 126 static int dev_suspend(struct pci_dev *dev, pm_message_t state) 127 { 128 ... 129 130 return 0; 131 } 132 133 static int dev_resume(struct pci_dev *dev) 134 { 135 ... 136 137 return 0; 138 } 139 140 static void dev_shutdown(struct pci_dev *dev) 141 { 142 ... 143 } 144 145 static int dev_sriov_configure(struct pci_dev *dev, int numvfs) 146 { 147 if (numvfs > 0) { 148 ... 149 pci_enable_sriov(dev, numvfs); 150 ... 151 return numvfs; 152 } 153 if (numvfs == 0) { 154 .... 155 pci_disable_sriov(dev); 156 ... 157 return 0; 158 } 159 } 160 161 static struct pci_driver dev_driver = { 162 .name = "SR-IOV Physical Function driver", 163 .id_table = dev_id_table, 164 .probe = dev_probe, 165 .remove = dev_remove, 166 .suspend = dev_suspend, 167 .resume = dev_resume, 168 .shutdown = dev_shutdown, 169 .sriov_configure = dev_sriov_configure, 170 }; 171