rcu_read_lock() / rcu_read_unlock():用于进入和离开RCU读取段,保证了在这两个函数调用内的读取不会看到中间状态的数据。 synchronize_rcu():等待一个RCU宽限期的结束,确保之前的所有RCU读者都已经完成。 call_rcu():将一个回调函数传递给RCU,该函数会在RCU宽限期之后被调用,用于释放老的数据结构。 kfree_...
读者在访问被RCU保护的共享数据期间不能被阻塞,这是RCU机制得以实现的一个基本前提,也就说当读者在引用被RCU保护的共享数据期间,读者所在的CPU不能发生上下文切换,spinlock和rwlock都需要这样的前提。写者在访问被RCU保护的共享数据时不需要和读者竞争任何锁,只有在有多于一个写者的情况下需要获得某种锁以与其他写者...
如上图所示,操作系统启动将rcu_ctrlblk、rcu_state以及各个cpu的rcu_data进行初始化(对应于t0时刻)。接下来各个cpu可以读取RCU锁保护的相关资源,t1时刻cpu2调用call_rcu函数使得cpu2的rcu_data的nxt_list不为空(图中假定指向A)。后面cpu2再次触发时钟中断,调用函数rcu_pending函数判断是否需要RCU相关处理,相关函数...
实时RCU可以通过用call_rcu()替换synchronize_rcu()来避免此问题,或者采用RCU优先级提升来避免。 除了那些“玩具”RCU实现,RCU优雅周期可能会延续好几个毫秒。这使得RCU更适于使用在读数据占多数的情景。 将读写锁转换成RCU非常简单,如下: 1.2 RCU是一种受限制的引用计数机制 因为优雅周期不能在RCU读端临界区进行...
图10.4RCU机制的函数接口 关于写者函数,主要就是call_rcu和call_rcu_bh两个函数。其中call_rcu能实现的功能是它不会使写者阻塞,因而它可在中断上下文及软中断使用,该函数将函数func挂接到RCU的回调函数链表上,然后立即返回,读者函数中提及的synchronize_rcu()函数在实现时也调用了该函数。而call_rcu_bh函数实现的...
(3)call_rcu。当然,某些情况下(例如在softirq context中),writer无法阻塞,这时候可以调用call_rcu接口函数,该函数仅仅是注册了callback就直接返回了,在适当的时机会调用callback函数,完成reclaimation的操作。这样的场景其实是分开removal和reclaimation的操作在两个不同的线程中:updater和reclaimer。
Updater使用synchronize_rcu或call_rcu来启动Reclaimer,对旧的临界资源进行回收,其中synchronize_rcu表示同步...
4. call_rcu()函数:用于延迟释放某些资源或对象的场景,通过调用该函数将某个对象注册到RCU回收队列中...
另外在Linux源码中关于call_rcu_bh函数的注释中还明确说明了如果当前的进程是在中断上下文中,则需要执行rcu_read_lock()和rcu_read_unlock(),结合这两个函数的实现实质表明它实际上禁止或使能内核的抢占调度,原因不言而喻,避免当前进程在执行读写过程中被其它进程抢占。同时内核注释还表明call_rcu_bh这个接口函数的...
在释放老指针方面,Linux内核提供两种方法供使用者使用,一个是调用call_rcu,另一个是调用synchronize_rcu。前者是一种异步 方式,call_rcu会将释放老指针的回调函数放入一个结点中,然后将该结点加入到当前正在运行call_rcu的处理器的本地链表中,在时钟中断的 softirq部分(RCU_SOFTIRQ), rcu软中断处理函数rcu_process_...