** RFC not for inclusion ** Although this patch is against the -rt tree, it is also applicable to mainline after Paul's RCU preempt patches make it in. This patch adds RCU preemption boosting to RCU readers that were preempted (or sleep due to spin_locks in -rt). The approach I took is similar to priority inheritance. When a task does a synchronize_rcu, all sleeping RCU readers will inherit the priority of the caller. Any new RCU reader that schedules out will also boost its priority until the end of the grace period. The way this works is that there's a global rcu_boost_prio variable that keeps track of what the RCU readers that schedule out should boost their priority to. Along with that is a rcu_boost_dat structure per cpu that keeps its own copy of the rcu_boost_prio. When a RCU reader is preempted and schedules, it adds itself to a "toboost" link list in the local CPU rcu_boost_dat. If the rcu_boost_prio is lower (higher in priority) than the priority of the RCU reader that is about to sleep, the RCU reader will increase its priority to that of the rcu_boost_prio. The RCU reader will keep this priority until it releases the last of the RCU read locks that it held. At that time the RCU reader will lower its priority back to what it was originally. When a call is made to synchronize_rcu, if the rcu_boost_prio is higher than (lower in priority) the caller's priority, then the caller will set the rcu_boost_prio to its priority. An iteration is done to all the CPUs rcu_boost_dat. If there are any RCU readers already on the "boosted" link list a rcu_boost_dat they are moved back to the "toboost" list. Then each task is moved back to the the "boosted" list after it has its priority boosted to the new rcu_boost_prio. This is done until there are no more tasks on the "toboost" list. Each iteration releases all locks and reacquires them and checks to see if another task of higher priority didn't come in and start boosting them higher. If this happened, then the ...
