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