aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul E. McKenney <paulmck@linux.vnet.ibm.com>2017-01-26 16:45:38 -0500
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>2017-04-18 14:38:17 -0400
commitabb06b99484a9f5af05c7147c289faf835f68e8e (patch)
treeff5a96680bf5e7049ab9a8ee9c687fc88ca59eef
parent88a4976d0e37c0797ff3e6579a5f91cb7dced90d (diff)
rcu: Pull rcu_sched_qs_mask into rcu_dynticks structure
The rcu_sched_qs_mask variable is yet another isolated per-CPU variable, so this commit pulls it into the pre-existing rcu_dynticks per-CPU structure. Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
-rw-r--r--Documentation/RCU/Design/Data-Structures/Data-Structures.html9
-rw-r--r--kernel/rcu/tree.c12
-rw-r--r--kernel/rcu/tree.h1
3 files changed, 14 insertions, 8 deletions
diff --git a/Documentation/RCU/Design/Data-Structures/Data-Structures.html b/Documentation/RCU/Design/Data-Structures/Data-Structures.html
index d583c653a703..bf7f266e8888 100644
--- a/Documentation/RCU/Design/Data-Structures/Data-Structures.html
+++ b/Documentation/RCU/Design/Data-Structures/Data-Structures.html
@@ -1104,6 +1104,7 @@ Its fields are as follows:
1104 1 int dynticks_nesting; 1104 1 int dynticks_nesting;
1105 2 int dynticks_nmi_nesting; 1105 2 int dynticks_nmi_nesting;
1106 3 atomic_t dynticks; 1106 3 atomic_t dynticks;
1107 4 int rcu_sched_qs_mask;
1107</pre> 1108</pre>
1108 1109
1109<p>The <tt>-&gt;dynticks_nesting</tt> field counts the 1110<p>The <tt>-&gt;dynticks_nesting</tt> field counts the
@@ -1117,11 +1118,17 @@ NMIs are counted by the <tt>-&gt;dynticks_nmi_nesting</tt>
1117field, except that NMIs that interrupt non-dyntick-idle execution 1118field, except that NMIs that interrupt non-dyntick-idle execution
1118are not counted. 1119are not counted.
1119 1120
1120</p><p>Finally, the <tt>-&gt;dynticks</tt> field counts the corresponding 1121</p><p>The <tt>-&gt;dynticks</tt> field counts the corresponding
1121CPU's transitions to and from dyntick-idle mode, so that this counter 1122CPU's transitions to and from dyntick-idle mode, so that this counter
1122has an even value when the CPU is in dyntick-idle mode and an odd 1123has an even value when the CPU is in dyntick-idle mode and an odd
1123value otherwise. 1124value otherwise.
1124 1125
1126</p><p>Finally, the <tt>-&gt;rcu_sched_qs_mask</tt> field is used
1127to record the fact that the RCU core code would really like to
1128see a quiescent state from the corresponding CPU.
1129This flag is checked by RCU's context-switch and <tt>cond_resched()</tt>
1130code, which provide a momentary idle sojourn in response.
1131
1125<table> 1132<table>
1126<tr><th>&nbsp;</th></tr> 1133<tr><th>&nbsp;</th></tr>
1127<tr><th align="left">Quick Quiz:</th></tr> 1134<tr><th align="left">Quick Quiz:</th></tr>
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
index 3747277aae67..3a0703035874 100644
--- a/kernel/rcu/tree.c
+++ b/kernel/rcu/tree.c
@@ -272,8 +272,6 @@ void rcu_bh_qs(void)
272 } 272 }
273} 273}
274 274
275static DEFINE_PER_CPU(int, rcu_sched_qs_mask);
276
277/* 275/*
278 * Steal a bit from the bottom of ->dynticks for idle entry/exit 276 * Steal a bit from the bottom of ->dynticks for idle entry/exit
279 * control. Initially this is for TLB flushing. 277 * control. Initially this is for TLB flushing.
@@ -464,8 +462,8 @@ static void rcu_momentary_dyntick_idle(void)
464 * Yes, we can lose flag-setting operations. This is OK, because 462 * Yes, we can lose flag-setting operations. This is OK, because
465 * the flag will be set again after some delay. 463 * the flag will be set again after some delay.
466 */ 464 */
467 resched_mask = raw_cpu_read(rcu_sched_qs_mask); 465 resched_mask = raw_cpu_read(rcu_dynticks.rcu_sched_qs_mask);
468 raw_cpu_write(rcu_sched_qs_mask, 0); 466 raw_cpu_write(rcu_dynticks.rcu_sched_qs_mask, 0);
469 467
470 /* Find the flavor that needs a quiescent state. */ 468 /* Find the flavor that needs a quiescent state. */
471 for_each_rcu_flavor(rsp) { 469 for_each_rcu_flavor(rsp) {
@@ -499,7 +497,7 @@ void rcu_note_context_switch(void)
499 trace_rcu_utilization(TPS("Start context switch")); 497 trace_rcu_utilization(TPS("Start context switch"));
500 rcu_sched_qs(); 498 rcu_sched_qs();
501 rcu_preempt_note_context_switch(); 499 rcu_preempt_note_context_switch();
502 if (unlikely(raw_cpu_read(rcu_sched_qs_mask))) 500 if (unlikely(raw_cpu_read(rcu_dynticks.rcu_sched_qs_mask)))
503 rcu_momentary_dyntick_idle(); 501 rcu_momentary_dyntick_idle();
504 trace_rcu_utilization(TPS("End context switch")); 502 trace_rcu_utilization(TPS("End context switch"));
505 barrier(); /* Avoid RCU read-side critical sections leaking up. */ 503 barrier(); /* Avoid RCU read-side critical sections leaking up. */
@@ -524,7 +522,7 @@ void rcu_all_qs(void)
524 unsigned long flags; 522 unsigned long flags;
525 523
526 barrier(); /* Avoid RCU read-side critical sections leaking down. */ 524 barrier(); /* Avoid RCU read-side critical sections leaking down. */
527 if (unlikely(raw_cpu_read(rcu_sched_qs_mask))) { 525 if (unlikely(raw_cpu_read(rcu_dynticks.rcu_sched_qs_mask))) {
528 local_irq_save(flags); 526 local_irq_save(flags);
529 rcu_momentary_dyntick_idle(); 527 rcu_momentary_dyntick_idle();
530 local_irq_restore(flags); 528 local_irq_restore(flags);
@@ -1351,7 +1349,7 @@ static int rcu_implicit_dynticks_qs(struct rcu_data *rdp,
1351 * is set too high, we override with half of the RCU CPU stall 1349 * is set too high, we override with half of the RCU CPU stall
1352 * warning delay. 1350 * warning delay.
1353 */ 1351 */
1354 rcrmp = &per_cpu(rcu_sched_qs_mask, rdp->cpu); 1352 rcrmp = &per_cpu(rcu_dynticks.rcu_sched_qs_mask, rdp->cpu);
1355 if (time_after(jiffies, rdp->rsp->gp_start + jtsq) || 1353 if (time_after(jiffies, rdp->rsp->gp_start + jtsq) ||
1356 time_after(jiffies, rdp->rsp->jiffies_resched)) { 1354 time_after(jiffies, rdp->rsp->jiffies_resched)) {
1357 if (!(READ_ONCE(*rcrmp) & rdp->rsp->flavor_mask)) { 1355 if (!(READ_ONCE(*rcrmp) & rdp->rsp->flavor_mask)) {
diff --git a/kernel/rcu/tree.h b/kernel/rcu/tree.h
index 7468b4de7e0c..e298281984dc 100644
--- a/kernel/rcu/tree.h
+++ b/kernel/rcu/tree.h
@@ -113,6 +113,7 @@ struct rcu_dynticks {
113 /* Process level is worth LLONG_MAX/2. */ 113 /* Process level is worth LLONG_MAX/2. */
114 int dynticks_nmi_nesting; /* Track NMI nesting level. */ 114 int dynticks_nmi_nesting; /* Track NMI nesting level. */
115 atomic_t dynticks; /* Even value for idle, else odd. */ 115 atomic_t dynticks; /* Even value for idle, else odd. */
116 int rcu_sched_qs_mask; /* GP old, need quiescent state. */
116#ifdef CONFIG_NO_HZ_FULL_SYSIDLE 117#ifdef CONFIG_NO_HZ_FULL_SYSIDLE
117 long long dynticks_idle_nesting; 118 long long dynticks_idle_nesting;
118 /* irq/process nesting level from idle. */ 119 /* irq/process nesting level from idle. */