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.

E.7. PROMELA PARABLE: DYNTICKS AND PREEMPTABLE RCU 25714 return 1;15 }Lines 7 and 8 pick up current and snapshot versionsof dynticks_progress_counter, respectively.The memory barrier on line ensures that the counterchecks in the later rcu_try_flip_waitzero_statefollow the fetches of these counters. Lines 10 and11 return zero (meaning no communication with thespecified CPU is required) if that CPU has remainedin dynticks-idle state since the time that the snapshotwas taken. Similarly, lines 12 and 13 returnzero if that CPU was initially in dynticks-idle stateor if it has completely passed through a dynticks-idlestate. In both these cases, there is no way that thatCPU could have retained the old value of the graceperiodcounter. <strong>If</strong> neither of these conditions hold,line 14 returns one, meaning that the CPU needs toexplicitly respond.For its part, the rcu_try_flip_waitmb_statestate invokes rcu_try_flip_waitmb_needed(),shown below:1 static inline int2 rcu_try_flip_waitmb_needed(int cpu)3 {4 long curr;5 long snap;67 curr = per_cpu(dynticks_progress_counter, cpu);8 snap = per_cpu(rcu_dyntick_snapshot, cpu);9 smp_mb();10 if ((curr == snap) && ((curr & 0x1) == 0))11 return 0;12 if (curr != snap)13 return 0;14 return 1;15 }This is quite similar to rcu_try_flip_waitack_needed, the difference being in lines 12 and 13, becauseany transition either to or from dynticks-idlestate executes the memory barrier needed by thercu_try_flip_waitmb_state() state.We now have seen all the code involved in theinterface between RCU and the dynticks-idle state.The next section builds up the Promela model usedto verify this code.Quick Quiz E.9: <strong>Can</strong> you spot any bugs in anyof the code in this section?E.7.2 Validating Preemptable RCUand dynticksThis section develops a Promela model for the interfacebetween dynticks and RCU step by step, witheach of the following sections illustrating one step,starting with the process-level code, adding assertions,interrupts, and finally NM<strong>Is</strong>.E.7.2.1 Basic ModelThis section translates the process-level dynticks entry/exitcode and the grace-period processing intoPromela [Hol03]. We start with rcu_exit_nohz()and rcu_enter_nohz() from the 2.6.25-rc4 kernel,placing these in a single Promela process that modelsexiting and entering dynticks-idle mode in a loopas follows:1 proctype dyntick_nohz()2 {3 byte tmp;4 byte i = 0;56 do7 :: i >= MAX_DYNTICK_LOOP_NOHZ -> break;8 :: i < MAX_DYNTICK_LOOP_NOHZ ->9 tmp = dynticks_progress_counter;10 atomic {11 dynticks_progress_counter = tmp + 1;12 assert((dynticks_progress_counter & 1) == 1);13 }14 tmp = dynticks_progress_counter;15 atomic {16 dynticks_progress_counter = tmp + 1;17 assert((dynticks_progress_counter & 1) == 0);18 }19 i++;20 od;21 }Lines 6 and 20 define a loop. Line 7 exits theloop once the loop counter i has exceeded the limitMAX_DYNTICK_LOOP_NOHZ. Line 8 tells the loop constructto execute lines 9-19 for each pass throughthe loop. Because the conditionals on lines 7 and 8are exclusive of each other, the normal Promela randomselection of true conditions is disabled. Lines 9and 11 model rcu_exit_nohz()’s non-atomic incrementof dynticks_progress_counter, while line 12models the WARN_ON(). The atomic construct simplyreduces the Promela state space, given that theWARN_ON() is not strictly speaking part of the algorithm.Lines 14-18 similarly models the incrementand WARN_ON() for rcu_enter_nohz(). Finally,line 19 increments the loop counter.Each pass through the loop therefore models aCPU exiting dynticks-idle mode (for example, startingto execute a task), then re-entering dynticks-idlemode (for example, that same task blocking).Quick Quiz E.10: Whyisn’tthememorybarrierin rcu_exit_nohz() and rcu_enter_nohz() modeledin Promela?Quick Quiz E.11: <strong>Is</strong>n’t it a bit strange to modelrcu_exit_nohz() followed by rcu_enter_nohz()?Wouldn’t it be more natural to instead model entrybefore exit?The next step is to model the interfaceto RCU’s grace-period processing. For this,we need to model dyntick_save_progress_counter(), rcu_try_flip_waitack_needed(),

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

Saved successfully!

Ooh no, something went wrong!