rcu-tasks: Make RCU Tasks Trace make use of RCU scheduler hooks
This commit makes the calls to rcu_tasks_qs() detect and report quiescent states for RCU tasks trace. If the task is in a quiescent state and if ->trc_reader_checked is not yet set, the task sets its own ->trc_reader_checked. This will cause the grace-period kthread to remove it from the holdout list if it still remains there. [ paulmck: Fix conditional compilation per kbuild test robot feedback. ] Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
This commit is contained in:
@@ -180,7 +180,7 @@ static int __noreturn rcu_tasks_kthread(void *arg)
|
||||
|
||||
/* Pick up any new callbacks. */
|
||||
raw_spin_lock_irqsave(&rtp->cbs_lock, flags);
|
||||
smp_mb__after_unlock_lock(); // Order updates vs. GP.
|
||||
smp_mb__after_spinlock(); // Order updates vs. GP.
|
||||
list = rtp->cbs_head;
|
||||
rtp->cbs_head = NULL;
|
||||
rtp->cbs_tail = &rtp->cbs_head;
|
||||
@@ -874,7 +874,7 @@ static void rcu_tasks_trace_pertask(struct task_struct *t,
|
||||
struct list_head *hop)
|
||||
{
|
||||
WRITE_ONCE(t->trc_reader_need_end, false);
|
||||
t->trc_reader_checked = false;
|
||||
WRITE_ONCE(t->trc_reader_checked, false);
|
||||
t->trc_ipi_to_cpu = -1;
|
||||
trc_wait_for_one_reader(t, hop);
|
||||
}
|
||||
@@ -983,6 +983,7 @@ static void rcu_tasks_trace_postgp(struct rcu_tasks *rtp)
|
||||
pr_err("\t%d holdouts\n", atomic_read(&trc_n_readers_need_end));
|
||||
}
|
||||
smp_mb(); // Caller's code must be ordered after wakeup.
|
||||
// Pairs with pretty much every ordering primitive.
|
||||
}
|
||||
|
||||
/* Report any needed quiescent state for this exiting task. */
|
||||
|
@@ -331,8 +331,7 @@ void rcu_note_context_switch(bool preempt)
|
||||
rcu_qs();
|
||||
if (rdp->exp_deferred_qs)
|
||||
rcu_report_exp_rdp(rdp);
|
||||
if (!preempt)
|
||||
rcu_tasks_qs(current);
|
||||
rcu_tasks_qs(current, preempt);
|
||||
trace_rcu_utilization(TPS("End context switch"));
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rcu_note_context_switch);
|
||||
@@ -841,8 +840,7 @@ void rcu_note_context_switch(bool preempt)
|
||||
this_cpu_write(rcu_data.rcu_urgent_qs, false);
|
||||
if (unlikely(raw_cpu_read(rcu_data.rcu_need_heavy_qs)))
|
||||
rcu_momentary_dyntick_idle();
|
||||
if (!preempt)
|
||||
rcu_tasks_qs(current);
|
||||
rcu_tasks_qs(current, preempt);
|
||||
out:
|
||||
trace_rcu_utilization(TPS("End context switch"));
|
||||
}
|
||||
|
Reference in New Issue
Block a user