10.07.2015 Views

Is Parallel Programming Hard, And, If So, What Can You Do About It?

Is Parallel Programming Hard, And, If So, What Can You Do About It?

Is Parallel Programming Hard, And, If So, What Can You Do About It?

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

196 APPENDIX D. READ-COPY UPDATE IMPLEMENTATION<strong>So</strong>nlyiftheaforementioneddyntickscounteriseven.In other words, NMI’s refrain from manipulating thedynticks_nmi counter if the NMI occurred in nondynticks-idlemode or within an interrupt handler.The only difference between these two functions istheerrorchecks,asrcu_nmi_enter()mustleavethedynticks_nmi counter with an odd value, and rcu_nmi_exit() must leave this counter with an evenvalue.D.2.7.7 Note That a CPU is in Dynticks IdleModeThe force_quiescent_state() function implementsa three-phase state machine. The first phase(RCU_INITIALIZING) waits for rcu_start_gp() tocomplete grace-period initialization. This stateis not exited by force_quiescent_state(), butrather by rcu_start_gp().In the second phase (RCU_SAVE_DYNTICK), thedyntick_save_progress_counter() functionscans the CPUs that have not yet reported aquiescent state, recording their per-CPU dynticksand dynticks_nmi counters. <strong>If</strong> these counters bothhave even-numbered values, then the correspondingCPU is in dynticks-idle state, which is thereforenoted as an extended quiescent state (reported viacpu_quiet_msk()).In the third phase (RCU_FORCE_QS), the rcu_implicit_dynticks_qs() function again scans theCPUs that have not yet reported a quiescent state(either explicitly or implicitly during the RCU_SAVE_DYNTICK phase), again checking the per-CPUdynticks and dynticks_nmi counters. <strong>If</strong> each ofthesehaseitherchangedinvalueorisnoweven, thenthe corresponding CPU has either passed through oris now in dynticks idle, which as before is noted asan extended quiescent state.<strong>If</strong> rcu_implicit_dynticks_qs() finds that agiven CPU has neither been in dynticks idle modenor reported a quiescent state, it invokes rcu_implicit_offline_qs(), whichcheckstoseeifthatCPU is offline, which is also reported as an extendedquiescent state. <strong>If</strong> the CPU is online, thenrcu_implicit_offline_qs() sends it a rescheduleIPI in an attempt to remind it of its duty to reporta quiescent state to RCU.Note that force_quiescent_state() does notdirectly invoke either dyntick_save_progress_counter() or rcu_implicit_dynticks_qs(), insteadpassing these functions to an intervening rcu_process_dyntick() function that abstracts out thecommon code involved in scanning the CPUs andreporting extended quiescent states.Quick Quiz D.13: <strong>And</strong> what happens if oneCPU comes out of dyntick-idle mode and thenpassed through a quiescent state just as anotherCPU notices that the first CPU was in dyntick-idlemode? Couldn’t they both attempt to report a quiescentstateatthesametime,resultinginconfusion?Quick Quiz D.14: But what if all the CPUs endup in dyntick-idle mode? Wouldn’t that prevent thecurrent RCU grace period from ever ending?Quick Quiz D.15: Given that force_quiescent_state() is a three-phase state machine,don’t we have triple the scheduling latency due toscanning all the CPUs?D.2.7.8 Offline a CPUCPU-offline events cause rcu_cpu_notify() to invokercu_offline_cpu(), which in turn invokes__rcu_offline_cpu() on both the rcu and thercu bh instances of the data structures. This functionclears the outgoing CPU’s bits so that futuregrace periods will not expect this CPU to announcequiescentstates, andfurtherinvokescpu_quiet()inorder to announce the offline-induced extended quiescentstate. This work is performed with the global->onofflock held in order to prevent interferencewith concurrent grace-period initialization.Quick Quiz D.16: But the other reason to hold->onofflock is to prevent multiple concurrent online/offlineoperations, right?D.2.7.9 Online a CPUCPU-online events cause rcu_cpu_notify() to invokercu_online_cpu(), which initializes the incomingCPU’s dynticks state, and then invokesrcu_init_percpu_data() to initialize the incomingCPU’s rcu_data structure, and also to setthis CPU’s bits (again protected by the global ->onofflock) so that future grace periods will waitfor a quiescent state from this CPU. Finally, rcu_online_cpu() sets up the RCU softirq vector forthis CPU.Quick Quiz D.17: Givenalltheseacquisitionsoftheglobal->onofflock, won’ttherebehorriblelockcontention when running with thousands of CPUs?Quick Quiz D.18: Why not simplify the codeby merging the detection of dyntick-idle CPUs withthat of offline CPUs?

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!