基于 Linux-5.10
一、不可抢占RCU
1. 不可抢占RCU不允许进程在读端临界区被其它进程抢占,使用函数 rcu_read_lock_sched()/rcu_read_unlock_sched() 标记读临界区。前者禁止内核抢占,后者开启内核抢占。
static inline void rcu_read_lock_sched(void) //include/linux/rcupdate.h { preempt_disable(); } static inline void rcu_read_unlock_sched(void) { preempt_enable(); }
2. 不可抢占RCU通过以下事件观察到静止状态
(1) 进程调度器调度进程。因为不可抢占RCU读临界区禁止内核抢占,所以进程调度器不会在读临界区调度进程,如果调度了进程,那么一定不在读临界区。
(2) 当前进程正在用户模式下运行。
(3) 处理器空闲,正在执行idle线程。
静态的观察位置1:
__schedule(bool preempt) //sched/core.c rcu_note_context_switch(preempt); //tree_plugin.h local_irq_disable()后调用,这个函数也要求必须要关中断调用 rcu_qs();
TODO
二、加速版不可抢占RCU
1. 加速版不可抢占RCU(RCU-bh)使用 rcu_read_lock_bh()/rcu_read_unlock_bh() 标记读端临界区,前者禁止软中断,后者开启软中断。
static inline void rcu_read_lock_bh(void) { local_bh_disable(); ... } static inline void rcu_read_unlock_bh(void) { ... local_bh_enable(); }
2. 加速版不可抢占RCU通过以下事件观察到静止状态:
(1) 执行完软中断。因为RCU-bh的读端临界区是禁止软中断的,所以进程在读端临界区是不会被软中断抢占。
(2) 当前进程在用户模式下运行。
(3) 处理器空闲,正在执行idle线程。
(4) 处理器没有执行软中断或禁止软中断的代码区域。
3. 检查静止状态的时机
(1) 执行完一轮软中断后,禁止硬中断之前,调用 rcu_qs() 记录静止状态:
irq_exit_rcu irq_exit __irq_exit_rcu invoke_softirq do_softirq_own_stack __do_softirq //softirq.c rcu_softirq_qs //tree.c rcu_qs //tree_plugin.h
(2) tick中断中会检查
update_process_times
TODO
标签:抢占,read,RCU,代码,bh,rcu,void From: https://www.cnblogs.com/hellokitty2/p/17360214.html