ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

23、DMA与网络子系统:MTK Ethernet GMAC与WiFi的DMA加速实战

23、DMA与网络子系统:MTK Ethernet GMAC与WiFi的DMA加速实战 网络数据包的收发说白了就是一场与时间的赛跑。CPU如果亲自去搬每个数据包那基本就不用干别的了。DMA在这里扮演的角色就是那个不知疲倦的搬运工。我在MTK平台上调试GMAC时遇到过一个问题千兆以太网跑不满带宽。查来查去发现是DMA描述符环配置不合理。嗯今天我们就来聊聊这个。23.1 MTK Ethernet GMAC的DMA架构MTK的GMACGigabit MAC内部集成了专用的DMA引擎。它负责把网络数据包从FIFO搬到系统内存或者反过来。核心结构就两个发送描述符环Tx Descriptor RingCPU准备好数据DMA负责发送接收描述符环Rx Descriptor RingDMA接收数据CPU负责处理每个描述符里包含了数据缓冲区的物理地址数据长度状态标志位是否完成、是否有错误我个人习惯把描述符环设计成256个条目。太少容易丢包太多浪费内存。你想想看256个刚好能扛住突发流量。关键点描述符环必须放在非Cacheable的内存区域。否则CPU和DMA看到的数据不一致你会疯掉的。23.2 WiFi模块的DMA传输机制MTK的WiFi芯片比如MT7668内部也有DMA。但和GMAC不同WiFi的DMA要处理更多的协议头。WiFi数据包的DMA流程大致是这样WiFi固件把收到的数据写到内部SRAMDMA把数据从SRAM搬到主机内存驱动解析802.11头转换成802.3格式交给网络协议栈我曾经踩过一个坑WiFi的DMA描述符里有个「数据偏移」字段。默认值是0但WiFi数据包前面有24字节的802.11头。如果不设置偏移DMA会把头和数据一起搬导致协议栈解析失败。注意WiFi DMA的缓冲区大小要预留足够的头部空间。我一般设置2048字节够用。23.3 NAPI与DMA的配合机制NAPINew API是Linux网络子系统的中断缓解机制。它的核心思想是有数据来时先触发中断中断处理函数关闭中断切换到轮询模式轮询完所有数据后再开启中断为什么要配合DMA因为DMA已经把数据搬好了。NAPI只需要去描述符环里取就行了。在MTK平台上典型的NAPI轮询函数长这样static int mtk_napi_poll(struct napi_struct *napi, int budget) { struct mtk_eth *eth container_of(napi, struct mtk_eth, napi); int rx_done 0; // 遍历接收描述符环 while (rx_done budget) { struct mtk_rx_desc *desc eth-rx_ring[rx_done]; // 检查DMA是否完成 if (!(desc-status MTK_RX_DMA_DONE)) break; // 处理数据包 skb build_skb(desc-data, desc-len); napi_gro_receive(napi, skb); // 重新填充描述符 desc-status 0; rx_done; } // 如果没处理完继续轮询 if (rx_done budget) return budget; // 处理完了重新开启中断 napi_complete_done(napi, rx_done); mtk_irq_enable(eth, MTK_RX_DONE_INT); return rx_done; }这段代码里有个细节每次处理完一个包要立即重新填充描述符。否则DMA没地方放新数据会丢包。我的经验budget值不要设太大。我一般设64既能保证吞吐量又不会让CPU饿死其他任务。23.4 性能调优实战在实际项目中DMA和NAPI的配合有几个关键参数参数推荐值说明描述符环大小256平衡内存和吞吐量NAPI budget64单次轮询最大包数DMA burst size8一次DMA传输的字节数中断合并阈值4攒够4个包再触发中断我曾经在MT7621平台上调试WiFi吞吐量。默认配置下2.4G只能跑到80Mbps。后来我把DMA burst size从4改成8NAPI budget从32改成64直接飙到150Mbps。为什么会这样因为burst size大了DMA每次搬运的数据更多减少了总线占用。NAPI budget大了一次轮询能处理更多包减少了中断次数。核心原则让DMA多干活让CPU少中断。NAPI就是那个「攒一波再处理」的机制。23.5 避坑指南最后分享几个我踩过的坑Cache一致性DMA缓冲区一定要用dma_alloc_coherent()分配或者手动做cache flush。否则你会看到数据错乱。描述符环溢出如果CPU处理速度跟不上DMA描述符环会满。这时候要丢包还是反压我建议丢包反压会导致DMA卡死。中断亲和性多核CPU上把网络中断绑定到同一个核。否则cache来回迁移性能下降30%。嗯DMA和网络子系统的配合说白了就是「让硬件干硬件的活让软件干软件的活」。NAPI就是那个协调者告诉DMA「你先搬搬完了叫我」。搞懂了这一点MTK平台的网络驱动就没什么秘密了。
返回列表