预览加载中,请您耐心等待几秒...
1/6
2/6
3/6
4/6
5/6
6/6

在线预览结束,喜欢就下载吧,查找使用更方便

如果您无法下载资料,请参考说明:

1、部分资料下载需要金币,请确保您的账户上有足够的金币

2、已购买过的文档,再次下载不重复扣费

3、资料包下载后请先用软件解压,在使用对应软件打开

对linuxrcu机制的理解 RCU(Read-copyupdate)锁机制是kernel2.6的重大进步,使用rcu可以获得比使用rwlock更高的性能,而且代码简单,不易死锁。 Linux文档如下描述: SothetypicalRCUupdatesequencegoessomethinglikethefollowing: a. Removepointerstoadatastructure,sothatsubsequent readerscannotgainareferencetoit. b. WaitforallpreviousreaderstocompletetheirRCUread-side criticalsections. c. Atthispoint,therecannotbeanyreaderswhoholdreferences tothedatastructure,soitnowmaysafelybereclaimed (e.g.,kfree()d). 如上所述,RCU原理其实很简单,现在假设你自己要实现一个基于rcu原理的模型。 假定cpu处理报文的过程是原子的,这样可以认为处理完一个报文就经过了一个quiescentstate,RCU引用的过时数据就可以释放了。接收报文开始进入一个新的周期,当发送报文后,标记一个周期的结束。假设有8个cpu,轮流处理报文,而报文处理依赖的信息存储在共享内存中。 那末,现在的问题是:请用rcu机制实现共享内存的释放。假设所有的cpu处理一个报文结束,就代表一个graceperiod(因为只有处理报文时才会使用共享内存),即每个cpu都经过了一个quiscentstate. 那么现在就有三个问题: 如何确定所有的cpu都经过了一个quiscentstate? 在rcu处理时,如何保证别的cpu不对要释放的数据操作? 在rcu处理后,如何开启和判断下一个rcu周期? 带着这三个问题,我们可以看一下linux是如何实现rcu机制的。 以下的分析是基于linux-2.6.27代码: Rcu有两个重要的数据结构: /*Globalcontrolvariablesforrcupdatecallbackmechanism.*/ structrcu_ctrlblk{ long cur; /*Currentbatchnumber.*/ long completed; /*Numberofthelastcompletedbatch*/ int next_pending; /*Isthenextbatchalreadywaiting?*/ int signaled; spinlock_t lock ____cacheline_internodealigned_in_smp; cpumask_t cpumask;/*CPUsthatneedtoswitchinorder*/ /*forcurrentbatchtoproceed.*/ }____cacheline_internodealigned_in_smp; 上述结构是rcu全局控制结构 structrcu_data{ /*1)quiescentstatehandling:*/ long quiescbatch;/*Batch#forgraceperiod*/ int passed_quiesc; /*User-mode/idleloopetc.*/ int qs_pending; /*corewaitsforquiescstate*/ /*2)batchhandling*/ long batch;/*Batch#forcurrentRCUbatch*/ structrcu_head*nxtlist; structrcu_head**nxttail; longqlen; /*#ofqueuedcallbacks*/ structrcu_head*curlist; structrcu_head**curtail; structrcu_head*donelist; structrcu_head**donetail; long blimit; /*Upperlimitonaprocessedbatch*/ intcpu; structrcu_headbarrier; }; 上述结构是每个cpu用的rcu数据结构。 DECLARE_PER_CPU(structrcu_data,rcu_data); staticstructrcu_ctrlblkrcu_ctrlblk={ .cur=-300, .completed=-300, .lock=__