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

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

F.7. CHAPTER 8: DEFERRED PROCESSING 299<strong>What</strong> happens if you mix and match? For example,suppose you use rcu_read_lock() andrcu_read_unlock() to delimit RCU read-sidecritical sections, but then use call_rcu_bh() topost an RCU callback?Answer:<strong>If</strong> there happened to be no RCU read-side criticalsections delimited by rcu_read_lock_bh() andrcu_read_unlock_bh() at the timecall_rcu_bh()was invoked, RCU would be within its rights toinvoke the callback immediately, possibly freeing adata structure still being used by the RCU read-sidecritical section! This is not merely a theoreticalpossibility: a long-running RCU read-side criticalsection delimited by rcu_read_lock() andrcu_read_unlock() is vulnerable to this failuremode.This vulnerability disappears in -rt kernels, whereRCUClassicandRCUBHbothmapontoacommonimplementation.Quick Quiz 8.26:<strong>Hard</strong>ware interrupt handlers can be thoughtof as being under the protection of an implicitrcu_read_lock_bh(), right?Answer:Absolutely not!!! <strong>And</strong> especially not when usingpreemptable RCU! <strong>If</strong> you need to access“rcu bh”-protected data structures in an interrupthandler, you need to provide explicit calls torcu_read_lock_bh() and rcu_read_unlock_bh().Quick Quiz 8.27:<strong>What</strong> happens if you mix and match RCU Classicand RCU Sched?Answer:In a non-PREEMPT or a PREEMPT kernel, mixing thesetwo works ”by accident” because in those kernelbuilds, RCU Classic and RCU Sched map to thesame implementation. However, this mixture isfatal in PREEMPT_RT builds using the -rt patchset,due to the fact that Realtime RCU’s read-sidecritical sections can be preempted, which wouldpermit synchronize_sched() to return beforethe RCU read-side critical section reached itsrcu_read_unlock() call. This could in turn resultin a data structure being freed before the read-sidecritical section was finished with it, which could inturn greatly increase the actuarial risk experiencedby your kernel.In fact, the split between RCU Classic and RCUSched was inspired by the need for preemptible RCUread-side critical sections.Quick Quiz 8.28:In general, you cannot rely on synchronize_sched() to wait for all pre-existing interrupthandlers, right?Answer:That is correct! Because -rt Linux uses threadedinterrupt handlers, there can be context switchesin the middle of an interrupt handler. Becausesynchronize_sched() waits only until each CPUhas passed through a context switch, it can returnbefore a given interrupt handler completes.<strong>If</strong> you need to wait for a given interrupt handlerto complete, you should instead use synchronize_irq() or place explicit RCU read-side critical sectionsin the interrupt handlers that you wish to waiton.Quick Quiz 8.29:Why do both SRCU and QRCU lack asynchronouscall_srcu() or call_qrcu() interfaces?Answer:Given an asynchronous interface, a single task couldregister an arbitrarily large number of SRCU orQRCU callbacks, thereby consuming an arbitrarilylarge quantity of memory. In contrast, given thecurrent synchronous synchronize_srcu() andsynchronize_qrcu() interfaces, a given task mustfinish waiting for a given grace period before it canstart waiting for the next one.Quick Quiz 8.30:Under what conditions can synchronize_srcu()be safely used within an SRCU read-side criticalsection?Answer:In principle, you can use synchronize_srcu() witha given srcu_struct within an SRCU read-sidecritical section that uses some other srcu_struct.In practice, however, doing this is almost certainlya bad idea. In particular, the code shown inFigure F.6 could still result in deadlock.

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

Saved successfully!

Ooh no, something went wrong!