** 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
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 ...