JasonWang's Blog

JasonWang's Blog

理解Android eBPF

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/dettach程序的接口
  • 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实现流量统计
什么是GARP

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请求包, 但无须其他节点发送回应包, 常用于如下三种情况:

ARP cache不更新导致的网络问题

最近碰到了一个很奇怪的问题, Android系统(Linux内核4.15)唤醒后, SoC(高通平台)跟TBox(Telematics Box)TCP的连接会偶发变慢, 需要等超过10s才能连接上. 发送ping包给TBox, 通过strace看进程一直提示EAGAIN的错误.从字面意义来说EAGAIN(Resource temporarily unavailable)是内核告知ping进程当前没有可用的数据包可以接收. 可是, 问题来了:

  • 为什么ping一直会收到EAGAIN的错误? 内核在什么时候会返回该错误?
  • 为什么ping收不到数据包, TBox回包到底去了哪里?

幸亏好这个问题比较容易重现, 折腾了两天才最终把问题的的来龙去脉搞清楚. 接下来就来看看这个问题的现象以及背后发生的根因, 最后给出几个相应的对策.

怎么招聘SRE工程师-看看Google是如何招人

看到左耳朵耗子的一篇文章程序员如何把控自己的职业, 里边提到了Google SRE的评分卡, 用于招聘时软件工程师对自己技能水平的评估, 总共分为11个等级:

  1. You are unfamiliar with the subject area.
  • 对相关的技术领域还不熟悉
  1. You can read/understand the most fundamental aspects of the subject area.
  • 能够读懂相关领域相关的基础知识
  1. Ability to implement small changes, understand basic principles and able to figure out additional details with minimal help.
  • 可以实现一些小的改动,清楚基本的原理,并能够在简单的指导下自己找到更多的细节
  1. Basic proficiency in a subject area without relying on help.
  • 基本精通一个技术领域, 完全不需要别人的帮助
一个SMMU内存访问异常的问题

最近碰到棘手的问题: 以太网进行iperf测试时, 发生了SMMU (System Memory Management Unit)访问异常导致内核崩溃. 原本只是内部测试发现, 后面在试验车上也概率性的出现. 问题发生的概率还不小. 很严重. 只能先从头把一些基本概念与流程梳理清楚. 好在最后还是找到了原因并解决了. 松了口气, 才有时间把整个问题的来龙去脉细细的总结下, 算是一个SMMU相关问题的案例.

首先来看看问题的发生的背景.

问题背景

问题发生在利用iperf做网络性能测试的时候, 测试系统(采用高通8155平台, 内置一个EMAC芯片, 最高支持1Gbps速率)作为客户端:

1
2
3

iperf -c 172.20.2.33 -p 8989 -f m -R

这里加-R参数表示客户端作为数据接收方(奇怪的是, 测试不加-R参数就不会有问题, 这也说明只有在接收数据的过程才会出现问题), 而服务端是发送方:

1
2
3

iperf -s -p 8989 -f m

这么测试几十个小时就很快出现了, 抓取到的问题堆栈如下. 前面的日志是SMMU相关的寄存器状态打印, 后面是内核调用堆栈.

从Wifi热点功能说一说Android Wifi框架

之前帮着解决了项目中WIFI相关的问题, 一直想梳理下WIFI的框架, 方便后续代码阅读以及问题的解决. 恰好年初修改了车机上WIFI热点相关的一些代码, 重新看了下Android 10(Q)的逻辑, 于是想通过WIFI热点相关的功能作为切入点, 完整的梳理下Android WIFI的整体框架.

先不多说, 看下Android WIFI的大致框架:

android wifi framwork

Linux网络协议之数据发送流程

最近抽空学习下Linux网络协议栈, 读源码时总会前一天梳理完, 等两天再来看却发现又忘记的差不多, 只能再过一遍, 没有对协议栈构建一个系统性的框架. 于是想着要把看过的代码逻辑整理下来, 算是对这段时间学习的总结, 也方便后面的查阅.

在之前的一篇有关网络协议的文章从NAPI说一说Linux内核数据的接收流程简单的讲到了Linux的数据接收流程, 但主要是集中在数据链路层与设备驱动之间的交互, 并没有涉及到IP网络层以及TCP传输层的逻辑.对于Linux系统来说, TCP数据的传输大致要经历如下几个步骤:

  • 用户进程创建socket并创建相应数据的buffer, 通过send函数发送给服务端
  • 内核收到数据后, 将用户空间的buffer数据拷贝到内核协议栈
  • 内核协议栈需要经过TCP层(L4)/IP层(L3)/数据链路层(L2)最后发送到网卡
  • CPU与网卡的数据传输一般通过DMA进行, 完成后网卡发送中断告知CPU, 此时内核会释放之前分配的buffer

这篇文章, 我们着重来看下数据传输中内核部分的流程, 并梳理下Linux协议栈大致的结构与初始化步骤, 主要分为如下两个部分:

  • Linux内核协议栈的初始化流程
  • 数据是如何从TCP传输层发送到设备驱动的
一个ADB无法识别设备的问题

这两天隔壁部门的同事反馈说新项目上, 车机(Android系统)上挂载的USB外设(一个可以上网的TBOX设备)无法通过ADB(Android Debug Bridge)进行连接. 心里有点纳闷, USB不都识别到了吗, 上次也把ADB相关的客户端都移植过去了, 为啥还会识别不到设备了? 只得从头开始理下ADB相关的代码与逻辑.先来看看ADB的基本原理.

ADB(全称Android Debug Bridge)是Android上用途十分广泛的调试工具, 可用于与开发设备进行连接;ADB命令既可以用来主机与设备之间传输文件, 也可以通过SHELL命令对设备进行操作. 如下所示, 是ADB的一个工作原理图:

How ADB works

avatar
JasonWang
生命短暂,莫空手而归