vRAN trên VM¶
vRAN (virtualized RAN) chạy phần mềm của trạm gốc 5G (CU/DU, hay gNodeB) trên server x86 thông dụng thay cho thiết bị chuyên dụng. Phần đòi hỏi nhất là O-DU: xử lý PHY và MAC theo từng slot, trao đổi với O-RU qua fronthaul Ethernet, lại phải khớp thời gian với mạng qua PTP. Trang này nói về việc đặt O-DU vào VM. Kỹ thuật real-time dùng chung (pin vCPU, huge page, NUMA, đo cyclictest) nằm ở Real-time KVM tuning, nên làm trước.
Vì sao khó¶
- Deadline cứng theo slot: với subcarrier spacing 30 kHz, một slot dài 0,5 ms gồm 14 symbol (khoảng 35,7 µs mỗi symbol). Gói fronthaul phải gửi và nhận đúng cửa sổ thời gian quanh symbol, trễ là mất dữ liệu radio.
- Tải liên tục: PHY xử lý theo chu kỳ cố định, nên ngoài độ trễ trung bình còn phải kiểm soát đỉnh trễ.
- Đồng bộ thời gian: toàn bộ chuỗi O-DU và O-RU phải chung một thang thời gian (PTP, thường kèm SyncE), nên nguồn thời gian của VM phải chính xác.
Mô hình tổng thể¶
O-RU ==(fronthaul: eCPRI qua Ethernet, PTP)== NIC (PF)
│ SR-IOV
┌─────────────────────┼─────────────────────┐
VF0 VF1 VF2
│ │
┌────────┴────────┐ ┌────────┴────────┐
│ VM: O-DU │ │ VM khác │
│ DPDK (PMD iavf) │ │ │
│ vCPU pin, 1G HP │ │ │
└─────────────────┘ └─────────────────┘
Host: PF driver, ptp4l/phc2sys, core housekeeping, KVM + VFIO + IOMMU
| Lớp | Công nghệ |
|---|---|
| Phần cứng | NIC hỗ trợ SR-IOV và đồng hồ PTP phần cứng (PHC), tùy chọn thêm accelerator FEC/LDPC |
| Host | KVM, VFIO, IOMMU, driver PF, ptp4l/phc2sys |
| Guest | Kernel RT, DPDK, PMD của VF, stack O-DU |
SR-IOV VF cho fronthaul¶
Fronthaul cần độ trễ thấp và gói đến đúng giờ, nên virtio (đi qua vhost, tiến trình hoặc kernel của host) thường không phù hợp: đường đi dài hơn, có thêm chuyển ngữ cảnh và nguồn jitter. Thay vào đó gán thẳng một VF của NIC vào VM bằng VFIO (I/O Virtualization), mỗi VM có một đường riêng tới phần cứng mà không cần card riêng cho từng VM. PF vẫn do host quản lý.
Điều kiện cần: IOMMU bật (intel_iommu=on iommu=pt trên kernel host, xem Memory Virtualization), BIOS bật SR-IOV và VT-d.
Tạo VF và cấu hình từ host (ví dụ card Intel E810, tên PF là ens1f0):
echo 4 > /sys/class/net/ens1f0/device/sriov_numvfs
# gán MAC, VLAN cho VF; cho phép guest dùng MAC khác nếu stack O-DU cần
ip link set ens1f0 vf 0 mac 00:11:22:33:44:66 vlan 564 spoofchk off trust on
ip link show ens1f0
# đưa VF cho VFIO
dpdk-devbind.py --status
dpdk-devbind.py -b vfio-pci 0000:3b:01.0
Với libvirt, VF được khai báo là thiết bị hostdev loại PCI (managed='yes'), với QEMU thì dùng -device vfio-pci,host=0000:3b:01.0.
Lưu ý khi chọn VF:
- VF phải nằm cùng NUMA node với vCPU và RAM của VM (NUMA).
- Cấu hình VLAN, MAC, QoS và giới hạn tốc độ của VF do PF áp, guest không tự đổi được. Nhờ đó cô lập tốt, nhưng cũng nghĩa là mọi thay đổi cần quyền ở host.
- Số VF, tính năng (VLAN filtering, đồng bộ thời gian, ...) phụ thuộc NIC, firmware và driver. Kiểm tra theo tài liệu của nhà sản xuất NIC và ứng dụng O-DU đang dùng.
- Accelerator FEC/LDPC cho PHY (ví dụ Intel ACC100) cũng thường gán vào VM theo cách tương tự (VF qua VFIO, dùng qua DPDK BBDev).
- VM gán thiết bị passthrough không live migrate được.
DPDK trong guest¶
Stack O-DU gửi/nhận gói fronthaul bằng DPDK: poll mode driver (PMD) chạy ở userspace, đọc thẳng ring của NIC, không có ngắt và không qua kernel network stack. Trong guest, VF xuất hiện như một thiết bị PCI bình thường, dùng PMD iavf (với VF Intel). Xem thêm trang DPDK.
Hệ quả cho cấu hình:
- Core dành riêng: PMD poll liên tục nên core chạy 100%. Dùng vCPU cô lập và pin (ở cả guest lẫn host), không dùng chung với tiến trình khác.
- Huge page 1G: DPDK lấy bộ nhớ từ hugepage của guest, nên guest cần
default_hugepagesz=1G hugepagesz=1G hugepages=N, và VM phải được backing bằng hugepage từ host (huge page). - IOMMU trong guest: để DPDK dùng
vfio-pcitrong guest cần IOMMU ảo (vIOMMU) hoặc chế độ no-IOMMU của VFIO. Bảo vệ DMA giữa VM và host đã do IOMMU của host đảm nhiệm, nên no-IOMMU trong guest chỉ bỏ cách ly giữa userspace và kernel của chính guest.
modprobe vfio enable_unsafe_noiommu_mode=1
modprobe vfio-pci
dpdk-devbind.py -b vfio-pci 0000:00:05.0
- Kiểm tra nhanh khi mới dựng:
-l chọn các core logical đã cô lập, -a cho phép đúng thiết bị cần dùng.
Khi đo độ trễ bằng cyclictest (Real-time KVM tuning), nên đo lúc PMD và stack O-DU đang chạy tải thật, vì tranh chấp cache và băng thông bộ nhớ chỉ lộ ra khi đó.
PTP qua VF¶
Đồng bộ thời gian là phần dễ sai nhất khi ảo hóa. Linux PTP đồng bộ đồng hồ phần cứng của NIC (PHC) nhờ timestamp ở tầng PHY/MAC, còn ứng dụng thì dùng đồng hồ hệ thống. Khi có VM, câu hỏi là ai chạy ptp4l, ai sở hữu PHC, và guest lấy giờ từ đâu.
Nhiều NIC giữ PHC ở PF, và VF không tự có PHC riêng hay hardware timestamp tương đương. Việc VF có timestamp phần cứng hay không phụ thuộc NIC, firmware và driver, nên kiểm tra trên đúng máy:
ethtool -T ens1f0 # trên host, PF: hardware-transmit/receive, PTP Hardware Clock
ethtool -T <if_vf> # trong guest, nếu VF dùng driver kernel
Các mô hình thường gặp:
| Mô hình | Cách làm | Ưu | Nhược |
|---|---|---|---|
A. PTP ở host, guest lấy giờ qua ptp_kvm |
ptp4l trên PF đồng bộ PHC với grandmaster, phc2sys đồng bộ CLOCK_REALTIME của host với PHC. Guest nạp ptp_kvm để lấy giờ từ host |
Đơn giản, nhiều VM dùng chung một nguồn giờ | Độ chính xác trong guest bị giới hạn bởi hypercall và độ ổn định TSC của host, cần kiểm chứng |
| B. Gán nguyên PF (hoặc cổng) cho VM | VM sở hữu NIC, chạy ptp4l với hardware timestamp như máy thật |
Chính xác như bare-metal, VM làm PTP master cho O-RU được | Không chia sẻ NIC, mất lợi thế SR-IOV |
| C. Hybrid | Cổng PTP riêng gán cho host (hoặc một VM), cổng fronthaul chia VF cho các VM | Tách đường thời gian khỏi đường dữ liệu | Cần nhiều cổng, cấu hình phức tạp hơn |
Cách khai thác ptp_kvm ở mô hình A:
# host
ptp4l -i ens1f0 -m -f /etc/ptp4l.conf # PHC của NIC <- grandmaster
phc2sys -s ens1f0 -c CLOCK_REALTIME -m -w # CLOCK_REALTIME của host <- PHC
# guest
modprobe ptp_kvm # có thiết bị PTP "KVM virtual PTP", tên /dev/ptpN
chronyc sources -v # chrony với: refclock PHC /dev/ptp0 poll 2
Tùy cấu hình đồng bộ O-RAN mà O-DU làm master cho O-RU hay chỉ là slave của mạng (các cấu hình LLS-C1 đến C4 khác nhau ở chỗ này). Nếu O-DU phải là PTP master thì cần hardware timestamp trên cổng nối tới O-RU, nghĩa là mô hình B hoặc một ptp4l (boundary clock) chạy trên host.
Kiểm tra độ chính xác (cần đo ở đầu cuối nơi ứng dụng dùng giờ, không chỉ log của ptp4l):
ptp4l -m ... # theo dõi "rms" và "max" của offset
pmc -u -b 0 'GET TIME_STATUS_NP' # trạng thái đồng bộ, offset từ master
phc_ctl /dev/ptp0 cmp # so PHC với CLOCK_REALTIME
Cần đảm bảo invtsc cho guest, TSC ổn định và đồng bộ giữa các core, vì ptp_kvm và kvm-clock đều dựa vào đó.
Checklist triển khai¶
| Bước | Việc cần làm | Xem |
|---|---|---|
| 1. BIOS | VT-x, VT-d, SR-IOV bật, C-state sâu tắt, SMT kiểm soát | Real-time KVM tuning |
| 2. Host | isolcpus, nohz_full, rcu_nocbs, irqaffinity, huge page 1G |
Cấu hình host |
| 3. NUMA | NIC, accelerator, vCPU và RAM cùng node | NUMA |
| 4. VF | Tạo VF, gán MAC/VLAN, bind vfio-pci |
SR-IOV VF |
| 5. VM | Pin vCPU và emulator, backing bằng hugepage, gán VF và accelerator | Pin vCPU |
| 6. Guest | Cô lập vCPU, kernel RT, hugepage, DPDK, vIOMMU hoặc no-IOMMU | DPDK trong guest |
| 7. Thời gian | ptp4l/phc2sys trên host, ptp_kvm hoặc PTP trong guest |
PTP qua VF |
| 8. Kiểm chứng | cyclictest có tải, testpmd, kiểm tra offset PTP, đếm gói mất/trễ fronthaul, chạy dài hạn |
Đo bằng cyclictest |
Giới hạn và hướng mở rộng¶
- Passthrough cho hiệu năng gần native nhưng đánh đổi tính linh hoạt: không migrate VM, VF và accelerator bị gắn với host.
- Cô lập giữa nhiều VM cùng chia sẻ một server chỉ tốt khi tài nguyên được chia tĩnh. Cache L3, băng thông bộ nhớ và PCIe vẫn là tài nguyên dùng chung và có thể gây nhiễu, cần đo với tải thật.
- Chạy O-DU dưới dạng container trên Kubernetes cũng phổ biến (CPU Manager
static, Topology Manager, SR-IOV device plugin, hugepage làm resource), chung các nguyên tắc ở trên. Phần container có thể bổ sung thành trang riêng trong nhóm này. - Nếu yêu cầu vượt khả năng của KVM trên server tổng quát, xem Partitioning hypervisor.
Đọc thêm¶
- O-RAN Alliance specifications (kiến trúc, fronthaul, đồng bộ)
- DPDK documentation
- Linux PTP Project
- Kernel docs: PTP hardware clock
- Kernel docs: VFIO