Skip to content

Commit 7fbe67e

Browse files
committed
Merge branch 'strictgp.2020.08.24a' into HEAD
strictgp.2020.08.24a: Strict grace periods for KASAN testing.
2 parents f511ce1 + cfeac39 commit 7fbe67e

File tree

7 files changed

+129
-16
lines changed

7 files changed

+129
-16
lines changed

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

include/linux/rcupdate.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,12 @@ void __rcu_read_unlock(void);
5555

5656
#else /* #ifdef CONFIG_PREEMPT_RCU */
5757

58+
#ifdef CONFIG_TINY_RCU
59+
#define rcu_read_unlock_strict() do { } while (0)
60+
#else
61+
void rcu_read_unlock_strict(void);
62+
#endif
63+
5864
static inline void __rcu_read_lock(void)
5965
{
6066
preempt_disable();
@@ -63,6 +69,7 @@ static inline void __rcu_read_lock(void)
6369
static inline void __rcu_read_unlock(void)
6470
{
6571
preempt_enable();
72+
rcu_read_unlock_strict();
6673
}
6774

6875
static inline int rcu_preempt_depth(void)

kernel/rcu/Kconfig

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -135,10 +135,12 @@ config RCU_FANOUT
135135

136136
config RCU_FANOUT_LEAF
137137
int "Tree-based hierarchical RCU leaf-level fanout value"
138-
range 2 64 if 64BIT
139-
range 2 32 if !64BIT
138+
range 2 64 if 64BIT && !RCU_STRICT_GRACE_PERIOD
139+
range 2 32 if !64BIT && !RCU_STRICT_GRACE_PERIOD
140+
range 2 3 if RCU_STRICT_GRACE_PERIOD
140141
depends on TREE_RCU && RCU_EXPERT
141-
default 16
142+
default 16 if !RCU_STRICT_GRACE_PERIOD
143+
default 2 if RCU_STRICT_GRACE_PERIOD
142144
help
143145
This option controls the leaf-level fanout of hierarchical
144146
implementations of RCU, and allows trading off cache misses

kernel/rcu/Kconfig.debug

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,4 +114,19 @@ config RCU_EQS_DEBUG
114114
Say N here if you need ultimate kernel/user switch latencies
115115
Say Y if you are unsure
116116

117+
config RCU_STRICT_GRACE_PERIOD
118+
bool "Provide debug RCU implementation with short grace periods"
119+
depends on DEBUG_KERNEL && RCU_EXPERT
120+
default n
121+
select PREEMPT_COUNT if PREEMPT=n
122+
help
123+
Select this option to build an RCU variant that is strict about
124+
grace periods, making them as short as it can. This limits
125+
scalability, destroys real-time response, degrades battery
126+
lifetime and kills performance. Don't try this on large
127+
machines, as in systems with more than about 10 or 20 CPUs.
128+
But in conjunction with tools like KASAN, it can be helpful
129+
when looking for certain types of RCU usage bugs, for example,
130+
too-short RCU read-side critical sections.
131+
117132
endmenu # "RCU Debugging"

kernel/rcu/tree.c

Lines changed: 62 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,12 @@ module_param(gp_init_delay, int, 0444);
165165
static int gp_cleanup_delay;
166166
module_param(gp_cleanup_delay, int, 0444);
167167

168+
// Add delay to rcu_read_unlock() for strict grace periods.
169+
static int rcu_unlock_delay;
170+
#ifdef CONFIG_RCU_STRICT_GRACE_PERIOD
171+
module_param(rcu_unlock_delay, int, 0444);
172+
#endif
173+
168174
/*
169175
* This rcu parameter is runtime-read-only. It reflects
170176
* a minimum allowed number of objects which can be cached
@@ -455,24 +461,25 @@ static int rcu_is_cpu_rrupt_from_idle(void)
455461
return __this_cpu_read(rcu_data.dynticks_nesting) == 0;
456462
}
457463

458-
#define DEFAULT_RCU_BLIMIT 10 /* Maximum callbacks per rcu_do_batch ... */
459-
#define DEFAULT_MAX_RCU_BLIMIT 10000 /* ... even during callback flood. */
464+
#define DEFAULT_RCU_BLIMIT (IS_ENABLED(CONFIG_RCU_STRICT_GRACE_PERIOD) ? 1000 : 10)
465+
// Maximum callbacks per rcu_do_batch ...
466+
#define DEFAULT_MAX_RCU_BLIMIT 10000 // ... even during callback flood.
460467
static long blimit = DEFAULT_RCU_BLIMIT;
461-
#define DEFAULT_RCU_QHIMARK 10000 /* If this many pending, ignore blimit. */
468+
#define DEFAULT_RCU_QHIMARK 10000 // If this many pending, ignore blimit.
462469
static long qhimark = DEFAULT_RCU_QHIMARK;
463-
#define DEFAULT_RCU_QLOMARK 100 /* Once only this many pending, use blimit. */
470+
#define DEFAULT_RCU_QLOMARK 100 // Once only this many pending, use blimit.
464471
static long qlowmark = DEFAULT_RCU_QLOMARK;
465472
#define DEFAULT_RCU_QOVLD_MULT 2
466473
#define DEFAULT_RCU_QOVLD (DEFAULT_RCU_QOVLD_MULT * DEFAULT_RCU_QHIMARK)
467-
static long qovld = DEFAULT_RCU_QOVLD; /* If this many pending, hammer QS. */
468-
static long qovld_calc = -1; /* No pre-initialization lock acquisitions! */
474+
static long qovld = DEFAULT_RCU_QOVLD; // If this many pending, hammer QS.
475+
static long qovld_calc = -1; // No pre-initialization lock acquisitions!
469476

470477
module_param(blimit, long, 0444);
471478
module_param(qhimark, long, 0444);
472479
module_param(qlowmark, long, 0444);
473480
module_param(qovld, long, 0444);
474481

475-
static ulong jiffies_till_first_fqs = ULONG_MAX;
482+
static ulong jiffies_till_first_fqs = IS_ENABLED(CONFIG_RCU_STRICT_GRACE_PERIOD) ? 0 : ULONG_MAX;
476483
static ulong jiffies_till_next_fqs = ULONG_MAX;
477484
static bool rcu_kick_kthreads;
478485
static int rcu_divisor = 7;
@@ -1571,6 +1578,19 @@ static void __maybe_unused rcu_advance_cbs_nowake(struct rcu_node *rnp,
15711578
raw_spin_unlock_rcu_node(rnp);
15721579
}
15731580

1581+
/*
1582+
* In CONFIG_RCU_STRICT_GRACE_PERIOD=y kernels, attempt to generate a
1583+
* quiescent state. This is intended to be invoked when the CPU notices
1584+
* a new grace period.
1585+
*/
1586+
static void rcu_strict_gp_check_qs(void)
1587+
{
1588+
if (IS_ENABLED(CONFIG_RCU_STRICT_GRACE_PERIOD)) {
1589+
rcu_read_lock();
1590+
rcu_read_unlock();
1591+
}
1592+
}
1593+
15741594
/*
15751595
* Update CPU-local rcu_data state to record the beginnings and ends of
15761596
* grace periods. The caller must hold the ->lock of the leaf rcu_node
@@ -1641,6 +1661,7 @@ static void note_gp_changes(struct rcu_data *rdp)
16411661
}
16421662
needwake = __note_gp_changes(rnp, rdp);
16431663
raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
1664+
rcu_strict_gp_check_qs();
16441665
if (needwake)
16451666
rcu_gp_kthread_wake();
16461667
}
@@ -1678,6 +1699,15 @@ static void rcu_gp_torture_wait(void)
16781699
}
16791700
}
16801701

1702+
/*
1703+
* Handler for on_each_cpu() to invoke the target CPU's RCU core
1704+
* processing.
1705+
*/
1706+
static void rcu_strict_gp_boundary(void *unused)
1707+
{
1708+
invoke_rcu_core();
1709+
}
1710+
16811711
/*
16821712
* Initialize a new grace period. Return false if no grace period required.
16831713
*/
@@ -1809,6 +1839,10 @@ static bool rcu_gp_init(void)
18091839
WRITE_ONCE(rcu_state.gp_activity, jiffies);
18101840
}
18111841

1842+
// If strict, make all CPUs aware of new grace period.
1843+
if (IS_ENABLED(CONFIG_RCU_STRICT_GRACE_PERIOD))
1844+
on_each_cpu(rcu_strict_gp_boundary, NULL, 0);
1845+
18121846
return true;
18131847
}
18141848

@@ -2025,6 +2059,10 @@ static void rcu_gp_cleanup(void)
20252059
rcu_state.gp_flags & RCU_GP_FLAG_INIT);
20262060
}
20272061
raw_spin_unlock_irq_rcu_node(rnp);
2062+
2063+
// If strict, make all CPUs aware of the end of the old grace period.
2064+
if (IS_ENABLED(CONFIG_RCU_STRICT_GRACE_PERIOD))
2065+
on_each_cpu(rcu_strict_gp_boundary, NULL, 0);
20282066
}
20292067

20302068
/*
@@ -2203,7 +2241,7 @@ rcu_report_unblock_qs_rnp(struct rcu_node *rnp, unsigned long flags)
22032241
* structure. This must be called from the specified CPU.
22042242
*/
22052243
static void
2206-
rcu_report_qs_rdp(int cpu, struct rcu_data *rdp)
2244+
rcu_report_qs_rdp(struct rcu_data *rdp)
22072245
{
22082246
unsigned long flags;
22092247
unsigned long mask;
@@ -2212,6 +2250,7 @@ rcu_report_qs_rdp(int cpu, struct rcu_data *rdp)
22122250
rcu_segcblist_is_offloaded(&rdp->cblist);
22132251
struct rcu_node *rnp;
22142252

2253+
WARN_ON_ONCE(rdp->cpu != smp_processor_id());
22152254
rnp = rdp->mynode;
22162255
raw_spin_lock_irqsave_rcu_node(rnp, flags);
22172256
if (rdp->cpu_no_qs.b.norm || rdp->gp_seq != rnp->gp_seq ||
@@ -2228,8 +2267,7 @@ rcu_report_qs_rdp(int cpu, struct rcu_data *rdp)
22282267
return;
22292268
}
22302269
mask = rdp->grpmask;
2231-
if (rdp->cpu == smp_processor_id())
2232-
rdp->core_needs_qs = false;
2270+
rdp->core_needs_qs = false;
22332271
if ((rnp->qsmask & mask) == 0) {
22342272
raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
22352273
} else {
@@ -2278,7 +2316,7 @@ rcu_check_quiescent_state(struct rcu_data *rdp)
22782316
* Tell RCU we are done (but rcu_report_qs_rdp() will be the
22792317
* judge of that).
22802318
*/
2281-
rcu_report_qs_rdp(rdp->cpu, rdp);
2319+
rcu_report_qs_rdp(rdp);
22822320
}
22832321

22842322
/*
@@ -2621,6 +2659,14 @@ void rcu_force_quiescent_state(void)
26212659
}
26222660
EXPORT_SYMBOL_GPL(rcu_force_quiescent_state);
26232661

2662+
// Workqueue handler for an RCU reader for kernels enforcing struct RCU
2663+
// grace periods.
2664+
static void strict_work_handler(struct work_struct *work)
2665+
{
2666+
rcu_read_lock();
2667+
rcu_read_unlock();
2668+
}
2669+
26242670
/* Perform RCU core processing work for the current CPU. */
26252671
static __latent_entropy void rcu_core(void)
26262672
{
@@ -2665,6 +2711,10 @@ static __latent_entropy void rcu_core(void)
26652711
/* Do any needed deferred wakeups of rcuo kthreads. */
26662712
do_nocb_deferred_wakeup(rdp);
26672713
trace_rcu_utilization(TPS("End RCU core"));
2714+
2715+
// If strict GPs, schedule an RCU reader in a clean environment.
2716+
if (IS_ENABLED(CONFIG_RCU_STRICT_GRACE_PERIOD))
2717+
queue_work_on(rdp->cpu, rcu_gp_wq, &rdp->strict_work);
26682718
}
26692719

26702720
static void rcu_core_si(struct softirq_action *h)
@@ -3862,6 +3912,7 @@ rcu_boot_init_percpu_data(int cpu)
38623912

38633913
/* Set up local state, ensuring consistent view of global state. */
38643914
rdp->grpmask = leaf_node_cpu_bit(rdp->mynode, cpu);
3915+
INIT_WORK(&rdp->strict_work, strict_work_handler);
38653916
WARN_ON_ONCE(rdp->dynticks_nesting != 1);
38663917
WARN_ON_ONCE(rcu_dynticks_in_eqs(rcu_dynticks_snap(rdp)));
38673918
rdp->rcu_ofl_gp_seq = rcu_state.gp_seq;

kernel/rcu/tree.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ struct rcu_data {
165165
/* period it is aware of. */
166166
struct irq_work defer_qs_iw; /* Obtain later scheduler attention. */
167167
bool defer_qs_iw_pending; /* Scheduler attention pending? */
168+
struct work_struct strict_work; /* Schedule readers for strict GPs. */
168169

169170
/* 2) batch handling */
170171
struct rcu_segcblist cblist; /* Segmented callback list, with */

kernel/rcu/tree_plugin.h

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ static void __init rcu_bootup_announce_oddness(void)
3636
pr_info("\tRCU dyntick-idle grace-period acceleration is enabled.\n");
3737
if (IS_ENABLED(CONFIG_PROVE_RCU))
3838
pr_info("\tRCU lockdep checking is enabled.\n");
39+
if (IS_ENABLED(CONFIG_RCU_STRICT_GRACE_PERIOD))
40+
pr_info("\tRCU strict (and thus non-scalable) grace periods enabled.\n");
3941
if (RCU_NUM_LVLS >= 4)
4042
pr_info("\tFour(or more)-level hierarchy is enabled.\n");
4143
if (RCU_FANOUT_LEAF != 16)
@@ -374,6 +376,8 @@ void __rcu_read_lock(void)
374376
rcu_preempt_read_enter();
375377
if (IS_ENABLED(CONFIG_PROVE_LOCKING))
376378
WARN_ON_ONCE(rcu_preempt_depth() > RCU_NEST_PMAX);
379+
if (IS_ENABLED(CONFIG_RCU_STRICT_GRACE_PERIOD) && rcu_state.gp_kthread)
380+
WRITE_ONCE(current->rcu_read_unlock_special.b.need_qs, true);
377381
barrier(); /* critical section after entry code. */
378382
}
379383
EXPORT_SYMBOL_GPL(__rcu_read_lock);
@@ -455,8 +459,14 @@ rcu_preempt_deferred_qs_irqrestore(struct task_struct *t, unsigned long flags)
455459
return;
456460
}
457461
t->rcu_read_unlock_special.s = 0;
458-
if (special.b.need_qs)
459-
rcu_qs();
462+
if (special.b.need_qs) {
463+
if (IS_ENABLED(CONFIG_RCU_STRICT_GRACE_PERIOD)) {
464+
rcu_report_qs_rdp(rdp);
465+
udelay(rcu_unlock_delay);
466+
} else {
467+
rcu_qs();
468+
}
469+
}
460470

461471
/*
462472
* Respond to a request by an expedited grace period for a
@@ -768,6 +778,24 @@ dump_blkd_tasks(struct rcu_node *rnp, int ncheck)
768778

769779
#else /* #ifdef CONFIG_PREEMPT_RCU */
770780

781+
/*
782+
* If strict grace periods are enabled, and if the calling
783+
* __rcu_read_unlock() marks the beginning of a quiescent state, immediately
784+
* report that quiescent state and, if requested, spin for a bit.
785+
*/
786+
void rcu_read_unlock_strict(void)
787+
{
788+
struct rcu_data *rdp;
789+
790+
if (!IS_ENABLED(CONFIG_RCU_STRICT_GRACE_PERIOD) ||
791+
irqs_disabled() || preempt_count() || !rcu_state.gp_kthread)
792+
return;
793+
rdp = this_cpu_ptr(&rcu_data);
794+
rcu_report_qs_rdp(rdp);
795+
udelay(rcu_unlock_delay);
796+
}
797+
EXPORT_SYMBOL_GPL(rcu_read_unlock_strict);
798+
771799
/*
772800
* Tell them what RCU they are running.
773801
*/

0 commit comments

Comments
 (0)