SR-IOV 網卡虛擬化技術


目錄

 

 

PCI 與 PCIe 設備

  • PCI(Peripheral Component Interconnect,外設組件互連):符合 PCI 總線標准的設備就被稱為 PCI 設備,PCI 總線架構中可以包含多個 PCI 設備。
  • PCIe(Peripheral Component Interconnect Express,快速外設組件互連):PCI Express,簡稱 PCIe,是電腦總線 PCI 的一種,它沿用了現有的 PCI 編程概念及通訊標准,但建基於更快的串行通信系統。是 Intel 提出的新一代的總線接口,PCI Express 采用了目前業內流行的點對點串行連接,比起 PCI 以及更早期的計算機總線的共享並行架構每個 PCIe 設備都有自己的專用連接,不需要向整個總線請求帶寬,而且可以把數據傳輸率提高到一個很高的頻率,達到 PCI 所不能提供的高帶寬。

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
如上圖,PCI 插槽都是等長的,防呆口位置靠上,大部分都是純白色。PCIe 插槽大大小小,最小的 x1,最大的 x16,防呆口靠下。

SR-IOV

SR-IOV(Single-Root I/O Virtualization,單根 I/O 虛擬化)是 PCI-SIG 推出的一項標准,定義了一種 PCIe 設備虛擬化技術的標准機制,是 “虛擬通道” 的一種技術實現,用於將一個 PCIe 設備虛擬成多個 PCIe 設備,每個虛擬 PCIe 設備都具有自己的 PCIe 配置空間,如同物理 PCIe 設備一樣為上層軟件提供服務。

SR-IOV 技術是一種基於物理硬件的虛擬化解決方案,可以提高物理 I/O 設備(常見的是網絡適配器)的性能與可擴展性。SR-IOV 技術允許在虛擬機之間高效共享 PCIe 設備,由於 SR-IOV 技術是基於硬件實現的,可以使虛擬機獲得與宿主機媲美的 I/O 性能。

SR-IOV 虛擬出來的通道分為兩個類型:

  • PF(Physical Function,物理功能):管理 PCIe 設備在物理層面的通道功能,可以看作是一個完整的 PCIe 設備,包含了 SR-IOV 的功能結構,具有管理、配置 VF 的功能。

  • VF(Virtual Function,虛擬功能):是 PCIe 設備在虛擬層面的通道功能,即僅僅包含了 I/O 功能,VF 之間共享物理資源。VF 是一種裁剪版的 PCIe 設備,僅允許配置其自身的資源,虛擬機無法通過 VF 對 SR-IOV 網卡進行管理。所有的 VF 都是通過 PF 衍生而來,有些型號的 SR-IOV 網卡最多可以生成 256 個 VF。

簡而言之,每個 VF 就像是物理網卡硬件資源的一個切片,而 PF 則是對所有物理網卡硬件資源的統籌者,包括管理眾多 VF 可以協同工作。
在這里插入圖片描述

SR-IOV 的實現依賴硬件和軟件兩部分,首先,SR-IOV 需要專門的網卡芯片和 BIOS 版本,其次上層 Hypervisor 還需要安裝相應的驅動。這是因為,只有通過 PF 才能夠直接管理物理網卡的 I/O 資源和生成 VF,而 Hypervisor 要具備區分 PF 和 VF 的能力,從而正確地對網卡進行配置。

當 Hypervisor 識別出一個 VF 后,會通過 PF 來管理和配置 VF 的 I/O 資源。對於 Hypervisor 來說,VF 如同普通的 PCIe 網卡一般,安裝相應驅動后就能夠直接使用。假設一台服務器上安裝了一個單端口 SR-IOV 網卡,這個端口生成了 4 個 VF,則 Hypervisor 就得到了四個以太網連接。

在 SR-IOV 的基礎上,通過進一步利用 Intel VT-d 或 AMD IOMMU(Input/Output Memory Management Unit)技術,可以直接在虛擬機和 VF 之間做一對一的映射(PCI-Passthought)。在這個過程中,Hypervisor 的軟件交換機被完全 Bypass 掉,從而實現低延時和近線速。同 VMware 的 VM DirectPath 相比,這種方式即實現了虛擬機對 VF 硬件資源的直接訪問,又無需隨着虛擬機數量的增加而增加物理網卡的數量。

缺省情況下,SR-IOV 網卡的 VF 處於禁用狀態,此時 PF 充當傳統的 PCIe 設備。一旦啟用了 VF,PF 通過寄存器創建 VF,並通過 PF 的總線、設備和功能編號(路由 ID)訪問各個 VF 的 PCIe 配置空間。每個 VF 都具有一個 PCIe 內存空間,用於映射其寄存器集。VF 設備驅動程序對寄存器集進行操作以啟用其功能,並且顯示為實際存在的 PCIe 設備。

在 KVM 中啟用 SR-IOV 網卡

在這里插入圖片描述

手動掛載 VF 到虛擬機

  1. 查看 PCI 設備清單:
[root@overcloud-compute-0 ~]# virsh nodedev-list | grep pci pci_0000_00_00_0 pci_0000_00_01_0 pci_0000_00_01_1 pci_0000_00_02_0 pci_0000_00_03_0 pci_0000_00_03_2 pci_0000_00_05_0 pci_0000_00_05_2 pci_0000_00_05_4 pci_0000_00_11_0 pci_0000_00_16_0 ... 
  1. 查看選擇的 PCI 設備詳情:
[root@overcloud-compute-0 ~]# virsh nodedev-dumpxml pci_0000_81_10_2
<device> <name>pci_0000_81_10_2</name> <path>/sys/devices/pci0000:80/0000:80:03.0/0000:81:10.2</path> <parent>pci_0000_80_03_0</parent> <driver> <name>ixgbevf</name> </driver> <capability type='pci'> <domain>0</domain> <bus>129</bus> <slot>16</slot> <function>2</function> <product id='0x10ed'>82599 Ethernet Controller Virtual Function</product> <vendor id='0x8086'>Intel Corporation</vendor> <capability type='phys_function'> <address domain='0x0000' bus='0x81' slot='0x00' function='0x0'/> </capability> <iommuGroup number='46'> <address domain='0x0000' bus='0x81' slot='0x10' function='0x2'/> </iommuGroup> <numa node='1'/> <pci-express> <link validity='cap' port='0' width='0'/> <link validity='sta' width='0'/> </pci-express> </capability> </device> 

NOTE:主要關注 <address domain='0x0000' bus='0x81' slot='0x10' function='0x2'/> 設備信息,e.g.

domain='0x0000' bus='0x81' slot='0x10' function='0x2' 

上述這些字段組成了 PCI device 的唯一地址:address: 0000:81:10.2

  1. Shut down the guest.

  2. 根據上述設備信息編寫 new-dev XML 文件

$ cat /tmp/new-device.xml
<interface type='hostdev' managed='yes'> <source> <address type='pci' domain='0x0000' bus='0x81' slot='0x10' function='0x2' /> </source> </interface> 
  1. 將 New Device Attach 到 GuestOS
$ virsh attach-device VM1 /tmp/new-device.xml --live --config Device attached successfully 
  1. 查看 VM1 的 XML 更新
$ virsh dumpxml vm1
 ...
 <devices> ... <interface type='hostdev' managed='yes'> <mac address='52:54:00:f0:d3:b8'/> <driver name='kvm'/> <source> <address type='pci' domain='0x0000' bus='0x81' slot='0x10' function='0x2' /> </source> <alias name='hostdev0'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/> </interface> ... </devices> 

NOTE:或者可以直接 Edit 虛擬機的 XML 文件

virsh edit MyGuest

# 添加下述標簽端: <hostdev mode='subsystem' type='pci' managed='yes'> <source> <address bus='0x81' slot='0x10' function='0x2'/> </source> </hostdev> 
  1. 進入 GuestOS 查看網卡信息
root@vm1:~# ip addr show eth4 4: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000 link/ether 2c:53:4a:02:20:3d brd ff:ff:ff:ff:ff:ff inet 192.168.99.169/24 brd 192.168.99.255 scope global eth1 valid_lft forever preferred_lft forever inet6 fe80::5054:ff:fe3b:6128/64 scope link valid_lft forever preferred_lft forever 
  1. 啟動虛擬機
virsh start MyGuest 
  1. Dettach 虛擬機的 PCI 設備
$ virsh nodedev-dettach pci_0000_06_10_0 Device pci_0000_06_10_0 detached 

指令方式掛載

qemu-system-x86_64 -enable-kvm -drive file=<vm img>,if=virtio -cpu host -smp 16 -m 16G \ -name <vm name> -device vfio-pci,host=<vf pci bus addr> -device vfio-pci,host=<vf pci bus addr> -vnc :1 -net none 

重點在於通過 -device vfio-pci,host=<vf pci bus addr> 將 VF Passthrough 到虛擬機。

SR-IOV 的數據包分發機制

其實,從邏輯上可以認為啟用了 SR-IOV 技術后的物理網卡內置了一個特別的 Switch,將所有的 PF 和 VF 端口連接起來,通過 VF 和 PF 的 MAC 地址以及 VLAN ID 來進行數據包分發。

  • 在 Ingress 上(從外部進入網卡):如果數據包的目的 MAC 地址和 VLAN ID 都匹配某一個 VF,那么數據包會分發到該 VF,否則數據包會進入 PF;如果數據包的目的 MAC 地址是廣播地址,那么數據包會在同一個 VLAN 內廣播,所有 VLAN ID 一致的 VF 都會收到該數據包。

  • 在 Egress 上(從 PF 或者 VF 發出):如果數據包的 MAC 地址不匹配同一 VLAN 內的任何端口(VF 或 PF),那么數據包會向網卡外部轉發,否則會直接在內部轉發給對應的端口;如果數據包的 MAC 地址為廣播地址,那么數據包會在同一個 VLAN 內以及向網卡外部廣播。

NOTE:所有未設置 VLAN ID 的 VF 和 PF,可以認為是在同一個 LAN 中,不帶 VLAN 的數據包在該 LAN 中按照上述規則進行處理。此外,設置了 VLAN 的 VF,發出數據包時,會自動給數據包加上 VLAN,在接收到數據包時,可以設置是否由硬件剝離 VLAN 頭部。

 

轉載:

https://www.cnblogs.com/jmilkfan-fanguiju/p/12789758.html

 Switch Representation within DPDK Applications

https://doc.dpdk.org/guides/prog_guide/switch_representation.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM