pcie SRIOV linux 调用流程

本文深入探讨了SR-IOV技术,一种增强I/O虚拟化的方法,通过为每个虚拟机提供独立的内存空间、中断和DMA流,实现绕过VMM的数据移动,提高I/O效率。介绍了SR-IOV的实现原理、配置过程及硬件软件条件。

背景

当前的I/O虚拟化技术有其优点和缺点。没有一个是基于任何行业标准的。
业界认识到可替代架构的问题,并正在开发可共享的新设备。这些设备复制每个VM所需的资源,以便直接连接到I/O设备,这样就可以在不涉及VMM的情况下进行数据移动。

本机共享设备通常为它们公开的每个接口提供惟一的内存空间、工作队列、中断和命令处理,同时利用主机接口背后的公共共享资源。这些共享资源仍然需要进行管理,通常将一组管理寄存器公开给VMM中的可信分区。见图1。
在这里插入图片描述
Figure 1. Natively and Software Shared

通过拥有独立的工作队列和命令处理,这些设备能够同时接收来自多个源的命令,并在将它们传递到次要结构(例如,以太网或SAS链接)之前将它们合并在一起。虚拟化软件不再需要将I/O请求多路复用到串行流中。
本地共享设备可以通过多种方式实现,包括标准化的和专有的。由于大多数这些设备是通过PCI访问的,PCI- SIG决定创建一个标准方法。PCI-SIG SR-IOV规范定义了创建本机共享设备的标准化机制。
图1显示了一个可能的示例配置,其中三个虚拟机通过虚拟函数原生(直接)访问以太网控制器中的专用资源,同时物理函数也有自己的资源。

1.1 SR-IOV Goals

PCI-SIG SR-IOV规范的目标是通过为每个虚拟机提供独立的内存空间、中断和DMA流来标准化绕过VMM参与数据移动的方法。SR-IOV体系结构的设计目的是允许设备支持多个虚拟功能(VFs),并将大量注意力放在最小化每个附加功能的硬件成本上。
SR-IOV引入了两种新的函数类型:

  1. 物理功能(PFs):这些是完整的PCIe功能,包括SR-IOV扩展功能。该功能用于配置和管理SR-IOV功能。
  2. 虚拟功能(VFs):这些是“轻量级”PCIe函数,包含数据移动所需的资源,但配置资源的集合被精心最小化。

1.2 SR-IOV概述

虚拟化的直接分配方法提供了非常快的I/O。但是,它阻止了I/O设备的共享。SR-IOV提供了一种机制,通过这种机制,单个根函数(例如单个以太网端口)可以看起来是多个独立的物理设备。
能够支持SR-IOV的设备可以配置(通常由VMM配置),使其在PCI配置空间中作为多个功能出现,每个功能都有自己的配置空间,带有基址寄存器。VMM通过将实际配置空间VFs映射到VMM提供给虚拟机的配置空间,将一个或多个VFs分配给VM。参见图2。
在这里插入图片描述
Figure 2. Mapping VF Configuration

支持SR-IOV的设备提供许多可配置的独立VFs,每个VFs都有自己的PCI配置空间。VMM将一个或多个VF分配给虚拟机。内存转换技术,如Intel®VT-x和Intel®VT-d提供硬件辅助技术,允许直接DMA传输到和从VM,从而绕过VMM的软件切换。

2.2 SR-IOV 的条件

硬件条件:
1. CPU 支持 Intel VT-x 和 VT-D (或者 AMD 的 SVM 和 IOMMU) 
2. 有支持 SR-IOV 规范的设备:目前这种设备较多,比如Intel的很多中高端网卡等。
3. CPU必须支持IOMMU(比如英特尔的 VT-d 或者AMD的 AMD-Vi,Power8 处理器默认支持IOMMU),并且在BIOS中已开启。
4. 支持PCI-SIG* Single Root I/O Virtualization and Sharing(SR-IOV),并且在BIOS中已开启。
软件条件:
  1. 需要 QEMU/KAM 的支持。
  2. 安装软件包
    yum install -y kvm virt-* libvirt bridge-utils qemu-img
    kvm:软件包中含有KVM内核模块,它在默认linux内核中提供kvm管理程序
    libvirts:安装虚拟机管理工具,使用virsh等命令来管理和控制虚拟机。
    bridge-utils:设置网络网卡桥接。
    virt-*:创建、克隆虚拟机命令,以及图形化管理工具virt-manager
    qemu-img:安装qemu组件,使用qemu命令来创建磁盘等。

查看系统是否支持虚拟化,egrep -c ‘(vmx|svm)’ /proc/cpuinfo
大于1表示开启了,等于0表示没开启,如果没开启则需要在BIOS中开启intel VT-d
查看kvm模块是否被加载lsmod |grep kvm,如果有信息,则表示加载成功。
Centos系统默认没有启动IOMMU功能,在grub文件的GRUB_CMDLINE_LINUX后面添加intel_iommu=on
检测是否生效 sudo virt-host-validate

RedHat Linux 官方提供了详细的流程:

https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/virtualization_host_configuration_and_guest_installation_guide/index

网上这方面资料还是比较多的:
https://www.cnblogs.com/sammyliu/p/4548194.html

https://www.cnblogs.com/liuhongru/p/11068460.html

https://blog.youkuaiyun.com/u010443710/article/details/104756445?utm_medium=distribute.pc_relevant_t0.none-task-blog-OPENSEARCH-1.edu_weight&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-OPENSEARCH-1.edu_weight

3.0 kernel 代码流程

查看是否支持SR-IOV:

lspci -vvs bus:dev.fun, 如果有类似下面的capability,说明支持SR-IOV, 并能看出来支持几个VFs等详细信息。
在这里插入图片描述

通过下面的命令来enable SRIOV功能:

echo 2 > /sys/bus/pci/devices/0000:5e:00.0/sriov_numvfs
上面红色的是一个支持SR-IOV功能的pcie 网卡,2是enable的数量,从下图看,enable了2个VFs后,多出来了2个pcie设备。
在这里插入图片描述

enable SR-IOV的流程:

从上面命令上看,入口是每个pcie的sriov_numvfs节点,下面是实现节点的代码:

/*
 * num_vfs > 0; number of VFs to enable
 * num_vfs = 0; disable all VFs
 *
 * Note: SRIOV spec doesn't allow partial VF
 *       disable, so it's all or none.
 */
static ssize_t sriov_numvfs_store(struct device *dev,
				  struct device_attribute *attr,
				  const char *buf, size_t count)
{
   
   
	struct pci_dev *pdev = to_pci_dev(dev);
	int ret
<think>首先,用户的问题是关于在Linux系统中配置和使用PCIe FLR(Function Level Reset)。用户提到了引用内容,这些引用是关于FLR的基本概念、优点和PCIe总线中的实现。我需要基于这些信息,结合Linux系统的实际情况来回答。 关键点: - FLR允许复位PCIe设备中的特定功能,而不影响其他功能。 -Linux中,这可能涉及内核模块、设备驱动或用户空间工具。 - 用户需要知道如何查询是否支持FLR,以及如何触发FLR。 我的回答应该: 1. **结构清晰**:分步骤解释如何配置和使用FLR。 2. **使用中文**:整个回答必须用中文。 3. **LaTeX格式**:对于数学表达式或技术术语,使用$...$或$$...$$格式。但在这个问题中,可能没有太多数学内容,主要是命令和代码。 4. **生成相关问题**:在回答末尾添加相关问题。 5. **引用标识**:在引用段落末尾添加引用标识,如[^1]。用户提供了引用[1]、[2]、[3],所以我应该引用这些。 步骤: 1. **介绍FLR**:简要解释什么是FLR,基于引用。 2. **查询FLR支持**:如何在Linux中检查PCIe设备是否支持FLR。 3. **触发FLR**:如何在Linux中执行FLR操作。 4. **配置**:如果有配置选项,解释如何设置。 5. **代码示例**:提供命令行或代码片段。 6. **注意事项**:讨论潜在风险和最佳实践。 7. **相关问题**:生成相关的问题列表。 基于引用: - [^1]:FLR允许对特定功能进行独立复位,提高系统可用性。 - [^2]:FLR在PCIe V2.0引入,可通过设备功能寄存器查询支持。 - [^3]:FLR在Multi-Function设备中优势,如清理问题功能而不影响其他。 在Linux中,FLR通常通过PCI子系统处理。常见工具: - `lspci`:列出PCI设备信息。 - `setpci`:修改PCI配置空间。 - 内核接口:如通过sysfs或直接操作配置空间。 如何触发FLR: - FLR通过设置PCI配置空间中的控制寄存器位来触发。具体是设置Device Control Register的Initiate Function Reset位。 查询支持: - 检查Device Capability Register是否支持FLR。 在Linux中,可以使用工具如`lspci -v`查看设备能力,或使用`setpci`来设置寄存器。 安全提示:FLR会复位设备,可能导致数据丢失或系统不稳定,需谨慎。 回答结构: 1. **引言**:解释FLR及其在Linux中的相关性。 2. **步骤1:查询FLR支持**:使用`lspci`命令。 3. **步骤2:触发FLR**:使用`setpci`命令或驱动方法。 4. **配置和使用**:示例命令。 5. **注意事项**:警告和最佳实践。 6. **相关问题**:生成3-5个相关问题。 生成相关问题: 1. 如何在Linux中调试FLR操作? 2. FLR与其他复位方法(如热复位)的区别? 3. 在虚拟化环境中如何使用FLR? 4. FLR操作失败的可能原因? 确保回答真实可靠:基于标准Linux PCI工具和文档。</think>### Linux PCIe FLR (Function Level Reset) 配置和使用方法 PCIe FLR (Function Level Reset) 是一种在PCIe总线中用于复位特定功能(Function)而不影响设备其他部分的机制,特别适用于多功能设备(Multi-Function Device)。它通过复位指定功能来清理状态,提高系统可用性和稳定性,尤其在调试或功能隔离场景中非常有用[^1][^3]。在Linux系统中,FLR的配置和使用主要通过命令行工具(如`lspci`和`setpci`) 或内核驱动接口实现。下面我将分步骤详细解释整个过程,确保操作安全可靠(FLR可能导致设备临时不可用,建议在测试环境或专业人员指导下进行)。 --- ### 步骤1: 查询PCIe设备是否支持FLR 在触发FLR前,必须先确认目标PCIe设备支持该功能。PCIe设备的配置空间中有一个设备能力寄存器(Device Capability Register),用于指示FLR支持。在Linux中,可以使用`lspci`命令查询该信息。 - **命令示例**: ```bash lspci -vvv -s <BDF> | grep "FLReset+" # <BDF> 替换为目标设备Bus:Device.Function标识符 ``` 如果输出中包含`FLReset+`(例如`Capabilities: [60] Express (v2) FLReset+`),则表示设备支持FLR[^2]。如果无输出,则设备不支持。 - **示例说明**: - 先使用`lspci`获取设备BDF标识: ```bash lspci # 列出所有PCI设备,例如输出"01:00.0 Ethernet controller: Intel Corporation ..." ``` - 假设BDF为`01:00.0`,运行: ```bash lspci -vvv -s 01:00.0 | grep "FLReset+" ``` 支持FLR时,输出类似:`Capabilities: [60] Express Endpoint, MSI 00, FLReset+`。 此步骤基于PCIe规范,设备功能寄存器中的FLR位由硬件厂商实现,软件通过标准工具查询[^2]。 --- ### 步骤2: 触发FLR操作 如果设备支持FLR,可以通过设置PCI配置空间中的设备控制寄存器(Device Control Register)来触发复位。在Linux中,常用`setpci`工具直接修改寄存器值,或通过内核驱动编程实现。以下是两种方法: #### 方法1: 使用`setpci`命令行工具(推荐用户空间操作) `setpci`允许直接读写PCI配置空间。FLR通过设置设备控制寄存器的第15位(Initiate Function Reset位)触发。 - **命令语法**: ```bash setpci -s <BDF> CAP_EXP+8.w=0000:0100 # 设置控制寄存器位 ``` 命令解释: - `CAP_EXP+8`:设备控制寄存器的偏移地址(通常为Express Capability结构偏移+8字节)。 - `0000:0100`:写入的值,其中`0100`表示设置第15位(二进制第15位为1)。 - 操作完成后,设备功能将被复位,可能需要几毫秒到几秒生效。 - **完整示例**: ```bash # 步骤1: 确认设备支持FLR(如步骤1所示) # 步骤2: 触发FLR setpci -s 01:00.0 CAP_EXP+8.w=0000:0100 # 步骤3: 验证复位(可选),通过dmesg查看内核日志 dmesg | grep "pci_reset_function" # 输出可能包含复位成功信息 ``` #### 方法2: 通过内核驱动编程(适用于开发者) 如果设备有自定义驱动,可以在驱动代码中使用Linux内核提供的PCI复位API。核心函数是`pci_reset_function()`,它封装了FLR操作。 - **代码示例**(C语言): ```c #include <linux/pci.h> void trigger_flr(struct pci_dev *pdev) { if (pci_reset_function(pdev) == 0) { printk(KERN_INFO "FLR triggered successfully for device %s\n", pci_name(pdev)); } else { printk(KERN_ERR "FLR failed for device %s\n", pci_name(pdev)); } } ``` 开发者需在驱动中调用此函数,并确保设备支持FLR(通过`pci_dev->device_cap`检查)。 --- ### 步骤3: 配置和最佳实践 - **配置注意事项**: - **权限要求**:`setpci`命令通常需要root权限,运行时添加`sudo`。 - **自动脚本**:可将FLR命令集成到脚本中,用于自动化测试。例如: ```bash #!/bin/bash BDF="01:00.0" if lspci -s $BDF | grep -q "FLReset+"; then setpci -s $BDF CAP_EXP+8.w=0000:0100 echo "FLR triggered for $BDF" else echo "Device does not support FLR" fi ``` - **内核参数**:在部分系统,可通过内核启动参数启用PCIe复位支持,但FLR通常无需额外配置。 - **最佳实践**: - **风险控制**:FLR会复位设备状态,可能导致未保存数据丢失或驱动崩溃。建议在设备空闲时操作,并避免在生产环境直接使用[^1]。 - **错误处理**:如果FLR失败,检查`dmesg`输出(如`pci_reset_function failed`),常见原因包括硬件不支持或寄存器访问冲突。 - **替代方案**:对于不支持FLR的设备,可使用其他复位方法,如热复位(`echo 1 > /sys/bus/pci/devices/<BDF>/reset`)[^3]。 FLR在Linux中的实现依赖于PCI子系统,合理使用可加速设备调试和功能隔离,尤其适用于虚拟化或多功能设备场景[^3]。 --- ### 相关问题 1. 如何在Linux中调试FLR操作失败的问题? 2. FLR与其他PCIe复位机制(如热复位或冷复位)有什么区别和优缺点? 3. 在KVM虚拟化环境中,如何为VF(Virtual Function)配置FLR? 4. 哪些常见的PCIe设备(如网卡或GPU)支持FLR,如何验证兼容性? [^1]: 手把手教你学pcie---基本概念:pcie的Function Level Reset(FLR)功能。综上所述,PCIe的PF中的Function Level Reset(FLR)功能是一种强大的工具,它允许对PCIe设备中的特定功能进行独立的复位操作。通过合理使用FLR功能,可以提高系统的可用性和稳定性,加速开发和调试过程,并维护系统的灵活性和可扩展性。 [^2]: PCIe总线自V2.0加入了功能层复位(Function Level Reset,FLR)的功能。该功能主要针对的是支持多个功能的PCIe设备(Multi-Fun PCIe Device),可以实现只对特定的Function复位,而其他的Function不受影响。当然,该功能是可选的,并非强制的,软件可以通过查询配置空间中的设备功能寄存器(Device Capability Register)来查询该PCIe设备是否支持FLR。 [^3]: FLR主要有优势的场景是在Multi-Function下: 某个Function出现问题并且是不可恢复的,这时可以使用FLR清理掉出问题的Function,而其它Function正常工作(FLR也支持在SRIOV下清理掉Virtual Function,只有一个Physical Function的SRIOV场景不是Multi-Function)。有将一个系统的function移除或者合并到另外一个系统的场景,这时用FLR可以将被移除的Function 清理掉。当系统中某一个Function的软件需要重建软件栈时,只reset某个Function可以避免共享资源被清理进而影响到其它Function。 总结下来就是由于某些原因而需要清理某个Function,而不是所有Function或者系统而引入FLR。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值