关联CSDN:
Steam Deck OLED WLAN下载速率过低问题的排查和解决-CSDN博客
前言
如前所述,Steam Deck OLED WLAN速率低问题和IOMMU有一定的关系,这里我们对IOMMU为什么会对速率有影响进行一个较深入的理解。
对于IOMMU我相信大家通过网上的资料,或多或少都有一定的了解,那在这里我们只是简单的描述下,具体相关的资料大家可以google等等。。。
首先IOMMU(Input and Output Memory Management Unit)可以我们可以直接理解为一个硬件单元,主要的作用是地址的转换和地址的隔离,可以将它和MMU进行类比。
从上图可以看出,IOMMU是直接内存访问,即设备与内存直接通信,而无需经过CPU的一个操作。
IOMMU: https://en.wikipedia.org/wiki/Input%E2%80%93output_memory_management_unit
接下来我们理解为什么IOMMU会影响Steam Deck OLED WLAN的速率:
基于市场环境,大部分外设的寻址范围优先,以目前主流的32位设备为例,其在物理内存中直接寻址的范围是0~4GB。但是,现代操作系统的内存往往大于4GB。如果设备申请DMA时,内核为设备分配的DMA buffer的地址高于4GB(如上图所示简称为"high buffer"),则设备将无法寻址到它。
但是有了IOMMU以后,IOMMU就可以在0~4GB范围内分配一段与高地址buffer长度相同的内存,让设备能够直接寻址(以下称为"low buffer")。设备向low buffer写入后,IOMMU就会将low buffer中的内容,复制到high buffer,而后通知CPU从high buffer读取内容。反之亦然——CPU向high buffer写入后,IOMMU就会将high buffer中的内容,复制到low buffer,而后通知设备从low buffer读取内容。这样,CPU和设备都能读取到对方写入的内容,这样就不会占用过多的CPU资源,以提高数据搬用的效率。这样在"high buffer"和"low buffer"之间复制内容的操作,在IOMMU机制中被称为"sync"或"bounce"。
如前描述Steam Deck OLED WLAN使用的是Qualcomm QCA2066芯片,其支持能力如下所示:
WLAN
- Compliant with lEEE 802.11a/b/g/n/ac/ax Supports 2x2 Muli-User Multiple-nput Multiple-Qutput(MU-MIMO)
- Dual Band Simultaneous(DBS), up to 3 Gbps data rate(2x2+2x2 11ax DBS)
- Tri-band 2.4 GHz/5 GHz/6 GHz support 20 MHz/40 MHz channel bandwidth for 2.4 GHz and 20MHz/40 MHz/80 MHz/160 MHz channel bandwidth for 5 GHz/6 GHz
- Seamless antenna sharing with Bluetooth, LTE, LTE-U.and 5G
- Dynamic Frequency Selection (DFS, radar detection)
- Offloading traffc for minimal host ulilization at 802.11ac/ax speeds
- Low-power PCle (with Li substate) interface
- Integrated close-loop power detector
Bluetooth
- Compliant with Bluetooth Milan and ANT+
- Supports 2 Mbps Bluetooth Low Energy (BLE), BLE LOngRange
- Split ACL support for A2DP true stereo (earbuds)
- Dedicated Bluetooth antenna, sharing Bluetooth antenna with WLAN, and concurrent with 5G WLAN
- Dual eSCO and dual A2DP streams
- Supports class 1 and class 2 power-level transmissions without requiring an extemal PA (power amplifier)
- Backward-compatible with previous Bluetooth standards
- Flexible interace Slimbus, PCM2S for Bluetooth audio
因为QCA2066的PCIe寻址范围被限制到了0~4G,所以跑流时,PCIe无法直接访问高于4G以上的内存,并且IOMMU没有被使能,所以就会发生大量的软中断进行数据的搬运,基于上图,也能直观的看到问题的原因。
这里再插个话题:
为啥Qualcomm QCA206x设备使能的是32位DMA MASK(本身支持36位 DMA MASK),而不是36位的DMA MASK,这里做了一个猜测:因为我们平常适配的都是嵌入式ARM设备,对于嵌入式ARM设备的话,其实本身的物理内存一般都是小于4G的(当前有一些Android设备除外),所以对于物理内存小于4G的设备,本身在进行内存拷贝的时候,也就不需要IOMMU的参与了,所以QCA206x只需要使能32位的DMA MASK,另一个原因是为了兼容性,一些嵌入式ARM设备不支持36位的DMA MASK。