Linux 内核与 eBPF 工程索引
汇总本站 Linux 内核工程相关文章,覆盖 eBPF、bpftrace、Cilium、io_uring 协同以及内存分配器实践。
发布来自土法炼钢兴趣小组的知识、笔记、进展和应用。主题包括数据结构和算法、编程语言、网络安全、密码学等。
共 79 篇文章 · 返回首页
汇总本站 Linux 内核工程相关文章,覆盖 eBPF、bpftrace、Cilium、io_uring 协同以及内存分配器实践。
系统化的 Linux 内核网络调优方法论:从基准测试建立性能基线,到 sysctl 参数与内核数据结构的对应关系,再到中断亲和性、NUMA 拓扑、ring buffer、qdisc 的逐层调优,最终通过 A/B 对比验证生产效果。
从内核源码拆解 Linux 网络丢包追踪的完整体系:kfree_skb tracepoint 与 80+ 种 drop_reason 枚举、drop_monitor netlink 子系统、dropwatch 工具、perf 丢包记录、bpftrace 丢包聚合脚本,以及生产环境常见丢包点速查表。
从内核 tracepoint 定义出发,系统讲解 bpftrace、perf、ftrace 三大工具在网络诊断中的实战用法:TCP 重传根因分析、softirq 延迟定位、收发包路径延迟剖析、conntrack 表满监控、per-function 火焰图,以及各工具的适用场景与性能开销对比。
从内核源码全面拆解 eBPF 在网络子系统中的所有挂载点:TC BPF direct-action 模式与 bpf_mprog 多程序链、XDP 驱动级钩子回顾、socket ops 回调与 TCP 生命周期事件、cgroup BPF 策略控制、sk_msg/sk_skb 的 sockmap 重定向引擎、struct_ops 实现自定义拥塞控制,以及 bpftrace 可观测实战。
从内核源码拆解 XDP 的完整实现:xdp_buff 数据结构、驱动级钩子、五种动作路径、AF_XDP 零拷贝通道、devmap/cpumap/xskmap 重定向机制、多缓冲区支持,以及 bpftrace 可观测实战。
从内核源码拆解网络子系统的内存管理全貌:sk_buff 分配路径与 slab 缓存、page_pool 页面回收机制、NUMA 感知分配策略、socket 内存记账与反压,以及 bpftrace 可观测实战。
从内核源码拆解 GRO 聚合引擎、GSO 延迟分段、TSO 硬件卸载的完整实现,分析 LRO 废弃原因,以及卸载机制对 Netfilter/TC/隧道的影响与常见陷阱。
单队列网卡的时代早已过去,但多队列本身只是起点——如何把包分到正确的 CPU 上,才是性能的关键。本文从 Linux 6.6 内核源码拆解多队列网络的完整流量分发体系:RSS 硬件哈希与 Toeplitz 算法、RPS 软件多队列模拟与 get_rps_cpu() 路径、RFS 应用感知的 rps_sock_flow_table 机制、XPS 发送端 CPU/队列亲和、aRFS 硬件流表加速,以及 netdev_pick_tx() 发送队列选择逻辑。
隧道是 overlay 网络的基础设施。本文从 Linux 6.6 内核源码拆解四类隧道协议的实现:ip_tunnel 通用框架与 struct ip_tunnel_key 元数据、IPIP 最小开销封装、GRE 可选头部与 ERSPAN 集成、VXLAN 的 UDP 封装路径与 FDB 转发表、metadata mode 流式隧道与 OVS/Cilium 集成、WireGuard 的 Noise 协议与加密路由模型,以及各协议的封装开销与硬件卸载能力对比。
容器网络不能没有虚拟设备。本文从 Linux 6.6 内核源码拆解四类核心虚拟网络设备的实现:veth pair 的 veth_xmit 零拷贝转发与 XDP native 模式、Linux bridge 的 br_handle_frame 转发路径与 FDB 学习/老化机制、macvlan 五种模式的内核实现差异、tun/tap 的内核态与用户态数据交换路径,以及各类设备的性能特征对比。
容器网络的一切隔离能力,都建立在网络命名空间之上。本文从 Linux 6.6 内核源码拆解 struct net 的完整布局、possible_net_t 与 RCU 访问模式、pernet_operations 子系统注册与生命周期回调、copy_net_ns() 命名空间创建路径、per-netns 路由表/netfilter/socket 隔离机制,以及 veth pair 跨命名空间数据转发的 skb->dev 切换原理。
dev_queue_xmit() 不是直接把包交给网卡——中间还有一层 Traffic Control。本文从 Linux 6.6 内核源码拆解 TC 框架的完整实现:struct Qdisc 与 Qdisc_ops 操作表、pfifo_fast/fq_codel/HTB/TBF 的内核实现差异、TCQ_F_CAN_BYPASS 快路径、TCQ_F_NOLOCK 无锁排队、EDT(Earliest Departure Time)调度模型、TC BPF direct-action 模式,以及 MQ 多队列根 qdisc 与 netdev_queue 的关系。
iptables/nftables 只是用户态前端——真正拦截每一个网络包的是内核中的 Netfilter 框架。本文从 Linux 6.6 内核源码拆解 Netfilter 的三大核心:nf_hook_entries 钩子链的注册与遍历、nf_conn 连接跟踪的双向元组哈希表与 GC 机制、NAT 的 SNAT/DNAT 转换路径;以及 nf_tables 相比 iptables 的关键架构升级——generation-based 无锁更新和 blob 化规则存储。
IP 包到了 ip_rcv_finish(),下一跳怎么选?本文深入拆解 Linux 路由子系统的完整实现:fib_table 的 LC-trie 数据结构、fib_info/fib_nh 的内存布局、fib_rules 策略路由链、ECMP 多路径哈希选路、nexthop 对象 API、FNHE 异常缓存(路由缓存的替代品)、dst_entry 与 rtable 的关系、IPv6 fib6 差异,以及 bpftrace 追踪路由决策的实战方法。
IP 层知道下一跳是 10.0.0.1,但网卡发帧需要 MAC 地址。ARP 解析只是表面——底层是邻居子系统(neighbour subsystem)的完整状态机:NUD_INCOMPLETE → NUD_REACHABLE → NUD_STALE → NUD_DELAY → NUD_PROBE → NUD_FAILED。本文从 Linux 6.6 内核源码拆解 struct neighbour、neigh_table 双哈希表、ARP 请求/响应处理、NDP(IPv6)、Proxy ARP、GC 回收机制,以及 neigh_connected_output 快路径的 L2 头缓存优化。
你调用 socket(AF_INET, SOCK_STREAM, 0) 创建一个 TCP 连接,底层发生了什么?内核分配了两个核心对象——VFS 层的 struct socket 和协议层的 struct sock,通过 proto_ops 和 proto 两张分发表,把文件系统语义的 read/write 翻译成协议语义的 tcp_sendmsg/tcp_recvmsg。本文从 Linux 6.6 内核源码拆解 socket 创建、双层分发、SO_REUSEPORT 多核分发、epoll 集成的完整实现。
UDP 简单?在内核中它一点都不简单。双哈希表 socket 查找、SO_REUSEPORT 多核分发、Early Demux 路由缓存、UDP GRO 聚合、reader_queue 无锁读、forward allocation 内存管理、UDP 封装(ESP/L2TP/VXLAN)——本文从 Linux 6.6 内核源码拆解 UDP 的每一个优化细节。
tcp_sendmsg 把用户数据拷到 sk_buff 就完事了?远没有。后面还有 Nagle 合并、TSQ 限流、cwnd/rwnd 双窗口门控、RACK-TLP 丢包检测、拥塞状态机五态跳转、sk_pacing_rate 软件限速。本文从 Linux 6.6 内核源码拆解 TCP 数据传输的完整路径——从 send() 到 ACK 处理——以及拥塞控制框架 tcp_congestion_ops 的可插拔架构。
TCP 连接在内核中不只是一个状态机——它是一组精心设计的数据结构和队列。本文从 Linux 6.6 内核源码出发,拆解 TCP 连接建立的 SYN Queue / Accept Queue 二级队列模型、request_sock 半连接对象、tcp_sock 全连接对象、SYN Cookie 无状态防御、TCP Fast Open 零 RTT 机制、inet_timewait_sock 轻量级 TIME_WAIT 实现,以及完整的 TCP 状态机在内核中的真实转换路径。
IP 层是 Linux 网络栈的中枢——收包时决定本地投递还是转发,发包时查路由、过 Netfilter、做分片。本文从 Linux 6.6 内核源码出发,拆解 ip_rcv → 路由决策 → ip_local_deliver / ip_forward 的完整路径,深入 FIB 表的 LC-trie 实现、策略路由 ip rule 选表机制、IP 分片/重组状态机、PMTU 发现与 FNHE 缓存,以及 Netfilter 五个钩子点的实际调用时机。
网络包到达网卡后,真正消耗 CPU 的处理全部发生在软中断上下文。本文从 Linux 6.6 内核源码出发,拆解 softirq 10 向量优先级体系、__do_softirq() 主循环与 MAX_SOFTIRQ_RESTART 放弃策略、ksoftirqd 调度时机、Threaded NAPI 替代方案,以及 CONFIG_PREEMPT_RT 下的行为变化。最后用 bpftrace/perf 实测软中断延迟和 time_squeeze 饥饿。
一个用户态 send() 调用要走过 TCP 分段、IP 路由、Netfilter 钩子、Qdisc 排队、GSO 分段、驱动 DMA 映射六个阶段才能把数据送上网线。本文从 Linux 6.6 内核源码出发,逐函数拆解完整的 TX 发包路径,深入 TSQ 限流、Qdisc 调度、BQL 防膨胀、GSO/TSO 分段决策等核心机制。
一个网络包从网卡 DMA 到用户态 recvmsg(),要走过硬中断、NAPI 轮询、GRO 聚合、协议分发、IP 路由、Netfilter 钩子、TCP/UDP 处理、socket 队列八个阶段。本文从 Linux 6.6 内核源码出发,逐函数拆解完整的 RX 收包路径,量化每一跳的 CPU 开销,并用 bpftrace 实测各阶段延迟分布。
net_device 是 Linux 内核中一切网络设备的抽象——物理网卡、虚拟 veth、隧道设备都实现同一套接口。本文从 Linux 6.6 源码出发,拆解 net_device 的结构体布局、net_device_ops 驱动操作表、NAPI 轮询模型、多队列架构、DMA ring buffer 与中断机制。
sk_buff 是 Linux 内核网络栈的通用货币——每一个收到或发出的网络包,都必须装在这个容器里走完全程。本文从 Linux 6.6 内核源码出发,拆解 sk_buff 的内存布局、四大指针操作、clone 与 copy 的代价差异、skb_shared_info 的 fragment 机制,并用 bpftrace 实测 sk_buff 分配热点和生命周期。
从 sk_buff 到 XDP,从收包路径到 TC 框架——系统拆解 Linux 内核网络子系统的每一个核心模块。基于 Linux 6.6 LTS 源码,配合 bpftrace/perf 实测追踪。
容器不是魔法。它就是几个系统调用。本文用 C 从 clone() 开始,逐个开启 PID/UTS/Mount/IPC namespace,看隔离到底是怎么回事。50 行代码,你就拥有了一个'容器'的雏形。
上一篇我们用 clone() 隔离了 PID、主机名和挂载点,但那个'容器'连 lo 都 ping 不通。本文从 CLONE_NEWNET 出发,用 veth pair + bridge + iptables MASQUERADE,一步步给容器接上网。
chroot 不是安全边界——10 行 C 就能逃出去。本文用 pivot_root 构建真正隔离的容器根文件系统:从 Alpine minirootfs 到设备节点,从 mount propagation 到只读根,一步步把容器的'地基'打牢。
你给容器设了 512MB 内存限制,结果宿主机上的数据库被 OOM-kill 了。Cgroups 不是'加个限制'那么简单 — v1 的设计是个历史错误,v2 才是正确答案。本文用 C 代码从 mkdir 开始,手动创建 cgroup,设 CPU/内存/IO 限制,压测,看它怎么把进程关进笼子。
Docker 镜像为什么能分层?pull 一个 100MB 的镜像为什么只下载 3MB?答案是 OverlayFS 的 copy-on-write。本文手工构建分层镜像,实测 COW 的性能代价。
五篇文章攒了一堆内核积木:namespace、netns、rootfs、cgroup、overlayfs。现在是时候用 Go 把它们拼成一个能跑的容器运行时了。不到 500 行代码,create/start/exec/kill/delete,五个命令走完容器的一生。
我们的迷你容器运行时能跑了,但没人能用它——因为 containerd、Kubernetes 不认识它。OCI Runtime Spec 就是容器世界的通用语言。本文拆解规范的每个关键字段,把迷你运行时改造成 containerd 能调用的标准运行时。
你的容器能调用 reboot()。是的,现在就能。除非有人拦住它。Capabilities 拆分 root 权限,Seccomp-BPF 过滤系统调用——两道防线,缺一不可。本文用 C 代码拆解这两套机制,看看 Docker 到底替你挡住了什么。
容器运行时需要 root 权限?不一定。User namespace 让普通用户也能创建容器——容器内是 root,容器外是你自己。Podman 就是这么干的。但 rootless 不是免费午餐,限制比你想象的多。
容器用 namespace 隔离,microVM 用硬件虚拟化。AWS Lambda 背后的 Firecracker 去掉了 BIOS、ACPI、PCI,只用 virtio-mmio,125ms 启动一个 VM。两种隔离模型到底差在哪?安全性差多少?开销差多少?
容器网络为什么比裸机慢?veth + bridge 每个包经过两次 netfilter,macvlan 跳过了 bridge,Cilium 用 eBPF 替掉了 iptables。到底慢多少?我们用 iperf3、wrk 和自定义 echo server 实测。
我们的迷你运行时有 500 行,runc 有 15000 行。多出来的代码在干什么?本文拆解 runc 的核心流程:从 runc create 到容器 init 进程,libcontainer 的设计,nsenter 里那段神秘的 C 代码,以及 Go runtime fork 的天坑。
深入解析 Linux io_uring 的核心机制:提交队列 (SQ)、完成队列 (CQ) 与零拷贝技术,理解它如何重塑高性能网络编程。
全方位对比 io_uring 与 epoll:从系统调用开销、内存管理到编程模型,分析 io_uring 在高性能 I/O 场景中的优势与局限。
手把手教你使用 liburing 编写第一个 io_uring 程序。详解 io_uring_queue_init, io_uring_submit 等核心 API 的使用流程。
深入网络编程,实现一个异步 TCP 服务器。学习如何使用 user_data 管理连接上下文,处理 Accept, Read, Write 链式调用。
深入探讨 io_uring 的进阶功能:SQPOLL (零系统调用)、Fixed Files (减少引用计数开销) 和 Provided Buffers (自动缓冲区管理)。
探索 Libevent 2.2+ 版本中新增的 io_uring backend。如何开启、性能表现以及当前的局限性。
并非所有场景都适合 io_uring。深入分析快路径延迟、内存隐性成本、生态复杂度等因素,帮助你做出理性的技术选型。
系统梳理 Go 集成 io_uring 的关键问题:何时值得做、CGO 与纯 Go 如何取舍、runtime.Pinner、固定缓冲区与 SQPOLL 的工程实践。
一份面向线上事故的事件驱动代码排障手册:从症状收敛、strace/eBPF/perf 逐层下钻,到 OpenTelemetry 集成与 Sanitizer 离线复盘。
系统梳理 io_uring 的线程安全模型与四种主流多线程架构模式(Thread-per-Ring、Shared Ring、Submit/Reap 分离、SQPOLL),包含完整的多线程 Echo Server 实战、NUMA 优化、性能对比与生产避坑指南。
从 NIC 驱动到用户态 read(),一个网络包在 Linux 内核中到底经历了什么?本文拆解 sk_buff、NAPI、softirq、netfilter 的完整收包路径,并用 bpftrace 实测追踪每一跳的延迟。
五种 Linux 虚拟网络设备的内核实现原理、数据流路径、性能代价与适用场景,附手工实验验证。
Netfilter 五个 hook 点、四表五链的真实遍历顺序、conntrack 状态机与性能开销、SNAT/DNAT/MASQUERADE 辨析,再到 nftables 替代方案和 eBPF 数据面——从内核视角拆解 Linux 防火墙。
Linux 路由表、FIB 查找、策略路由,以及 VXLAN/Geneve/WireGuard 隧道技术深度拆解
从 AS 和路径属性到 Route Reflector,理解 Calico 底层依赖的 BGP 协议
eBPF 在网络栈中的五大挂载点,bpf_redirect 三兄弟,以及动手写一个 TC BPF 包过滤器
从 2014 年 socket filter 到可编程拥塞控制和 SmartNIC offload,eBPF 网络能力的完整演化史
eBPF 让你在内核里插代码而不用写内核模块。听起来很美,但验证器的限制、Map 的性能陷阱、BTF 的兼容性噩梦,这些他们不会在教程里告诉你。
你的 P99 延迟突然飙到 500ms,但平均值只有 3ms。日志里什么都没有,Prometheus 图表一片祥和。bpftrace 一行命令,30 秒定位问题。这篇文章告诉你怎么做到的。
5000 个 Service、十万条 iptables 规则、一次更新锁五秒——这就是 kube-proxy 的现实。Cilium 用 eBPF Map 的 O(1) 查找干掉了整条 KUBE-SERVICES 链,顺便把 sidecar 也一起埋了。
eBPF 在内核里做决策,io_uring 在内核里做 I/O。当这两个东西连起来,你的数据包从网卡到应用可以完全不经过传统协议栈。
你有火焰图,但它只能告诉你 CPU 在忙什么——CPU 不忙的时候呢?从 perf 到 Parca,Linux 性能分析工具链走过了 15 年,是时候搞清楚每个工具的真正定位了。
Seccomp 只能说 yes or no,但攻击者早就学会了在 yes 里面做文章。是时候让 eBPF 接管安全审计了。
当 DDoS 洪水来袭,iptables 在协议栈里挣扎,而 XDP 在网卡驱动层就把垃圾包丢了。不进协议栈、不分配 skb、不走 netfilter——这才是丢包该有的样子。
用 C 和 Go 从零实现一个 OCI 兼容的迷你容器运行时,逐篇拆解 Linux 内核的隔离机制。不是讲 Docker 怎么用,而是理解容器到底是什么。
探索 Linux 下一代高性能异步 I/O 接口 io_uring,从核心原理到性能对比,再到与现有网络库的集成。
Linux 内核 ACCESS_ONCE/READ_ONCE/WRITE_ONCE 宏详解:并发编程与内存访问
从 eBPF 基础到 XDP 防火墙、安全监控、容器网络、性能分析——eBPF 在现代 Linux 的完整应用图谱。
Linux 文件 I/O 深度解析:内核文件表、系统调用与文件描述符管理
SQPOLL 烧 CPU、fixed buffer 内存泄漏、CQE overflow 丢事件、内核版本兼容性噩梦——io_uring 在生产中踩过的坑,逐个拆解。
正确的无锁数据结构可以写出来。但代价比你想象的大。CAS 循环、ABA 问题、内存回收、x86 和 ARM 的行为差异——这篇从一行 compare_exchange 开始,到一个完整的无锁哈希表结束。
拆解 GitHub 高星'无锁'库的真实面目:隐藏的 mutex、被滥用的 memory_order_relaxed、以及 CAS 重试循环的阻塞本质。附 x86 vs ARM 上的行为差异实测。
一个在 x86 上跑了两年的内核模块,迁移到 ARM 后开始随机丢数据。三天的调试过程教会了我 smp_wmb() 的真正含义。附 Linux 内核屏障 API 完整分类与 x86/ARM 编译产物对比。
Linux 高并发服务器内核参数调优:文件描述符、TCP 网络栈与 core dump 配置
Linux 进程调度详解:调度类、优先级与实时任务调度机制
Linux 进程状态详解:运行、睡眠、僵尸等 7 种进程状态分析
sendfile/splice/io_uring 的 zero-copy 路径深度解析与实测。揭示小数据包场景下传统 copy 因 cache locality 反而更快的反直觉真相。
分配器的 micro-benchmark 全是骗人的。真正的差距在碎片率和尾延迟。我们把四个分配器塞进一个真实的 HTTP 服务器,跑 24 小时,看谁先崩。
Linux Daemon 进程创建指南:后台服务开发规范与最佳实践
程序内存布局详解:虚拟内存、栈、堆、代码段、数据段的组织结构