在优化网络性能时, 不可避免要对网络的带宽进行测试. 通常大家可能都会使用iperf
来执行网络链路的吞吐量测试, 但iperf
只能测试TCP/IP
协议层的速度, 这个带宽数据跟TCP/UDP
协议的参数配置以及应用层缓冲区的大小都有关系. 有时, 我们希望直接测试网卡本身的实际吞吐量, 看看网卡实际的发包能力. Linux内核提供了pktgen
工具用以产生数据包, 向网卡注入TCP/UDP
数据. 这里, 我们就来看下具体如何通过pktgen
来测试网卡性能.
最近因为公司安全的需求, 要修改openssh
的源码, 将其移植到一个ARM的嵌入式系统上, 替换原有的预编译的版本. 参考了网上的一些移植openssh
的资料, 如openssl官网编译安装说明; 移植openssh到arm-linux, 但是由于目标平台不一样, 实践起来并不能完全参考, 会有细微的差异. 这里把整个流程写下来, 总结一下, 方便后面移植相关开发工具.
深度学习(Deep Learning
)是近年来人工智能的热门研究领域, 广泛地应用在工业与商业领域, 如计算机视觉(Computer Vision
), 语音识别(Speech Recognition
), 自然语言处理(Natural Language Processing
), 机器翻译(Machine Translation
), 以及医学图像分析, 药物发现等领域都采用了深度学习方法. 从本质上来说, 深度学习属于机器学习(Machine Learning
)的一个分支, 是一种从大规模数据进行学习然后能在新数据集进行推理泛化的数学模型.
相比人工智能, 深度学习只是最近十来年才出现的概念, 但为何会在在最近几年(2010开始)内出现井喷式的增长, 成为人工智能领域炙手可热的研究方向了? 总结来说主要有如下几个原因:
天之道, 利而不害; 圣人之道, 为而不争
老子
Android从9.0版本开始全面支持eBPF(extended Berkeley Packet Filters
), 其主要用在流量统计上, 也可以用来监控CPU/IO/内存等模块的状态.简单来说, eBPF
可以与内核的kprobe
/tracepoints
/skfilter
等模块相结合, 将eBPF的函数hook到内核事件从而监控相应的系统状态.
Android为eBPF提供了许多封装的库, 并提供了eBPF加载器bpfloader
:
bpfloader
: 位于/system/bpf/bpfloader
, 系统启动时负责加载位于/system/etc/bpf
中的eBPF目标文件libbpf_android
: 位于/system/bpf/libbpf_android
提供创建bpf容器/加载bpf目标文件的接口libbpf
: 位于/external/bcc
, 封装了bpf的系统调用, 提供如attach/deattach程序的接口libnetdbpf
: 位于/system/netd/libnetdbpf
, 实现了netd流量统计功能的函数
目前在Android(Q)上有两处eBPF的代码: 一个是/system/netd/bpf_progs/netd.c
, 主要是用于流量统计;一个是/system/bpfprogs/time_in_state.c
用于监控CPU运行频率以及上下文切换的耗时.
接下来我们就从三个部分来深入理解下Android是如何利用eBPF的:
- eBPF程序与目标文件格式
- Android eBPF加载与执行流程
- Android如何基于eBPF实现流量统计
ARP(Address Resolution Protocol)
即地址解析协议, 用于将网络层L3的IP地址转换成数据链路层的L2地址(MAC地址), 常用在诸如以太网, 无线网络等局域网中, 但对如点对点(P2P)网络, 组播与多播IP地址, 都无需使用ARP
协议.
一般来说, L3-L2地址的转换通常被成为邻区协议(neighboring protocol
), 这种发现邻居节点(neighbor
)的协议被统称为邻居发现协议(Neighbor Discovery Protocol
, ND
). ARP
可以看作是ND
的ipv4版本(参考RFC826), 在ipv6中则直接称为ND
(参考RFC4861).
邻居节点(
neighbor
)指的是跟主机在同一局域网(LAN
)的其他节点
ND
协议有两种消息类型:
Solicitation Request
(也称为Neighbor Solicitation
): 用于主机发送消息到网络中查询是否有主机拥有某个L3的IP地址, 该消息可以是单播, 组播或者广播形式.Solicitation Reply
(又称为Neighbor Advertisement
): 收到Solicitation Request
包时发出的回应包(有可能是HOST本身发出的, 也有可能是ARP
代理服务器发送的)
那么, 什么是Gratuitous ARP
(简称GARP
, 免费ARP)了? 简单来说, GARP
是一种用于告知网络中其他节点某些特定信息的ARP请求包, 但无须其他节点发送回应包, 常用于如下三种情况:
最近碰到了一个很奇怪的问题, Android系统(Linux内核4.15)唤醒后, SoC(高通平台)跟TBox(Telematics Box)TCP的连接会偶发变慢, 需要等超过10s才能连接上. 发送ping包给TBox, 通过strace
看进程一直提示EAGAIN
的错误.从字面意义来说EAGAIN
(Resource temporarily unavailable
)是内核告知ping进程当前没有可用的数据包可以接收. 可是, 问题来了:
- 为什么ping一直会收到
EAGAIN
的错误? 内核在什么时候会返回该错误? - 为什么ping收不到数据包, TBox回包到底去了哪里?
幸亏好这个问题比较容易重现, 折腾了两天才最终把问题的的来龙去脉搞清楚. 接下来就来看看这个问题的现象以及背后发生的根因, 最后给出几个相应的对策.
看到左耳朵耗子的一篇文章程序员如何把控自己的职业, 里边提到了Google SRE的评分卡, 用于招聘时软件工程师对自己技能水平的评估, 总共分为11个等级:
- You are unfamiliar with the subject area.
- 对相关的技术领域还不熟悉
- You can read/understand the most fundamental aspects of the subject area.
- 能够读懂相关领域相关的基础知识
- Ability to implement small changes, understand basic principles and able to figure out additional details with minimal help.
- 可以实现一些小的改动,清楚基本的原理,并能够在简单的指导下自己找到更多的细节
- Basic proficiency in a subject area without relying on help.
- 基本精通一个技术领域, 完全不需要别人的帮助
最近碰到棘手的问题: 以太网进行iperf测试时, 发生了SMMU (System Memory Management Unit)访问异常导致内核崩溃. 原本只是内部测试发现, 后面在试验车上也概率性的出现. 问题发生的概率还不小. 很严重. 只能先从头把一些基本概念与流程梳理清楚. 好在最后还是找到了原因并解决了. 松了口气, 才有时间把整个问题的来龙去脉细细的总结下, 算是一个SMMU相关问题的案例.
首先来看看问题的发生的背景.
问题背景
问题发生在利用iperf
做网络性能测试的时候, 测试系统(采用高通8155平台, 内置一个EMAC芯片, 最高支持1Gbps速率)作为客户端:
1 |
|
这里加-R
参数表示客户端作为数据接收方(奇怪的是, 测试不加-R
参数就不会有问题, 这也说明只有在接收数据的过程才会出现问题), 而服务端是发送方:
1 |
|
这么测试几十个小时就很快出现了, 抓取到的问题堆栈如下. 前面的日志是SMMU相关的寄存器状态打印, 后面是内核调用堆栈.
之前帮着解决了项目中WIFI相关的问题, 一直想梳理下WIFI的框架, 方便后续代码阅读以及问题的解决. 恰好年初修改了车机上WIFI热点相关的一些代码, 重新看了下Android 10(Q)的逻辑, 于是想通过WIFI热点相关的功能作为切入点, 完整的梳理下Android WIFI的整体框架.
先不多说, 看下Android WIFI的大致框架: