rk3588/kernel-6.1 IPC 架构与实现原理分析
1. IPC 子系统用途概览
ipc/ 目录实现 Linux 内核中的进程间通信核心能力,主要包括:
- System V IPC
- 消息队列(
msg.c) - 信号量(
sem.c) - 共享内存(
shm.c)
- 消息队列(
- POSIX Message Queue
- 消息队列文件系统与系统调用(
mqueue.c)
- 消息队列文件系统与系统调用(
- IPC 命名空间
- 隔离不同容器/命名空间的 IPC 对象(
namespace.c)
- 隔离不同容器/命名空间的 IPC 对象(
- 通用框架
- IPC ID 分配、权限、生命周期与并发模型(
util.c/.h)
- IPC ID 分配、权限、生命周期与并发模型(
简化理解:ipc/ 是“对象管理层 + 同步/消息语义层 + namespace 隔离层”的组合。
2. 编译与配置入口
2.1 Kconfig
位于 init/Kconfig 的关键项:
SYSVIPC:启用 SysV IPCPOSIX_MQUEUE:启用 POSIX 消息队列(依赖NET)IPC_NS:启用 IPC namespace(依赖SYSVIPC || POSIX_MQUEUE)SYSVIPC_SYSCTL、POSIX_MQUEUE_SYSCTL:对应 sysctl 配置接口
2.2 Makefile
ipc/Makefile 体现模块分层:
obj-$(CONFIG_SYSVIPC):util.o msgutil.o msg.o sem.o shm.o syscall.oobj-$(CONFIG_POSIX_MQUEUE):mqueue.o msgutil.oobj-$(CONFIG_IPC_NS):namespace.oobj-$(CONFIG_*_SYSCTL):sysctl 参数支持
3. 总体架构分层
可分为四层:
系统调用入口层
- 现代路径:
msgget/msgsnd/msgrcv、semget/semtimedop/semctl、shmget/shmat/shmdt/shmctl、mq_* - 兼容路径:
ipc/syscall.c中sys_ipc复用旧多路复用接口
- 现代路径:
通用对象管理层(SysV 共用)
ipc_ids+idr+rhashtable管理对象 ID 与 key 查找ipc_addid/ipc_rmid/ipcget/ipcperms提供统一创建/查找/鉴权逻辑ipc_ops{getnew, associate, more_checks}抽象msg/sem/shm的差异
机制实现层
msg.c:消息队列收发/阻塞唤醒sem.c:信号量集合、原子 semop、undo 机制shm.c:共享内存段创建、映射、拆映射mqueue.c:POSIX mqueue 的 VFS 化实现
隔离与可观测层
namespace.c:IPC namespace 创建、切换、销毁ipc_sysctl.c/mq_sysctl.c:运行时参数调优/proc/sysvipc/*:对象状态观测
4. 通用实现原理(SysV IPC 核心骨架)
4.1 对象标识设计
util.h 中 ID 由 index + sequence 组成:
- 用
ipcid_to_idx()取索引 - 用
ipcid_to_seqx()校验序号 - 防止“ID 被回收后复用”导致陈旧句柄误命中
4.2 ipcget() 统一建/取流程
msgget/semget/shmget 都走类似流程:
- 构造
ipc_ops(getnew/associate/more_checks) - 通过 key 在
ipc_ids查找对象 - 找不到且允许创建时,调用
getnew()分配对象 - 执行 LSM 安全检查与权限校验
这让三类 SysV IPC 在入口逻辑一致,语义差异下沉到各自文件。
4.3 并发与锁模型
util.c 顶部注释给出关键模型:
ids->rwsem:保护 IPC 集合(创建/删除/遍历)kern_ipc_perm.lock:保护单个 IPC 对象状态RCU:支持 lockless 查找和并发删除期间安全访问
总体思想:集合级 rwsem + 对象级 spinlock + RCU 生命周期。
5. 三大 SysV IPC 机制
5.1 消息队列(msg.c)
用途
- 进程间按消息粒度交换数据,支持类型匹配(
msgtyp)。
核心调用链
- 创建:
msgget->ksys_msgget->ipcget(..., newque, ...) - 发送:
msgsnd->ksys_msgsnd->do_msgsnd - 接收:
msgrcv->ksys_msgrcv->do_msgrcv - 控制:
msgctl(IPC_SET/IPC_RMID/IPC_STAT等)
实现要点
- 队列满时,发送方进入等待队列;
IPC_NOWAIT下直接-EAGAIN - 接收方按
msgtyp策略筛选(SEARCH_ANY/EQUAL/LESSEQUAL/...) - 支持“管线化发送/接收”(
pipelined_send),减少中间排队开销 - 删除队列时
freeque()负责唤醒阻塞 sender/receiver 并回收消息
5.2 信号量(sem.c)
用途
- 对共享资源做计数同步与互斥控制。
核心调用链
- 创建:
semget->ksys_semget->ipcget(..., newary, ...) - 操作:
semop/semtimedop->do_semtimedop->__do_semtimedop - 控制:
semctl->semctl_main
实现要点
newary()创建的是 信号量集合(nsems个)perform_atomic_semop()保证一个sembuf[]批操作的原子语义SEM_UNDO记录进程级 undo,进程异常退出可回滚影响- 不可满足操作条件时可阻塞等待,超时/信号打断返回对应错误
5.3 共享内存(shm.c)
用途
- 多进程共享一段虚拟内存,适合大数据低拷贝通信。
核心调用链
- 创建:
shmget->ksys_shmget->ipcget(..., newseg, ...) - 挂接:
shmat->do_shmat - 脱离:
shmdt->ksys_shmdt - 控制:
shmctl->shmctl_down
实现要点
newseg()基于shmem或hugetlb创建后端文件对象do_shmat()完成权限检查、地址对齐策略、do_mmap映射shmdt会处理被mremap/munmap改写后的复杂 VMA 拆卸场景- 通过
shm_nattch、shm_may_destroy管理段生命周期
6. POSIX 消息队列(mqueue.c)
6.1 用途与模型
- 提供
mq_open/mq_timedsend/mq_timedreceive/mq_notify等 POSIX API。 - 与 SysV msg 的差异:VFS 对象化 + 优先级消息 + 命名队列路径语义。
6.2 核心调用链
mq_open->do_mq_open(在当前 IPC namespace 的mq_mnt下查找/创建)mq_timedsend->do_mq_timedsendmq_timedreceive->do_mq_timedreceive
6.3 实现要点
- 队列底层是
mqueue文件系统 inode(mqueue_get_inode) - 发送/接收使用自旋锁 + 等待队列管理并发
- 支持 sender/receiver“直接管线化交付”,避免总是入队再出队
- 定时版本通过绝对超时参数实现可中断等待
7. IPC Namespace 实现原理(namespace.c)
7.1 创建
copy_ipcs(CLONE_NEWIPC)->create_ipc_ns()- 初始化
mq/msg/sem/shm各子系统与 sysctl - 将对象隔离到新的
ipc_namespace
7.2 销毁
put_ipc_ns()引用计数归零后异步释放free_ipc_ns()顺序清理sem/msg/shm/mqueue对象与 sysctl
7.3 意义
- 不同容器拥有独立 IPC 视图(ID 空间、对象集合、限制参数互不干扰)。
8. 安全与权限控制
IPC 路径中有三层权限约束:
- 经典权限位检查:
ipcperms() - 能力检查:如
CAP_SYS_RESOURCE、CAP_SYS_ADMIN - LSM Hook:
security_msg_* / security_sem_* / security_shm_*
因此 IPC 访问不仅受 uid/gid 控制,也受安全模块策略控制。
9. 调优与排障建议
对象创建失败(ENOSPC/ENOMEM)
- 检查
msgmni/msgmnb/msgmax、semmni/semmns、shm_ctl*限制 - 检查 namespace 下是否资源已耗尽
- 检查
阻塞超时或吞吐低
- 消息队列是否频繁满队列(sender 阻塞)
- semop 是否存在热点 semaphore 争用
- shm 方案是否更适合高吞吐场景
容器中 IPC 行为异常
- 确认是否在预期的 IPC namespace
- 检查容器 runtime 的
--ipc模式与挂载的 mqueuefs
兼容接口问题
- 关注
sys_ipc老接口与 compat 路径参数差异 - 注意
IPC_OLD/IPC_64结构体转换逻辑
- 关注
10. 一句话总结
ipc/ 的本质是:
以 util.c 提供统一对象管理与并发骨架,分别实现 msg/sem/shm 三类 SysV IPC 与 mqueue POSIX IPC,并通过 IPC namespace 提供容器级隔离。
正在加载留言…