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>
This commit is contained in:
parent
4e025f52a1
commit
3d29aaf1ef
@ -4152,6 +4152,15 @@
|
|||||||
This wake_up() will be accompanied by a
|
This wake_up() will be accompanied by a
|
||||||
WARN_ONCE() splat and an ftrace_dump().
|
WARN_ONCE() splat and an ftrace_dump().
|
||||||
|
|
||||||
|
rcutree.rcu_unlock_delay= [KNL]
|
||||||
|
In CONFIG_RCU_STRICT_GRACE_PERIOD=y kernels,
|
||||||
|
this specifies an rcu_read_unlock()-time delay
|
||||||
|
in microseconds. This defaults to zero.
|
||||||
|
Larger delays increase the probability of
|
||||||
|
catching RCU pointer leaks, that is, buggy use
|
||||||
|
of RCU-protected pointers after the relevant
|
||||||
|
rcu_read_unlock() has completed.
|
||||||
|
|
||||||
rcutree.sysrq_rcu= [KNL]
|
rcutree.sysrq_rcu= [KNL]
|
||||||
Commandeer a sysrq key to dump out Tree RCU's
|
Commandeer a sysrq key to dump out Tree RCU's
|
||||||
rcu_node tree with an eye towards determining
|
rcu_node tree with an eye towards determining
|
||||||
|
@ -430,6 +430,12 @@ static bool rcu_preempt_has_tasks(struct rcu_node *rnp)
|
|||||||
return !list_empty(&rnp->blkd_tasks);
|
return !list_empty(&rnp->blkd_tasks);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add delay to rcu_read_unlock() for strict grace periods.
|
||||||
|
static int rcu_unlock_delay;
|
||||||
|
#ifdef CONFIG_RCU_STRICT_GRACE_PERIOD
|
||||||
|
module_param(rcu_unlock_delay, int, 0444);
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Report deferred quiescent states. The deferral time can
|
* Report deferred quiescent states. The deferral time can
|
||||||
* be quite short, for example, in the case of the call from
|
* 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)
|
|||||||
}
|
}
|
||||||
t->rcu_read_unlock_special.s = 0;
|
t->rcu_read_unlock_special.s = 0;
|
||||||
if (special.b.need_qs) {
|
if (special.b.need_qs) {
|
||||||
if (IS_ENABLED(CONFIG_RCU_STRICT_GRACE_PERIOD))
|
if (IS_ENABLED(CONFIG_RCU_STRICT_GRACE_PERIOD)) {
|
||||||
rcu_report_qs_rdp(rdp->cpu, rdp);
|
rcu_report_qs_rdp(rdp->cpu, rdp);
|
||||||
else
|
udelay(rcu_unlock_delay);
|
||||||
|
} else {
|
||||||
rcu_qs();
|
rcu_qs();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user