RCU CPU stall warning updates for v4.15
cover RCU CPU stall warning updates for v4.15
Hello!
This series updates RCU CPU stall warnings, and also, due to conflicts, pulls along a long-standing patch that allows cond_resched() to do the work that cond_resched_rcu_qs() does.
1. Make cond_resched() provide RCU quiescent state. This has been
heavily optimized over its lifetime, which is almost one year. It should be close enough. Yes, some benchmarks show that it results in higher context-switch rates, but then again, the problem being solved is in fact too few context switches. ;-)
2. Make RCU CPU stall warnings check for irq-disabled CPUs.
3. Turn off tracing before dumping traces.
4. Suppress RCU CPU stall warnings while dumping RCU-related traces.
Thanx, Paul
------------------------------------------------------------------------
include/linux/sched.h | 3 - kernel/rcu/rcu.h | 21 +++++++ kernel/rcu/tree.c | 129 +++++++++++++++++++++++++++++++++++------------ kernel/rcu/tree.h | 5 + kernel/rcu/tree_plugin.h | 7 ++ kernel/rcu/update.c | 1 kernel/sched/core.c | 1 7 files changed, 132 insertions(+), 35 deletions(-)
PATCH 1/4 sched,rcu: Make cond_resched() provide RCU quiescent state
There is some confusion as to which of cond_resched() or cond_resched_rcu_qs() should be added to long in-kernel loops. This commit therefore eliminates the decision by adding RCU quiescent states to cond_resched(). This commit also simplifies the code that used to interact with cond_resched_rcu_qs(), and that now interacts with cond_resched(), to reduce its overhead. This reduction is necessary to allow the heavier-weight cond_resched_rcu_qs() mechanism to be invoked everywhere that cond_resched() is invoked.
Part of that reduction in overhead converts the jiffies_till_sched_qs kernel parameter to read-only at runtime, thus eliminating the need for bounds checking.
--- include/linux/sched.h | 3 ++- kernel/rcu/tree.c | 25 +++++-------------------- kernel/sched/core.c | 1 + 3 files changed, 8 insertions(+), 21 deletions(-)
include/linux/sched.h +2 -1
@@ -1565,10 +1565,11 @@ static inline int test_tsk_need_resched(struct task_struct *tsk)* cond_resched_lock() will drop the spinlock before scheduling, * cond_resched_softirq() will enable bhs before scheduling. */ +void rcu_all_qs (void );#ifndef CONFIG_PREEMPT extern int _cond_resched (void );#else -static inline int _cond_resched (void ) {return 0 ; } +static inline int _cond_resched (void ) {rcu_all_qs ();return 0 ; }#endif #define cond_resched () ({ \
kernel/rcu/tree.c +5 -20
@@ -534,8 +534,8 @@ module_param(rcu_kick_kthreads, bool, 0644);* How long the grace period must be before we start recruiting * quiescent-state help from rcu_note_context_switch(). */ -static ulong jiffies_till_sched_qs =HZ /20 ; -module_param (jiffies_till_sched_qs, ulong,0644 ); +static ulong jiffies_till_sched_qs =HZ /10 ; +module_param (jiffies_till_sched_qs, ulong,0444 );static bool rcu_start_gp_advanced (struct rcu_state *rsp,struct rcu_node *rnp,struct rcu_data *rdp);
@@ -1235,7 +1235,6 @@ static int rcu_implicit_dynticks_qs(struct rcu_data *rdp)unsigned long jtsq;bool *rnhqp;bool *ruqp; -unsigned long rjtsc;struct rcu_node *rnp;/*
@@ -1252,23 +1251,13 @@ static int rcu_implicit_dynticks_qs(struct rcu_data *rdp)return 1 ; } -/* Compute and saturate jiffies_till_sched_qs. */ - jtsq = jiffies_till_sched_qs; - rjtsc =rcu_jiffies_till_stall_check (); -if (jtsq > rjtsc /2 ) { -WRITE_ONCE (jiffies_till_sched_qs, rjtsc); - jtsq = rjtsc /2 ; - }else if (jtsq <1 ) { -WRITE_ONCE (jiffies_till_sched_qs,1 ); - jtsq =1 ; - } -/* * Has this CPU encountered a cond_resched_rcu_qs() since the * beginning of the grace period? For this to be the case, * the CPU has to have noticed the current grace period. This * might not be the case for nohz_full CPUs looping in the kernel. */ + jtsq = jiffies_till_sched_qs; rnp = rdp->mynode; ruqp =per_cpu_ptr (&rcu_dynticks.rcu_urgent_qs, rdp->cpu); if (time_after(jiffies, rdp->rsp->gp_start + jtsq) &&
@@ -1276,7 +1265,7 @@ static int rcu_implicit_dynticks_qs(struct rcu_data *rdp) READ_ONCE(rdp->gpnum) == rnp->gpnum && !rdp->gpwrap) {trace_rcu_fqs (rdp->rsp->name, rdp->gpnum, rdp->cpu,TPS ("rqc" ));return 1 ; - } else { + } else if (time_after(jiffies, rdp->rsp->gp_start + jtsq)) {/* Load rcu_qs_ctr before store to rcu_urgent_qs. */ smp_store_release (ruqp, true); }
@@ -1304,10 +1293,6 @@ static int rcu_implicit_dynticks_qs(struct rcu_data *rdp)* updates are only once every few jiffies, the probability of * lossage (and thus of slight grace-period extension) is * quite low. -* -* Note that if the jiffies_till_sched_qs boot/sysfs parameter -* is set too high, we override with half of the RCU CPU stall -* warning delay. */ rnhqp = &per_cpu (rcu_dynticks.rcu_need_heavy_qs, rdp->cpu); if (!READ_ONCE(*rnhqp) &&
@@ -1316,7 +1301,7 @@ static int rcu_implicit_dynticks_qs(struct rcu_data *rdp)WRITE_ONCE (*rnhqp, true);/* Store rcu_need_heavy_qs before rcu_urgent_qs. */ smp_store_release (ruqp, true); - rdp->rsp->jiffies_resched +=5 ;/* Re-enable beating. */ + rdp->rsp->jiffies_resched += jtsq;/* Re-enable beating. */ }/*
kernel/sched/core.c +1 -0
@@ -4842,6 +4842,7 @@ int __sched _cond_resched(void)preempt_schedule_common ();return 1 ; } +rcu_all_qs ();return 0 ; }EXPORT_SYMBOL (_cond_resched);
Signature · 1 line
2.5.2
Peter Zijlstra
maintainerRe: [PATCH tip/core/rcu 1/4] sched,rcu: Make cond_resched() provide RCU quiescent state
Quoted 5 lines · Paul E. McKenney
include/linux/sched.h +0
-0
include/linux/sched.h static inline int test_tsk_need_resched(struct task_struct *tsk) · line 1573
Quoted 10 lines
include/linux/sched.h +2
-1@@ -1565,10 +1565,11 @@ static inline int test_tsk_need_resched(struct task_struct *tsk)* cond_resched_lock() will drop the spinlock before scheduling, * cond_resched_softirq() will enable bhs before scheduling. */ +void rcu_all_qs (void );#ifndef CONFIG_PREEMPT extern int _cond_resched (void );#else -static inline int _cond_resched (void ) {return 0 ; } +static inline int _cond_resched (void ) {rcu_all_qs ();return 0 ; }#endif
Why does it need to change PREEMPT? the whole cond_resched() thing should be a no-op on PREEMPT.
Re: [PATCH tip/core/rcu 1/4] sched,rcu: Make cond_resched() provide RCU quiescent state
Quoted 11 lines · Peter Zijlstra
Quoted 10 lines · Paul E. McKenney
include/linux/sched.h +1
-0@@ -1565,10 +1565,11 @@ static inline int test_tsk_need_resched(struct task_struct *tsk)* cond_resched_lock() will drop the spinlock before scheduling, * cond_resched_softirq() will enable bhs before scheduling. */ +void rcu_all_qs (void );#ifndef CONFIG_PREEMPT
Quoted 8 lines
include/linux/sched.h static inline int test_tsk_need_resched(struct task_struct *tsk) · line 1573
Quoted 5 lines
include/linux/sched.h +1
-1extern int _cond_resched (void );#else -static inline int _cond_resched (void ) {return 0 ; } +static inline int _cond_resched (void ) {rcu_all_qs ();return 0 ; }#endif Why does it need to change PREEMPT? the whole
cond_resched()thing should be a no-op on PREEMPT.
Let's see... Clearly for RCU-preempt, there is no need. And you are quite right, if rcu_read_lock_bh() or rcu_read_lock_sched() are preventing a CPU from context switching, invoking cond_resched() on that CPU would be a bug anyway.
I will drop this hunk, thank you!
Thanx, Paul
PATCH 2/4 rcu: Make RCU CPU stall warnings check for irq-disabled CPUs
In reply to Paul E. McKenneyOne common question upon seeing an RCU CPU stall warning is "did the stalled CPUs have interrupts disabled?" However, the current stall warnings are silent on this point. This commit therefore uses irq_work to check whether stalled CPUs still respond to IPIs, and flags this state in the RCU CPU stall warning console messages.
--- kernel/rcu/tree.c | 104 +++++++++++++++++++++++++++++++++++++++++------ kernel/rcu/tree.h | 5 +++ kernel/rcu/tree_plugin.h | 7 +++- 3 files changed, 103 insertions(+), 13 deletions(-)
kernel/rcu/tree.c +92 -12
@@ -1207,6 +1207,22 @@ static int rcu_is_cpu_rrupt_from_idle(void) }/* +* We are reporting a quiescent state on behalf of some other CPU, so +* it is our responsibility to check for and handle potential overflow +* of the rcu_node ->gpnum counter with respect to the rcu_data counters. +* After all, the CPU might be in deep idle state, and thus executing no +* code whatsoever. +*/ +static void rcu_gpnum_ovf (struct rcu_node *rnp,struct rcu_data *rdp) +{ +lockdep_assert_held (&rnp->lock); +if (ULONG_CMP_LT (READ_ONCE (rdp->gpnum) +ULONG_MAX /4 , rnp->gpnum)) +WRITE_ONCE (rdp->gpwrap, true); +if (ULONG_CMP_LT (rdp->rcu_iw_gpnum +ULONG_MAX /4 , rnp->gpnum)) + rdp->rcu_iw_gpnum = rnp->gpnum +ULONG_MAX /4 ; +} + +/* * Snapshot the specified CPU's dynticks counter so that we can later * credit them with an implicit quiescent state. Return 1 if this CPU * is in dynticks idle mode, which is an extended quiescent state.
@@ -1216,15 +1232,34 @@ static int dyntick_save_progress_counter(struct rcu_data *rdp) rdp->dynticks_snap =rcu_dynticks_snap (rdp->dynticks);if (rcu_dynticks_in_eqs (rdp->dynticks_snap)) {trace_rcu_fqs (rdp->rsp->name, rdp->gpnum, rdp->cpu,TPS ("dti" )); -if (ULONG_CMP_LT (READ_ONCE (rdp->gpnum) +ULONG_MAX /4 , - rdp->mynode->gpnum)) -WRITE_ONCE (rdp->gpwrap, true); +rcu_gpnum_ovf (rdp->mynode, rdp);return 1 ; }return 0 ; }/* +* Handler for the irq_work request posted when a grace period has +* gone on for too long, but not yet long enough for an RCU CPU +* stall warning. Set state appropriately, but just complain if +* there is unexpected state on entry. +*/ +static void rcu_iw_handler (struct irq_work *iwp) +{ +struct rcu_data *rdp; +struct rcu_node *rnp; + + rdp = container_of(iwp, struct rcu_data, rcu_iw); + rnp = rdp->mynode; +raw_spin_lock_rcu_node (rnp); +if (!WARN_ON_ONCE (!rdp->rcu_iw_pending)) { + rdp->rcu_iw_gpnum = rnp->gpnum; + rdp->rcu_iw_pending = false; + } +raw_spin_unlock_rcu_node (rnp); +} + +/* * Return true if the specified CPU has passed through a quiescent * state by virtue of being in or having passed through an dynticks * idle state since the last call to dyntick_save_progress_counter()
@@ -1235,7 +1270,7 @@ static int rcu_implicit_dynticks_qs(struct rcu_data *rdp)unsigned long jtsq;bool *rnhqp;bool *ruqp; -struct rcu_node *rnp; +struct rcu_node *rnp = rdp->mynode;/* * If the CPU passed through or entered a dynticks idle phase with
@@ -1248,6 +1283,7 @@ static int rcu_implicit_dynticks_qs(struct rcu_data *rdp)if (rcu_dynticks_in_eqs_since (rdp->dynticks, rdp->dynticks_snap)) {trace_rcu_fqs (rdp->rsp->name, rdp->gpnum, rdp->cpu,TPS ("dti" )); rdp->dynticks_fqs++; +rcu_gpnum_ovf (rnp, rdp);return 1 ; }
@@ -1258,12 +1294,12 @@ static int rcu_implicit_dynticks_qs(struct rcu_data *rdp)* might not be the case for nohz_full CPUs looping in the kernel. */ jtsq = jiffies_till_sched_qs; - rnp = rdp->mynode; ruqp =per_cpu_ptr (&rcu_dynticks.rcu_urgent_qs, rdp->cpu);if (time_after (jiffies, rdp->rsp->gp_start + jtsq) &&READ_ONCE (rdp->rcu_qs_ctr_snap) !=per_cpu (rcu_dynticks.rcu_qs_ctr, rdp->cpu) &&READ_ONCE (rdp->gpnum) == rnp->gpnum && !rdp->gpwrap) {trace_rcu_fqs (rdp->rsp->name, rdp->gpnum, rdp->cpu,TPS ("rqc" )); +rcu_gpnum_ovf (rnp, rdp);return 1 ; }else if (time_after (jiffies, rdp->rsp->gp_start + jtsq)) {/* Load rcu_qs_ctr before store to rcu_urgent_qs. */
@@ -1274,6 +1310,7 @@ static int rcu_implicit_dynticks_qs(struct rcu_data *rdp)if (!(rdp->grpmask &rcu_rnp_online_cpus (rnp))) {trace_rcu_fqs (rdp->rsp->name, rdp->gpnum, rdp->cpu,TPS ("ofl" )); rdp->offline_fqs++; +rcu_gpnum_ovf (rnp, rdp);return 1 ; }
@@ -1305,11 +1342,22 @@ static int rcu_implicit_dynticks_qs(struct rcu_data *rdp) }/* -* If more than halfway to RCU CPU stall-warning time, do -* a resched_cpu() to try to loosen things up a bit. +* If more than halfway to RCU CPU stall-warning time, do a +* resched_cpu() to try to loosen things up a bit. Also check to +* see if the CPU is getting hammered with interrupts, but only +* once per grace period, just to keep the IPIs down to a dull roar. */ -if (jiffies - rdp->rsp->gp_start >rcu_jiffies_till_stall_check () /2 ) +if (jiffies - rdp->rsp->gp_start >rcu_jiffies_till_stall_check () /2 ) {resched_cpu (rdp->cpu); +if (IS_ENABLED (CONFIG_IRQ_WORK ) && + !rdp->rcu_iw_pending && rdp->rcu_iw_gpnum != rnp->gpnum && + (rnp->ffmask & rdp->grpmask)) { +init_irq_work (&rdp->rcu_iw, rcu_iw_handler); + rdp->rcu_iw_pending = true; + rdp->rcu_iw_gpnum = rnp->gpnum; +irq_work_queue_on (&rdp->rcu_iw, rdp->cpu); + } + }return 0 ; }
@@ -1498,6 +1546,7 @@ static void print_cpu_stall(struct rcu_state *rsp) {int cpu;unsigned long flags; +struct rcu_data *rdp =this_cpu_ptr (rsp->rda);struct rcu_node *rnp =rcu_get_root (rsp);long totqlen =0 ;
@@ -1513,7 +1562,9 @@ static void print_cpu_stall(struct rcu_state *rsp)*/ pr_err ("INFO: %s self-detected stall on CPU" , rsp->name);print_cpu_stall_info_begin (); +raw_spin_lock_irqsave_rcu_node (rdp->mynode, flags);print_cpu_stall_info (rsp,smp_processor_id ()); +raw_spin_unlock_irqrestore_rcu_node (rdp->mynode, flags);print_cpu_stall_info_end ();for_each_possible_cpu (cpu) totqlen += rcu_segcblist_n_cbs(&per_cpu_ptr(rsp->rda,
@@ -1907,6 +1958,7 @@ static bool __note_gp_changes(struct rcu_state *rsp, struct rcu_node *rnp, rdp->core_needs_qs = need_gp;zero_cpu_stall_ticks (rdp);WRITE_ONCE (rdp->gpwrap, false); +rcu_gpnum_ovf (rnp, rdp); }return ret; }
@@ -3685,6 +3737,8 @@ rcu_init_percpu_data(int cpu, struct rcu_state *rsp) rdp->cpu_no_qs.b.norm = true; rdp->rcu_qs_ctr_snap =per_cpu (rcu_dynticks.rcu_qs_ctr, cpu); rdp->core_needs_qs = false; + rdp->rcu_iw_pending = false; + rdp->rcu_iw_gpnum = rnp->gpnum -1 ;trace_rcu_grace_period (rsp->name, rdp->gpnum,TPS ("cpuonl" ));raw_spin_unlock_irqrestore_rcu_node (rnp, flags); }
@@ -3722,10 +3776,24 @@ static void rcutree_affinity_setting(unsigned int cpu, int outgoing)*/ int rcutree_online_cpu (unsigned int cpu) { -sync_sched_exp_online_cleanup (cpu); -rcutree_affinity_setting (cpu,-1 ); +unsigned long flags; +struct rcu_data *rdp; +struct rcu_node *rnp; +struct rcu_state *rsp; + +for_each_rcu_flavor (rsp) { + rdp =per_cpu_ptr (rsp->rda, cpu); + rnp = rdp->mynode; +raw_spin_lock_irqsave_rcu_node (rnp, flags); + rnp->ffmask |= rdp->grpmask; +raw_spin_unlock_irqrestore_rcu_node (rnp, flags); + }if (IS_ENABLED (CONFIG_TREE_SRCU ))srcu_online_cpu (cpu); +if (rcu_scheduler_active ==RCU_SCHEDULER_INACTIVE ) +return 0 ;/* Too early in boot for scheduler work. */ +sync_sched_exp_online_cleanup (cpu); +rcutree_affinity_setting (cpu,-1 );return 0 ; }
@@ -3735,6 +3803,19 @@ int rcutree_online_cpu(unsigned int cpu)*/ int rcutree_offline_cpu (unsigned int cpu) { +unsigned long flags; +struct rcu_data *rdp; +struct rcu_node *rnp; +struct rcu_state *rsp; + +for_each_rcu_flavor (rsp) { + rdp =per_cpu_ptr (rsp->rda, cpu); + rnp = rdp->mynode; +raw_spin_lock_irqsave_rcu_node (rnp, flags); + rnp->ffmask &= ~rdp->grpmask; +raw_spin_unlock_irqrestore_rcu_node (rnp, flags); + } +rcutree_affinity_setting (cpu, cpu);if (IS_ENABLED (CONFIG_TREE_SRCU ))srcu_offline_cpu (cpu);
@@ -4183,8 +4264,7 @@ void __init rcu_init(void)for_each_online_cpu (cpu) {rcutree_prepare_cpu (cpu);rcu_cpu_starting (cpu); -if (IS_ENABLED (CONFIG_TREE_SRCU )) -srcu_online_cpu (cpu); +rcutree_online_cpu (cpu); } }
kernel/rcu/tree.h +5 -0
@@ -103,6 +103,7 @@ struct rcu_node {/* Online CPUs for next expedited GP. */ /* Any CPU that has ever been online will */ /* have its bit set. */ +unsigned long ffmask;/* Fully functional CPUs. */ unsigned long grpmask;/* Mask to apply to parent qsmask. */ /* Only one bit will be set in this mask. */ int grplo;/* lowest-numbered CPU or group here. */
@@ -285,6 +286,10 @@ struct rcu_data {/* 8) RCU CPU stall data. */ unsigned int softirq_snap;/* Snapshot of softirq activity. */ +/* ->rcu_iw* fields protected by leaf rcu_node ->lock. */ +struct irq_work rcu_iw;/* Check for non-irq activity. */ +bool rcu_iw_pending;/* Is ->rcu_iw pending? */ +unsigned long rcu_iw_gpnum;/* ->gpnum associated with ->rcu_iw. */ int cpu;struct rcu_state *rsp;
kernel/rcu/tree_plugin.h +6 -1
@@ -1671,6 +1671,7 @@ static void print_cpu_stall_info_begin(void)*/ static void print_cpu_stall_info (struct rcu_state *rsp,int cpu) { +unsigned long delta;char fast_no_hz[72 ];struct rcu_data *rdp =per_cpu_ptr (rsp->rda, cpu);struct rcu_dynticks *rdtp = rdp->dynticks;
@@ -1685,11 +1686,15 @@ static void print_cpu_stall_info(struct rcu_state *rsp, int cpu) ticks_value = rsp->gpnum - rdp->gpnum; }print_cpu_stall_fast_no_hz (fast_no_hz, cpu); - pr_err("\t%d-%c%c%c: (%lu %s) idle=%03x/%llx/%d softirq=%u/%u fqs=%ld %s\n", + delta = rdp->mynode->gpnum - rdp->rcu_iw_gpnum; + pr_err("\t%d-%c%c%c%c: (%lu %s) idle=%03x/%llx/%d softirq=%u/%u fqs=%ld %s\n", cpu, "O."[!!cpu_online(cpu)], "o."[!!(rdp->grpmask & rdp->mynode->qsmaskinit)], "N."[!!(rdp->grpmask & rdp->mynode->qsmaskinitnext)], + !IS_ENABLED(CONFIG_IRQ_WORK) ? '?' : + rdp->rcu_iw_pending ? (int)min(delta, 9UL) + '0' : + "!."[!delta], ticks_value, ticks_title, rcu_dynticks_snap(rdtp) & 0xfff, rdtp->dynticks_nesting, rdtp->dynticks_nmi_nesting,
Signature · 1 line
2.5.2
PATCH 3/4 rcu: Turn off tracing before dumping trace
In reply to Paul E. McKenneyCurrently, RCU allows tracing to continue when it automatically does ftrace_dump() after detecting an error condition, which can result in excessively large traces and lost trace events. This commit therefore does a tracing_off() before any of these ftrace_dump() calls.
--- kernel/rcu/rcu.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
kernel/rcu/rcu.h +3 -1
@@ -220,8 +220,10 @@ do { \static atomic_t ___rfd_beenhere =ATOMIC_INIT (0 ); \ \if (!atomic_read (&___rfd_beenhere) && \ - !atomic_xchg (&___rfd_beenhere,1 )) \ + !atomic_xchg (&___rfd_beenhere,1 )) { \ +tracing_off (); \ftrace_dump (oops_dump_mode); \ + } \ }while (0 ) void rcu_early_boot_tests(void);
Signature · 1 line
2.5.2
PATCH 4/4 rcu: Suppress RCU CPU stall warnings while dumping trace
In reply to Paul E. McKenneyCurrently, RCU emits Suppress RCU CPU stall warnings during its automatically initiated ftrace_dump() calls after detecting an error condition, which can result in excessively excessive console output and lost trace events. This commit therefore suppresses RCU CPU stall warnings across any of these ftrace_dump() calls.
--- kernel/rcu/rcu.h | 17 +++++++++++++++++ kernel/rcu/update.c | 1 + 2 files changed, 18 insertions(+)
kernel/rcu/rcu.h +17 -0
@@ -203,6 +203,21 @@ static inline bool __rcu_reclaim(const char *rn, struct rcu_head *head)extern int rcu_cpu_stall_suppress;int rcu_jiffies_till_stall_check (void ); +#define rcu_ftrace_dump_stall_suppress () \ +do { \ + if (!rcu_cpu_stall_suppress) \ + rcu_cpu_stall_suppress = 3; \ +} while (0) + +#define rcu_ftrace_dump_stall_unsuppress () \ +do { \ + if (rcu_cpu_stall_suppress == 3) \ + rcu_cpu_stall_suppress = 0; \ +} while (0) + +#else /* #endif #ifdef CONFIG_RCU_STALL_COMMON */ +#define rcu_ftrace_dump_stall_suppress () +#define rcu_ftrace_dump_stall_unsuppress ()#endif /* #ifdef CONFIG_RCU_STALL_COMMON */ /*
@@ -222,7 +237,9 @@ do { \if (!atomic_read (&___rfd_beenhere) && \ !atomic_xchg (&___rfd_beenhere,1 )) { \tracing_off (); \ +rcu_ftrace_dump_stall_suppress (); \ftrace_dump (oops_dump_mode); \ +rcu_ftrace_dump_stall_unsuppress (); \ } \ }while (0 )
kernel/rcu/update.c +1 -0
@@ -494,6 +494,7 @@ EXPORT_SYMBOL_GPL(do_trace_rcu_torture_read);#endif int rcu_cpu_stall_suppress__read_mostly ;/* 1 = suppress stall warnings. */ +EXPORT_SYMBOL_GPL (rcu_cpu_stall_suppress);static int rcu_cpu_stall_timeout__read_mostly =CONFIG_RCU_CPU_STALL_TIMEOUT ;module_param (rcu_cpu_stall_suppress, int,0644 );
Signature · 1 line
2.5.2