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.

F.15. CHAPTER D: READ-COPY UPDATE IMPLEMENTATIONS 323later. There must therefore be some way to causethese readers to progress through their read-sidecritical sections in order to avoid such OOMs.Priority boosting is one way to force such progress,but only if readers are restricted to blocking suchthat they can be awakened via priority boosting.Of course, there are other methods besides priorityinheritance that handle the priority inversionproblem, including priority ceiling, preemption disabling,and so on. However, there are good reasonswhy priority inheritance is the approach used in theLinux kernel, so this is what is used for RCU.Quick Quiz D.57:Could the prohibition against using primitives thatwould block in a non-CONFIG_PREEMPT kernel belifted, and if so, under what conditions?Answer:<strong>If</strong> testing and benchmarking demonstrated thatthe preemptible RCU worked well enough thatclassic RCU could be dispensed with entirely, and ifpriority inheritance was implemented for blockingsynchronizationprimitivessuchassemaphores, thenthose primitives could be used in RCU read-sidecritical sections.Quick Quiz D.58:How is it possible for lines 38-43 of__rcu_advance_callbacks() to be executedwhen lines 7-37 have not? Won’t they both beexecuted just after a counter flip, and never at anyother time?Answer:Consider the following sequence of events:1. CPU 0 executes lines 5-12 of rcu_try_flip_idle().2. CPU 1 executes __rcu_advance_callbacks().Because rcu_ctrlblk.completed has been incremented,lines 7-37 execute. However, noneof the rcu_flip_flag variables have been set,so lines 38-43 do not execute.3. CPU 0 executes lines 13-15 of rcu_try_flip_idle().4. Later, CPU 1 again executes __rcu_advance_callbacks(). The counter has not been incrementedsince the earlier execution, but thercu_flip_flag variables have all been set, soonly lines 38-43 are executed.Quick Quiz D.59:<strong>What</strong> problems could arise if the lines containingACCESS_ONCE() in rcu_read_unlock() were reorderedby the compiler?Answer:1. <strong>If</strong> the ACCESS_ONCE() were omitted from thefetch of rcu_flipctr_idx (line 14), then thecompiler would be within its rights to eliminateidx. <strong>It</strong> would also be free to compile the rcu_flipctr decrement as a fetch-increment-storesequence, separatelyfetchingrcu_flipctr_idxfor both the fetch and the store. <strong>If</strong> an NMIwere to occur between the fetch and the store,andiftheNMIhandlercontainedanrcu_read_lock(), then the value of rcu_flipctr_idxwould change in the meantime, resulting in corruptionof the rcu_flipctr values, destroyingthe ability to correctly identify grace periods.2. Another failure that could result from omittingthe ACCESS_ONCE() from line 14 is due tothe compiler reordering this statement to followthe decrement of rcu_read_lock_nesting(line 16). In this case, if an NMI were to occurbetween these two statements, then anyrcu_read_lock() in the NMI handler couldcorrupt rcu_flipctr_idx, causing the wrongrcu_flipctr to be decremented. As with theanalogous situation in rcu_read_lock(), thiscould result in premature grace-period termination,an indefinite grace period, or even both.3. <strong>If</strong> ACCESS_ONCE() macros were omitted suchthat the update of rcu_read_lock_nestingcould be interchanged by the compiler with thedecrement of rcu_flipctr, and if an NMI occurredinbetween,anyrcu_read_lock() intheNMI handler would incorrectly conclude thatit was protected by an enclosing rcu_read_lock(), and fail to increment the rcu_flipctrvariables.<strong>It</strong>isnotclearthattheACCESS_ONCE()onthefetchof rcu_read_lock_nesting (line 7) is required.Quick Quiz D.60:<strong>What</strong> problems could arise if the lines containingACCESS_ONCE() in rcu_read_unlock() were reorderedby the CPU?

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

Saved successfully!

Ooh no, something went wrong!