diff options
| author | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2017-01-26 16:45:38 -0500 |
|---|---|---|
| committer | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2017-04-18 14:38:17 -0400 |
| commit | abb06b99484a9f5af05c7147c289faf835f68e8e (patch) | |
| tree | ff5a96680bf5e7049ab9a8ee9c687fc88ca59eef | |
| parent | 88a4976d0e37c0797ff3e6579a5f91cb7dced90d (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.html | 9 | ||||
| -rw-r--r-- | kernel/rcu/tree.c | 12 | ||||
| -rw-r--r-- | kernel/rcu/tree.h | 1 |
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>->dynticks_nesting</tt> field counts the | 1110 | <p>The <tt>->dynticks_nesting</tt> field counts the |
| @@ -1117,11 +1118,17 @@ NMIs are counted by the <tt>->dynticks_nmi_nesting</tt> | |||
| 1117 | field, except that NMIs that interrupt non-dyntick-idle execution | 1118 | field, except that NMIs that interrupt non-dyntick-idle execution |
| 1118 | are not counted. | 1119 | are not counted. |
| 1119 | 1120 | ||
| 1120 | </p><p>Finally, the <tt>->dynticks</tt> field counts the corresponding | 1121 | </p><p>The <tt>->dynticks</tt> field counts the corresponding |
| 1121 | CPU's transitions to and from dyntick-idle mode, so that this counter | 1122 | CPU's transitions to and from dyntick-idle mode, so that this counter |
| 1122 | has an even value when the CPU is in dyntick-idle mode and an odd | 1123 | has an even value when the CPU is in dyntick-idle mode and an odd |
| 1123 | value otherwise. | 1124 | value otherwise. |
| 1124 | 1125 | ||
| 1126 | </p><p>Finally, the <tt>->rcu_sched_qs_mask</tt> field is used | ||
| 1127 | to record the fact that the RCU core code would really like to | ||
| 1128 | see a quiescent state from the corresponding CPU. | ||
| 1129 | This flag is checked by RCU's context-switch and <tt>cond_resched()</tt> | ||
| 1130 | code, which provide a momentary idle sojourn in response. | ||
| 1131 | |||
| 1125 | <table> | 1132 | <table> |
| 1126 | <tr><th> </th></tr> | 1133 | <tr><th> </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 | ||
| 275 | static 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. */ |
