Skip to content

Commit 3d29aaf

Browse files
committed
rcu: Provide optional RCU-reader exit delay for strict GPs
The goal of this series is to increase the probability of tools like KASAN detecting that an RCU-protected pointer was used outside of its RCU read-side critical section. Thus far, the approach has been to make grace periods and callback processing happen faster. Another approach is to delay the pointer leaker. This commit therefore allows a delay to be applied to exit from RCU read-side critical sections. This slowdown is specified by a new rcutree.rcu_unlock_delay kernel boot parameter that specifies this delay in microseconds, defaulting to zero. Reported-by Jann Horn <jannh@google.com> Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
1 parent 4e025f5 commit 3d29aaf

2 files changed

Lines changed: 19 additions & 2 deletions

File tree

Documentation/admin-guide/kernel-parameters.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4152,6 +4152,15 @@
41524152
This wake_up() will be accompanied by a
41534153
WARN_ONCE() splat and an ftrace_dump().
41544154

4155+
rcutree.rcu_unlock_delay= [KNL]
4156+
In CONFIG_RCU_STRICT_GRACE_PERIOD=y kernels,
4157+
this specifies an rcu_read_unlock()-time delay
4158+
in microseconds. This defaults to zero.
4159+
Larger delays increase the probability of
4160+
catching RCU pointer leaks, that is, buggy use
4161+
of RCU-protected pointers after the relevant
4162+
rcu_read_unlock() has completed.
4163+
41554164
rcutree.sysrq_rcu= [KNL]
41564165
Commandeer a sysrq key to dump out Tree RCU's
41574166
rcu_node tree with an eye towards determining

kernel/rcu/tree_plugin.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,12 @@ static bool rcu_preempt_has_tasks(struct rcu_node *rnp)
430430
return !list_empty(&rnp->blkd_tasks);
431431
}
432432

433+
// Add delay to rcu_read_unlock() for strict grace periods.
434+
static int rcu_unlock_delay;
435+
#ifdef CONFIG_RCU_STRICT_GRACE_PERIOD
436+
module_param(rcu_unlock_delay, int, 0444);
437+
#endif
438+
433439
/*
434440
* Report deferred quiescent states. The deferral time can
435441
* be quite short, for example, in the case of the call from
@@ -460,10 +466,12 @@ rcu_preempt_deferred_qs_irqrestore(struct task_struct *t, unsigned long flags)
460466
}
461467
t->rcu_read_unlock_special.s = 0;
462468
if (special.b.need_qs) {
463-
if (IS_ENABLED(CONFIG_RCU_STRICT_GRACE_PERIOD))
469+
if (IS_ENABLED(CONFIG_RCU_STRICT_GRACE_PERIOD)) {
464470
rcu_report_qs_rdp(rdp->cpu, rdp);
465-
else
471+
udelay(rcu_unlock_delay);
472+
} else {
466473
rcu_qs();
474+
}
467475
}
468476

469477
/*

0 commit comments

Comments
 (0)