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.

D.3. HIERARCHICAL RCU CODE WALKTHROUGH 2131 #define RCU_DATA_PTR_INIT(rsp, rcu_data) \2 do { \3 rnp = (rsp)->level[NUM_RCU_LVLS - 1]; \4 j = 0; \5 for_each_possible_cpu(i) { \6 if (i > rnp[j].grphi) \7 j++; \8 per_cpu(rcu_data, i).mynode = &rnp[j]; \9 (rsp)->rda[i] = &per_cpu(rcu_data, i); \10 } \11 } while (0)1213 void __init __rcu_init(void)14 {15 int i;16 int j;17 struct rcu_node *rnp;1819 rcu_init_one(&rcu_state);20 RCU_DATA_PTR_INIT(&rcu_state, rcu_data);21 rcu_init_one(&rcu_bh_state);22 RCU_DATA_PTR_INIT(&rcu_bh_state, rcu_bh_data);2324 for_each_online_cpu(i)25 rcu_cpu_notify(&rcu_nb, CPU_UP_PREPARE,26 (void *)(long)i);27 register_cpu_notifier(&rcu_nb);28 }Figure D.29: rcu init() CodeLines 28-31 initialize these same fields for the restof the rcu_node structures in the hierarchy. Line 28computes the ->grpnum field as the index of thisrcu_node structure within the set having the sameparent, and line 29 sets the corresponding bit in the->grpmaskfield. Finally, lines30-31placesapointerto the parent node into the ->parent field. Thesethree fields will used to propagate quiescent statesup the hierarchy.Finally, line 33 records the hierarchy level in ->level, which is used for tracing when traversing thefull hierarchy.D.3.3.3rcu init()Figure D.29 shows the __rcu_init() function andits RCU_DATA_PTR_INIT() helper macro. The __rcu_init() function is invoked during early boot,before the scheduler has initialized, and before morethan one CPU is running.The RCU_DATA_PTR_INIT() macro takes as argumentsa pointer to an rcu_state structure andthe name of a set of rcu_data per-CPU variables.This macro scans the per-CPU rcu_datastructures, assigning the ->mynode pointer of eachrcu_data structure to point to the correspondingleaf rcu_node structure. <strong>It</strong> also fills out the specifiedrcu_state structure’s ->rda[] array entries toeach point to the corresponding rcu_data structure.Line 3 picks up a pointer to the first leaf rcu_nodestructure in local variable rnp (which must be declaredby the invoker of this macro), and line 4 setslocal variable j to the corresponding leaf-node numberof zero. Each pass through the loop spanninglines 5-10 performs initialization for the correspondingpotentialCPU(asspecifiedbyNR_CPUS).Withinthis loop, line 6 checks to see if we have moved beyondthe bounds of the current leaf rcu_node structure,and, ifso, line7advancestothenextstructure.Then, still within the loop, line 8 sets the ->mynodepointer of the current CPU’s rcu_data structureto reference the current leaf rcu_node structure,and line 9 sets the current CPU’s ->rda[] element(within the rcu_state structure) to reference thecurrent CPU’s rcu_data structure.Quick Quiz D.34: C-preprocessor macros are so1990s! Why not get with the times and convertRCU_DATA_PTR_INIT() in Figure D.29 to be a function?The __rcu_init() function first invokes rcu_init_one() on the rcu_state structure on line 19,then invokes RCU_DATA_PTR_INIT() on the rcu_state structure and the rcu_data set of per-CPUvariables. <strong>It</strong> then repeats this for rcu_bh_stateand rcu_bh_data on lines 21-22. The loop spanninglines 24-26 invokes rcu_cpu_notify() for eachCPU that is currently online (which should be onlythe boot CPU), and line 27 registers a notifier sothat rcu_cpu_notify() will be invoked each timea CPU comes online, in order to inform RCU of itspresence.Quick Quiz D.35: <strong>What</strong> happens if a CPUcomes online between the time that the last onlineCPUisnotifiedonlines25-26ofFigureD.29andthetime that register_cpu_notifier() is invoked online 27?The rcu_cpu_notify() and related functions arediscussed in Section D.3.4 below.D.3.4 CPU HotplugThe CPU-hotplug functions described in the followingsections allow RCU to track which CPUs are andare not present, but also complete initialization ofeach CPU’s rcu_data structure as that CPU comesonline.D.3.4.1 rcu init percpu data()Figure D.30 shows the code for rcu_init_percpu_data(), which initializes the specified CPU’s rcu_data structure in response to booting up or to thatCPU coming online. <strong>It</strong> also sets up the rcu_nodehierarchy so that this CPU will participate in futuregrace periods.

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

Saved successfully!

Ooh no, something went wrong!