说明:
- Kernel版本:4.14
- ARM64处理器,Contex-A53,双核
- 使用工具:Source Insight 3.5, Visio
1. 概述
RCU, Read-Copy-Update,是Linux内核中的一种同步机制。RCU常被描述为读写锁的替代品,它的特点是读者并不需要直接与写者进行同步,读者与写者也能并发的执行。RCU的目标就是最大程度来减少读者侧的开销,因此也常用于对读者性能要求高的场景。
- 优点:
- 读者侧开销很少、不需要获取任何锁,不需要执行原子指令或者内存屏障;
- 没有死锁问题;
- 没有优先级反转的问题;
- 没有内存泄露的危险问题;
- 很好的实时延迟;
- 缺点:
- 写者的同步开销比较大,写者之间需要互斥处理;
- 使用上比其他同步机制复杂;
来一张图片来描述下大体的操作吧:

- 多个读者可以并发访问临界资源,同时使用rcu_read_lock/rcu_read_unlock来标定临界区;
- 写者(updater)在更新临界资源的时候,拷贝一份副本作为基础进行修改,当所有读者离开临界区后,把指向旧临界资源的指针指向更新后的副本,并对旧资源进行回收处理;
- 图中只显示一个写者,当存在多个写者的时候,需要在写者之间进行互斥处理;
上述的描述比较简单,RCU的实现很复杂。本文先对RCU来一个初印象,并结合接口进行实例分析,后续文章再逐层深入到背后的实现原理。开始吧!
资料直通车:Linux内核源码技术学习路线+视频教程内核源码
2. RCU基础
2.1 RCU基本要素
RCU的基本思想是将更新Update操作分为两个部分:1)Removal移除;2)Reclamation回收。直白点来理解就是,临界资源被多个读者读取,写者在拷贝副本修改后进行更新时,第一步需要先把旧的临界资源数据移除(修改指针指向),第二步需要把旧的数据进行回收(比如kfree)。
因此,从功能上分为以下三个基本的要素:Reader/Updater/Reclaimer,三者之间的交互如下图:

- Reader
- 使用rcu_read_lock和rcu_read_unlock来界定读者的临界区,访问受RCU保护的数据时,需要始终在该临界区域内访问;
- 在访问受保护的数据之前,需要使用rcu_dereference来获取RCU-protected指针;
- 当使用不可抢占的RCU时,rcu_read_lock/rcu_read_unlock之间不能使用可以睡眠的代码;
- Updater
- 多个Updater更新数据时,需要使用互斥机制进行保护;
- Updater使用rcu_assign_pointer来移除旧的指针指向,指向更新后的临界资源;
- Updater使用synchronize_rcu或call_rcu来启动Reclaimer,对旧的临界资源进行回收,其中synchronize_rcu表示同步等待回收,call_rcu表示异步回收;
- Reclaimer
- Reclaimer回收的是旧的临界资源;
- 为了确保没有读者正在访问要回收的临界资源,Reclaimer需要等待所有的读者退出临界区,这个等待的时间叫做宽限期(Grace Period);
2.2 RCU三个基本机制
用来提供上述描述的功能,RCU基于三种机制来实现。
2.2.1Publish-Subscribe Mechanism
订阅机制是个什么概念,来张图:

初窥门径&spm=1001.2101.3001.5002&articleId=128345600&d=1&t=3&u=291ff174944f46f9b261e37f2d3394fc)
4052

被折叠的 条评论
为什么被折叠?



