在 Linux 内核中,网络协议栈的实现高度复杂,其中 socket 作为用户态与内核态交互的核心对象,其生命周期管理尤为重要。本文将以 socket 销毁函数 __sk_destruct
为切入点,结合代码片段解析内核如何安全释放 socket 关联的资源,并重点探讨 sk_filter_uncharge
的作用及其背后的设计思想。
1. 背景:Socket 销毁与 RCU 机制
当用户关闭一个 socket 时,内核并不会立即释放其资源,而是通过 RCU(Read-Copy Update) 机制延迟销毁。RCU 是一种无锁同步机制,确保在释放内存时不会与其他正在访问该资源的线程发生冲突。对于标记了 SOCK_RCU_FREE
的 socket(如 UDP socket 和 TCP 监听 socket),内核会在一个 RCU 宽限期(Grace Period)后调用 __sk_destruct
函数完成最终的资源释放。
static void __sk_destruct(struct rcu_head *head) { struct sock *sk = container_of(head, struct sock, sk_rcu); // 资源释放逻辑 }