Skip to content

Commit caf4c86

Browse files
vianplrostedt
authored andcommitted
tracing/osnoise: Force quiescent states while tracing
At the moment running osnoise on a nohz_full CPU or uncontested FIFO priority and a PREEMPT_RCU kernel might have the side effect of extending grace periods too much. This will entice RCU to force a context switch on the wayward CPU to end the grace period, all while introducing unwarranted noise into the tracer. This behaviour is unavoidable as overly extending grace periods might exhaust the system's memory. This same exact problem is what extended quiescent states (EQS) were created for, conversely, rcu_momentary_dyntick_idle() emulates them by performing a zero duration EQS. So let's make use of it. In the common case rcu_momentary_dyntick_idle() is fairly inexpensive: atomically incrementing a local per-CPU counter and doing a store. So it shouldn't affect osnoise's measurements (which has a 1us granularity), so we'll call it unanimously. The uncommon case involve calling rcu_momentary_dyntick_idle() after having the osnoise process: - Receive an expedited quiescent state IPI with preemption disabled or during an RCU critical section. (activates rdp->cpu_no_qs.b.exp code-path). - Being preempted within in an RCU critical section and having the subsequent outermost rcu_read_unlock() called with interrupts disabled. (t->rcu_read_unlock_special.b.blocked code-path). Neither of those are possible at the moment, and are unlikely to be in the future given the osnoise's loop design. On top of this, the noise generated by the situations described above is unavoidable, and if not exposed by rcu_momentary_dyntick_idle() will be eventually seen in subsequent rcu_read_unlock() calls or schedule operations. Link: https://lkml.kernel.org/r/[email protected] Cc: [email protected] Fixes: bce29ac ("trace: Add osnoise tracer") Signed-off-by: Nicolas Saenz Julienne <[email protected]> Acked-by: Paul E. McKenney <[email protected]> Acked-by: Daniel Bristot de Oliveira <[email protected]> Signed-off-by: Steven Rostedt (Google) <[email protected]>
1 parent f0cfe17 commit caf4c86

File tree

1 file changed

+20
-0
lines changed

1 file changed

+20
-0
lines changed

kernel/trace/trace_osnoise.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1386,6 +1386,26 @@ static int run_osnoise(void)
13861386
osnoise_stop_tracing();
13871387
}
13881388

1389+
/*
1390+
* In some cases, notably when running on a nohz_full CPU with
1391+
* a stopped tick PREEMPT_RCU has no way to account for QSs.
1392+
* This will eventually cause unwarranted noise as PREEMPT_RCU
1393+
* will force preemption as the means of ending the current
1394+
* grace period. We avoid this problem by calling
1395+
* rcu_momentary_dyntick_idle(), which performs a zero duration
1396+
* EQS allowing PREEMPT_RCU to end the current grace period.
1397+
* This call shouldn't be wrapped inside an RCU critical
1398+
* section.
1399+
*
1400+
* Note that in non PREEMPT_RCU kernels QSs are handled through
1401+
* cond_resched()
1402+
*/
1403+
if (IS_ENABLED(CONFIG_PREEMPT_RCU)) {
1404+
local_irq_disable();
1405+
rcu_momentary_dyntick_idle();
1406+
local_irq_enable();
1407+
}
1408+
13891409
/*
13901410
* For the non-preemptive kernel config: let threads runs, if
13911411
* they so wish.

0 commit comments

Comments
 (0)