aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul E. McKenney <paulmck@linux.vnet.ibm.com>2017-05-17 13:54:29 -0400
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>2017-06-08 21:52:45 -0400
commit6d48152eafde1f0d0a4a9e0584fa7d9ff4fbfdac (patch)
treea4e249fef970885c4a96b2251505ab81f3abf25b
parentc23484f0e7bc89e1facb04103ce24efeebee76b9 (diff)
rcu: Remove RCU CPU stall warnings from Tiny RCU
Tiny RCU's job is to be tiny, so this commit removes its RCU CPU stall warning code. After this, there is no longer any need for rcu_sched_ctrlblk and rcu_bh_ctrlblk to be in tiny_plugin.h, so this commit also moves them to tiny.c. Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
-rw-r--r--kernel/rcu/Kconfig2
-rw-r--r--kernel/rcu/tiny.c35
-rw-r--r--kernel/rcu/tiny_plugin.h78
-rw-r--r--tools/testing/selftests/rcutorture/configs/rcu/TINY021
4 files changed, 19 insertions, 97 deletions
diff --git a/kernel/rcu/Kconfig b/kernel/rcu/Kconfig
index 8edff43e8e94..be90c945063f 100644
--- a/kernel/rcu/Kconfig
+++ b/kernel/rcu/Kconfig
@@ -78,7 +78,7 @@ config TASKS_RCU
78 user-mode execution as quiescent states. 78 user-mode execution as quiescent states.
79 79
80config RCU_STALL_COMMON 80config RCU_STALL_COMMON
81 def_bool ( TREE_RCU || PREEMPT_RCU || RCU_TRACE ) 81 def_bool ( TREE_RCU || PREEMPT_RCU )
82 help 82 help
83 This option enables RCU CPU stall code that is common between 83 This option enables RCU CPU stall code that is common between
84 the TINY and TREE variants of RCU. The purpose is to allow 84 the TINY and TREE variants of RCU. The purpose is to allow
diff --git a/kernel/rcu/tiny.c b/kernel/rcu/tiny.c
index 595cb1bf944f..f8488965250f 100644
--- a/kernel/rcu/tiny.c
+++ b/kernel/rcu/tiny.c
@@ -38,11 +38,23 @@
38 38
39#include "rcu.h" 39#include "rcu.h"
40 40
41/* Forward declarations for tiny_plugin.h. */ 41/* Global control variables for rcupdate callback mechanism. */
42struct rcu_ctrlblk; 42struct rcu_ctrlblk {
43static void __call_rcu(struct rcu_head *head, 43 struct rcu_head *rcucblist; /* List of pending callbacks (CBs). */
44 rcu_callback_t func, 44 struct rcu_head **donetail; /* ->next pointer of last "done" CB. */
45 struct rcu_ctrlblk *rcp); 45 struct rcu_head **curtail; /* ->next pointer of last CB. */
46};
47
48/* Definition for rcupdate control block. */
49static struct rcu_ctrlblk rcu_sched_ctrlblk = {
50 .donetail = &rcu_sched_ctrlblk.rcucblist,
51 .curtail = &rcu_sched_ctrlblk.rcucblist,
52};
53
54static struct rcu_ctrlblk rcu_bh_ctrlblk = {
55 .donetail = &rcu_bh_ctrlblk.rcucblist,
56 .curtail = &rcu_bh_ctrlblk.rcucblist,
57};
46 58
47#include "tiny_plugin.h" 59#include "tiny_plugin.h"
48 60
@@ -65,7 +77,6 @@ EXPORT_SYMBOL(rcu_barrier_sched);
65 */ 77 */
66static int rcu_qsctr_help(struct rcu_ctrlblk *rcp) 78static int rcu_qsctr_help(struct rcu_ctrlblk *rcp)
67{ 79{
68 RCU_TRACE(reset_cpu_stall_ticks(rcp);)
69 if (rcp->donetail != rcp->curtail) { 80 if (rcp->donetail != rcp->curtail) {
70 rcp->donetail = rcp->curtail; 81 rcp->donetail = rcp->curtail;
71 return 1; 82 return 1;
@@ -111,7 +122,6 @@ void rcu_bh_qs(void)
111 */ 122 */
112void rcu_check_callbacks(int user) 123void rcu_check_callbacks(int user)
113{ 124{
114 RCU_TRACE(check_cpu_stalls();)
115 if (user) 125 if (user)
116 rcu_sched_qs(); 126 rcu_sched_qs();
117 else if (!in_softirq()) 127 else if (!in_softirq())
@@ -126,10 +136,8 @@ void rcu_check_callbacks(int user)
126 */ 136 */
127static void __rcu_process_callbacks(struct rcu_ctrlblk *rcp) 137static void __rcu_process_callbacks(struct rcu_ctrlblk *rcp)
128{ 138{
129 const char *rn = NULL;
130 struct rcu_head *next, *list; 139 struct rcu_head *next, *list;
131 unsigned long flags; 140 unsigned long flags;
132 RCU_TRACE(int cb_count = 0;)
133 141
134 /* Move the ready-to-invoke callbacks to a local list. */ 142 /* Move the ready-to-invoke callbacks to a local list. */
135 local_irq_save(flags); 143 local_irq_save(flags);
@@ -147,18 +155,15 @@ static void __rcu_process_callbacks(struct rcu_ctrlblk *rcp)
147 local_irq_restore(flags); 155 local_irq_restore(flags);
148 156
149 /* Invoke the callbacks on the local list. */ 157 /* Invoke the callbacks on the local list. */
150 RCU_TRACE(rn = rcp->name;)
151 while (list) { 158 while (list) {
152 next = list->next; 159 next = list->next;
153 prefetch(next); 160 prefetch(next);
154 debug_rcu_head_unqueue(list); 161 debug_rcu_head_unqueue(list);
155 local_bh_disable(); 162 local_bh_disable();
156 __rcu_reclaim(rn, list); 163 __rcu_reclaim("", list);
157 local_bh_enable(); 164 local_bh_enable();
158 list = next; 165 list = next;
159 RCU_TRACE(cb_count++;)
160 } 166 }
161 RCU_TRACE(rcu_trace_sub_qlen(rcp, cb_count);)
162} 167}
163 168
164static __latent_entropy void rcu_process_callbacks(struct softirq_action *unused) 169static __latent_entropy void rcu_process_callbacks(struct softirq_action *unused)
@@ -202,7 +207,6 @@ static void __call_rcu(struct rcu_head *head,
202 local_irq_save(flags); 207 local_irq_save(flags);
203 *rcp->curtail = head; 208 *rcp->curtail = head;
204 rcp->curtail = &head->next; 209 rcp->curtail = &head->next;
205 RCU_TRACE(rcp->qlen++;)
206 local_irq_restore(flags); 210 local_irq_restore(flags);
207 211
208 if (unlikely(is_idle_task(current))) { 212 if (unlikely(is_idle_task(current))) {
@@ -235,8 +239,5 @@ EXPORT_SYMBOL_GPL(call_rcu_bh);
235void __init rcu_init(void) 239void __init rcu_init(void)
236{ 240{
237 open_softirq(RCU_SOFTIRQ, rcu_process_callbacks); 241 open_softirq(RCU_SOFTIRQ, rcu_process_callbacks);
238 RCU_TRACE(reset_cpu_stall_ticks(&rcu_sched_ctrlblk);)
239 RCU_TRACE(reset_cpu_stall_ticks(&rcu_bh_ctrlblk);)
240
241 rcu_early_boot_tests(); 242 rcu_early_boot_tests();
242} 243}
diff --git a/kernel/rcu/tiny_plugin.h b/kernel/rcu/tiny_plugin.h
index c642f23f1582..f0a01b2a3062 100644
--- a/kernel/rcu/tiny_plugin.h
+++ b/kernel/rcu/tiny_plugin.h
@@ -22,34 +22,6 @@
22 * Author: Paul E. McKenney <paulmck@linux.vnet.ibm.com> 22 * Author: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
23 */ 23 */
24 24
25#include <linux/kthread.h>
26#include <linux/init.h>
27
28/* Global control variables for rcupdate callback mechanism. */
29struct rcu_ctrlblk {
30 struct rcu_head *rcucblist; /* List of pending callbacks (CBs). */
31 struct rcu_head **donetail; /* ->next pointer of last "done" CB. */
32 struct rcu_head **curtail; /* ->next pointer of last CB. */
33 RCU_TRACE(long qlen); /* Number of pending CBs. */
34 RCU_TRACE(unsigned long gp_start); /* Start time for stalls. */
35 RCU_TRACE(unsigned long ticks_this_gp); /* Statistic for stalls. */
36 RCU_TRACE(unsigned long jiffies_stall); /* Jiffies at next stall. */
37 RCU_TRACE(const char *name); /* Name of RCU type. */
38};
39
40/* Definition for rcupdate control block. */
41static struct rcu_ctrlblk rcu_sched_ctrlblk = {
42 .donetail = &rcu_sched_ctrlblk.rcucblist,
43 .curtail = &rcu_sched_ctrlblk.rcucblist,
44 RCU_TRACE(.name = "rcu_sched")
45};
46
47static struct rcu_ctrlblk rcu_bh_ctrlblk = {
48 .donetail = &rcu_bh_ctrlblk.rcucblist,
49 .curtail = &rcu_bh_ctrlblk.rcucblist,
50 RCU_TRACE(.name = "rcu_bh")
51};
52
53#if defined(CONFIG_DEBUG_LOCK_ALLOC) || defined(CONFIG_SRCU) 25#if defined(CONFIG_DEBUG_LOCK_ALLOC) || defined(CONFIG_SRCU)
54#include <linux/kernel_stat.h> 26#include <linux/kernel_stat.h>
55 27
@@ -73,53 +45,3 @@ void __init rcu_scheduler_starting(void)
73} 45}
74 46
75#endif /* #if defined(CONFIG_DEBUG_LOCK_ALLOC) || defined(CONFIG_SRCU) */ 47#endif /* #if defined(CONFIG_DEBUG_LOCK_ALLOC) || defined(CONFIG_SRCU) */
76
77#ifdef CONFIG_RCU_TRACE
78
79static void rcu_trace_sub_qlen(struct rcu_ctrlblk *rcp, int n)
80{
81 unsigned long flags;
82
83 local_irq_save(flags);
84 rcp->qlen -= n;
85 local_irq_restore(flags);
86}
87
88static void check_cpu_stall(struct rcu_ctrlblk *rcp)
89{
90 unsigned long j;
91 unsigned long js;
92
93 if (rcu_cpu_stall_suppress)
94 return;
95 rcp->ticks_this_gp++;
96 j = jiffies;
97 js = READ_ONCE(rcp->jiffies_stall);
98 if (rcp->rcucblist && ULONG_CMP_GE(j, js)) {
99 pr_err("INFO: %s stall on CPU (%lu ticks this GP) idle=%llx (t=%lu jiffies q=%ld)\n",
100 rcp->name, rcp->ticks_this_gp, DYNTICK_TASK_EXIT_IDLE,
101 jiffies - rcp->gp_start, rcp->qlen);
102 dump_stack();
103 WRITE_ONCE(rcp->jiffies_stall,
104 jiffies + 3 * rcu_jiffies_till_stall_check() + 3);
105 } else if (ULONG_CMP_GE(j, js)) {
106 WRITE_ONCE(rcp->jiffies_stall,
107 jiffies + rcu_jiffies_till_stall_check());
108 }
109}
110
111static void reset_cpu_stall_ticks(struct rcu_ctrlblk *rcp)
112{
113 rcp->ticks_this_gp = 0;
114 rcp->gp_start = jiffies;