rcu_gp_kthread 会注册新的grace period,开始新的grace period。 Grace Period完成 Quiescent Period完成,内核线程rcu_gp_kthread被唤醒后,执行:rcu_gp_cleanup(); 标记rcu_state上gp完成:rcu_seq_end(&new_gp_seq); 更新每个rcu_node上的gp_seq为完成状态:WRITE_ONCE(rnp->gp_seq, new_gp_seq); 进入ID...
既然涉及到宽限期GP的操作,都放到了rcu_gp_kthread内核线程中了,那么来看看这个内核线程的逻辑操作吧: 内核分别为rcu_preempt_state, rcu_bh_state, rcu_sched_state创建了内核线程rcu_gp_kthread; rcu_gp_kthread内核线程主要完成三个工作:1)创建新的宽限期GP;2)等待强制静止状态,设置超时,提前唤醒说明所有...
2. 在RT-Linux中并未使用软中断,而是为每个CPU都注册了一个rcu_cpu_kthread线程作为替代。 GP内核线程: 这里所谓的gp线程即rcu_gp_kthread(),主要功能是处理宽限期相关的事务,包括:开启新的宽限期、处理forcing QS、清理已结束的宽限期。 此线程的名字保存在rcu_state->name中,可抢占RCU命名是rcu_preempt;...
内核分别为rcu_preempt_state, rcu_bh_state, rcu_sched_state创建了内核线程rcu_gp_kthread; rcu_gp_kthread内核线程主要完成三个工作:1)创建新的宽限期GP;2)等待强制静止状态,设置超时,提前唤醒说明所有处理器经过了静止状态;3)宽限期结束处理。其中,前边两个操作都是通过睡眠等待在某个条件上。 7. 静止状...
static void rcu_check_gp_kthread_starvation(void) { struct task_struct *gpk = rcu_state.gp_kthread; unsigned long j; if (rcu_is_gp_kthread_starving(&j)) { pr_err("%s kthread starved for %ld jiffies! g%ld f%#x %s(%d) ->state=%#lx ->cpu=%d\n", ...
关键点来了:Tree RCU使用rcu_node节点来构造层级结构,进而管理静止状态Quiescent State和宽限期Grace Period,静止状态信息QS是从每个CPU的rcu_data往上传递到根节点的,而宽限期GP信息是通过根节点从上往下传递的,当每个CPU经历过一次QS状态后,宽限期结束 ...
1.2每个CPU度过quiescnet state 接下来我们看每个CPU上报完成抢占的过程。kernel把这个完成抢占的状态称为quiescent state。每个CPU在时钟中断的处理函数中,都会判断当前CPU是否度过quiescent state。 void update_process_times(int user_tick) { ... rcu_
(unsigned long mask, struct rcu_state *rsp, struct rcu_node *rnp, unsigned long gpseq, unsigned long flags) { raw_spin_lock_irqsave_rcu_node(rnp, flags); rnp->qsmask &= ~mask; // 如果所有CPU都报告了静止状态,则唤醒宽限期线程 if (!rnp->qsmask) rcu_gp_kthread_wake(...
从上文1.3节宽限期的结束处理过程我们可以知道,rcu_gp_kthread会判断! (rnp->qsmask) && !rcu_preempt_blocked_readers_cgp(rnp))两个条件来决定GP是否完成,其中!rnp->qsmask代表每个CPU都经过一次quiescent state,quiescent state的定义与传统RCU一致;!rcu_preempt_blocked_readers_cgp(rnp)这个条件就代表了rcu...
这发生在每个CPU的rcu_cpu_kthread中,其中内核线程rcu_gp_kthread仅更新了rcu_node的gp_seq,未直接触发回调执行。rcu_cpu_kthread在检查函数rcu_check_quiescent_state中确认Grace Period已完成,通过内部检查判断当前gp序列是否已完成,若已完成,则将所有callback移动到RCU_DONE_TAIL列表上,后续在rcu...