距离上次将openwifi更新到更先进的zcu102平台一个半月后,openwifi再次迎来重要更新:
- 修复用户报告的内核崩溃现象
- FPGA和driver的队列增加到4
- 更精简高效的FPGA和driver传输机制
不止一个用户报告在zc706板上他们的openwifi经常(或者一直)崩溃(kernel panic),而我们这边同样版本的硬件和软件却很难复现这种崩溃。这不仅使我回想起在Apple当射频软件工程师的日子,BSP组的工程师经常会说这种现象很正常,因为cpu上跑的任务不止一个,中断会随机到达,这些因素综合在一起导致某些设计bug导致的崩溃在不同环境下发生的概率不同。那时候就经常在解决类似问题,有时候不得不跑到富士康现场调试,因为在办公室无法复现。
经过仔细的分析和推敲,我认为崩溃是因为openwifi的driver缺乏很好的流控机制所导致,在很大流量或者信道很繁忙时,前一个packet发往fpga的dma还没完成甚至还没开始,Linux的新packet已经到来。导致dma到fpga的内容是乱的,而后当fpga真正把包发走产生中断汇报给linux时,linux后续处理也会基于垃圾数据,导致崩溃。
基于以上分析,优化了fpga设计,完善了driver与linux和fpga之间的流控措施,精简了driver的中断处理,以及调整了linux前台发包和发包完成中断的锁的范围。现在几乎怎么变态的折腾openwifi的上下行流量都不会崩溃了。报告bug的用户测试下来说不再崩溃。欢迎测试!
另一个重要更新是将FPGA和driver里的队列增加到4,并且汇报给Linux。此时就可以观察到Linux调用openwifi发包时,给的队列(priority)不再是万年不变的0,而是普通包走队列2,关键的包走队列0(控制包、管理包、beacon之类的),因为Linux默认队列0到3优先级依次降低。而且Linux会给不同的队列配置不同的MAC层参数:Contention Window Min,Contention Window Max,AIFS,TXOP等。下面的截图是openwifi driver 打印的Linux下来的配置:
我不确定openwifi所用hostapd版本是否开启了WMM(Wi-Fi multimedia),但看起来很像。比如这个华为的在线白皮书:华为wifi章节2.4.1就详细描述了WMM机制。
简单说,就是根据不同业务的特性和实时性要求,分配wifi包不同的优先级参数。从VO(话音),VI(视频),BE(上网,Best Effort)到BK(背景)优先级依次降低。
在openwifi的FPGA实现中,四条队列的发送优先级也是从0到3依次降低。也就是说,如果高优先级和低优先级队列里都有缓存的包,那么先发高优先级队列中的包。目前在driver中,随着linux包下来的priority(0~3)到fpga队列做了一一对应。当然你也可以在driver中修改这种对应关系,达到一些特殊需求。openwifi的设计中,FPGA的四条队列也可以设置他们占用空口的起止时间,达到一种时间切片(time slicing)的效果。四个切片(slice)的设置可以通过用户空间工具sdrctl来完成。
后话:
openwifi的fpga原来是有两个队列,本来以为增加到4个队列只是简单复制粘贴很快完成,结果并不是。结合内核crash的问题,花了足足一个半月。期中的复杂度,主要在于如何简单高效的同步更新和维护fpga和driver中对应的四个队列的状态,并及时反馈给linux。
经过以上更新,现在openwifi driver和FPGA基础架构日趋完善和稳定,接下来可以放开手脚解决其他问题以及加入一些新特性了,例如WiFi6!
原文发表于知乎:https://zhuanlan.zhihu.com/op...
更多OpenWifi芯片相关文章请关注开源芯片/FPGA设计