rcu: Make rcu_read_unlock_special() propagate ->qsmaskinit bit clearing
This commit causes rcu_read_unlock_special() to propagate ->qsmaskinit bit clearing up the rcu_node tree once a given rcu_node structure's blkd_tasks list becomes empty. This is the final commit in preparation for the rework of RCU priority boosting: It enables preempted tasks to remain queued on their rcu_node structure even after all of that rcu_node structure's CPUs have gone offline. Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
This commit is contained in:
Родитель
8af3a5e78c
Коммит
b6a932d1d9
|
@ -2329,6 +2329,10 @@ static void rcu_cleanup_dying_cpu(struct rcu_state *rsp)
|
|||
{
|
||||
}
|
||||
|
||||
static void __maybe_unused rcu_cleanup_dead_rnp(struct rcu_node *rnp_leaf)
|
||||
{
|
||||
}
|
||||
|
||||
static void rcu_cleanup_dead_cpu(int cpu, struct rcu_state *rsp)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -322,9 +322,10 @@ static bool rcu_preempt_has_tasks(struct rcu_node *rnp)
|
|||
*/
|
||||
void rcu_read_unlock_special(struct task_struct *t)
|
||||
{
|
||||
int empty_exp;
|
||||
int empty_norm;
|
||||
int empty_exp_now;
|
||||
bool empty;
|
||||
bool empty_exp;
|
||||
bool empty_norm;
|
||||
bool empty_exp_now;
|
||||
unsigned long flags;
|
||||
struct list_head *np;
|
||||
#ifdef CONFIG_RCU_BOOST
|
||||
|
@ -376,6 +377,7 @@ void rcu_read_unlock_special(struct task_struct *t)
|
|||
break;
|
||||
raw_spin_unlock(&rnp->lock); /* irqs remain disabled. */
|
||||
}
|
||||
empty = !rcu_preempt_has_tasks(rnp);
|
||||
empty_norm = !rcu_preempt_blocked_readers_cgp(rnp);
|
||||
empty_exp = !rcu_preempted_readers_exp(rnp);
|
||||
smp_mb(); /* ensure expedited fastpath sees end of RCU c-s. */
|
||||
|
@ -395,6 +397,14 @@ void rcu_read_unlock_special(struct task_struct *t)
|
|||
drop_boost_mutex = rt_mutex_owner(&rnp->boost_mtx) == t;
|
||||
#endif /* #ifdef CONFIG_RCU_BOOST */
|
||||
|
||||
/*
|
||||
* If this was the last task on the list, go see if we
|
||||
* need to propagate ->qsmaskinit bit clearing up the
|
||||
* rcu_node tree.
|
||||
*/
|
||||
if (!empty && !rcu_preempt_has_tasks(rnp))
|
||||
rcu_cleanup_dead_rnp(rnp);
|
||||
|
||||
/*
|
||||
* If this was the last task on the current list, and if
|
||||
* we aren't waiting on any CPUs, report the quiescent state.
|
||||
|
|
Загрузка…
Ссылка в новой задаче