Back to home page

OSCL-LXR

 
 

    


0001 .. SPDX-License-Identifier: GPL-2.0
0002 .. include:: <isonum.txt>
0003 .. include:: ../disclaimer-zh_CN.rst
0004 
0005 :Original: Documentation/PCI/pci-iov-howto.rst
0006 
0007 :翻译:
0008 
0009  司延腾 Yanteng Si <siyanteng@loongson.cn>
0010 
0011 :校译:
0012 
0013 
0014 
0015 .. _cn_pci-iov-howto:
0016 
0017 ==========================
0018 PCI Express I/O 虚拟化指南
0019 ==========================
0020 
0021 :版权: |copy| 2009 Intel Corporation
0022 :作者: - Yu Zhao <yu.zhao@intel.com>
0023           - Donald Dutile <ddutile@redhat.com>
0024 
0025 概述
0026 ====
0027 
0028 什么是SR-IOV
0029 ------------
0030 
0031 单根I/O虚拟化(SR-IOV)是一种PCI Express扩展功能,它使一个物理设备显示为多个
0032 虚拟设备。物理设备被称为物理功能(PF),而虚拟设备被称为虚拟功能(VF)。VF的分
0033 配可以由PF通过封装在该功能中的寄存器动态控制。默认情况下,该功能未被启用,PF表
0034 现为传统的PCIe设备。一旦开启,每个VF的PCI配置空间都可以通过自己的总线、设备和
0035 功能编号(路由ID)来访问。而且每个VF也有PCI内存空间,用于映射其寄存器集。VF设
0036 备驱动程序对寄存器集进行操作,这样它就可以发挥功能,并作为一个真正的现有PCI设备
0037 出现。
0038 
0039 使用指南
0040 ========
0041 
0042 我怎样才能启用SR-IOV功能
0043 ------------------------
0044 
0045 有多种方法可用于SR-IOV的启用。在第一种方法中,设备驱动(PF驱动)将通过SR-IOV
0046 核心提供的API控制功能的启用和禁用。如果硬件具有SR-IOV能力,加载其PF驱动器将启
0047 用它和与PF相关的所有VF。一些PF驱动需要设置一个模块参数,以确定要启用的VF的数量。
0048 在第二种方法中,对sysfs文件sriov_numvfs的写入将启用和禁用与PCIe PF相关的VF。
0049 这种方法实现了每个PF的VF启用/禁用值,而第一种方法则适用于同一设备的所有PF。此外,
0050 PCI SRIOV核心支持确保启用/禁用操作是有效的,以减少同一检查在多个驱动程序中的重
0051 复,例如,如果启用VF,检查numvfs == 0,确保numvfs <= totalvfs。
0052 第二种方法是对新的/未来的VF设备的推荐方法。
0053 
0054 我怎样才能使用虚拟功能
0055 ----------------------
0056 
0057 在内核中,VF被视为热插拔的PCI设备,所以它们应该能够以与真正的PCI设备相同的方式
0058 工作。VF需要的设备驱动与普通PCI设备的驱动相同。
0059 
0060 开发者指南
0061 ==========
0062 
0063 SR-IOV API
0064 ----------
0065 
0066 用来开启SR-IOV功能:
0067 
0068 (a) 对于第一种方法,在驱动程序中::
0069 
0070         int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn);
0071 
0072 nr_virtfn'是要启用的VF的编号。
0073 
0074 (b) 对于第二种方法,从sysfs::
0075 
0076         echo 'nr_virtfn' > \
0077         /sys/bus/pci/devices/<DOMAIN:BUS:DEVICE.FUNCTION>/sriov_numvfs
0078 
0079 用来关闭SR-IOV功能:
0080 
0081 (a) 对于第一种方法,在驱动程序中::
0082 
0083         void pci_disable_sriov(struct pci_dev *dev);
0084 
0085 (b) 对于第二种方法,从sysfs::
0086 
0087         echo  0 > \
0088         /sys/bus/pci/devices/<DOMAIN:BUS:DEVICE.FUNCTION>/sriov_numvfs
0089 
0090 要想通过主机上的兼容驱动启用自动探测VF,在启用SR-IOV功能之前运行下面的命令。这
0091 是默认的行为。
0092 ::
0093 
0094         echo 1 > \
0095         /sys/bus/pci/devices/<DOMAIN:BUS:DEVICE.FUNCTION>/sriov_drivers_autoprobe
0096 
0097 要禁止主机上的兼容驱动自动探测VF,请在启用SR-IOV功能之前运行以下命令。更新这个
0098 入口不会影响已经被探测的VF。
0099 ::
0100 
0101         echo  0 > \
0102         /sys/bus/pci/devices/<DOMAIN:BUS:DEVICE.FUNCTION>/sriov_drivers_autoprobe
0103 
0104 用例
0105 ----
0106 
0107 下面的代码演示了SR-IOV API的用法
0108 ::
0109 
0110         static int dev_probe(struct pci_dev *dev, const struct pci_device_id *id)
0111         {
0112                 pci_enable_sriov(dev, NR_VIRTFN);
0113 
0114                 ...
0115 
0116                 return 0;
0117         }
0118 
0119         static void dev_remove(struct pci_dev *dev)
0120         {
0121                 pci_disable_sriov(dev);
0122 
0123                 ...
0124         }
0125 
0126         static int dev_suspend(struct device *dev)
0127         {
0128                 ...
0129 
0130                 return 0;
0131         }
0132 
0133         static int dev_resume(struct device *dev)
0134         {
0135                 ...
0136 
0137                 return 0;
0138         }
0139 
0140         static void dev_shutdown(struct pci_dev *dev)
0141         {
0142                 ...
0143         }
0144 
0145         static int dev_sriov_configure(struct pci_dev *dev, int numvfs)
0146         {
0147                 if (numvfs > 0) {
0148                         ...
0149                         pci_enable_sriov(dev, numvfs);
0150                         ...
0151                         return numvfs;
0152                 }
0153                 if (numvfs == 0) {
0154                         ....
0155                         pci_disable_sriov(dev);
0156                         ...
0157                         return 0;
0158                 }
0159         }
0160 
0161         static struct pci_driver dev_driver = {
0162                 .name =         "SR-IOV Physical Function driver",
0163                 .id_table =     dev_id_table,
0164                 .probe =        dev_probe,
0165                 .remove =       dev_remove,
0166                 .driver.pm =    &dev_pm_ops
0167                 .shutdown =     dev_shutdown,
0168                 .sriov_configure = dev_sriov_configure,
0169         };