Blame view

kernel/rcutree_trace.c 14.1 KB
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
  /*
   * Read-Copy Update tracing for classic implementation
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation; either version 2 of the License, or
   * (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write to the Free Software
   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
   *
   * Copyright IBM Corporation, 2008
   *
   * Papers:  http://www.rdrop.com/users/paulmck/RCU
   *
   * For detailed explanation of Read-Copy Update mechanism see -
a71fca58b   Paul E. McKenney   rcu: Fix whitespa...
23
   *		Documentation/RCU
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
24
25
26
27
28
29
30
31
32
33
   *
   */
  #include <linux/types.h>
  #include <linux/kernel.h>
  #include <linux/init.h>
  #include <linux/spinlock.h>
  #include <linux/smp.h>
  #include <linux/rcupdate.h>
  #include <linux/interrupt.h>
  #include <linux/sched.h>
60063497a   Arun Sharma   atomic: use <linu...
34
  #include <linux/atomic.h>
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
35
36
37
38
39
40
41
42
43
44
  #include <linux/bitops.h>
  #include <linux/module.h>
  #include <linux/completion.h>
  #include <linux/moduleparam.h>
  #include <linux/percpu.h>
  #include <linux/notifier.h>
  #include <linux/cpu.h>
  #include <linux/mutex.h>
  #include <linux/debugfs.h>
  #include <linux/seq_file.h>
9f77da9f4   Paul E. McKenney   rcu: Move private...
45
  #define RCU_TREE_NONCORE
6258c4fb5   Ingo Molnar   kmemtrace, rcu: f...
46
  #include "rcutree.h"
a46e0899e   Paul E. McKenney   rcu: use softirq ...
47
  #ifdef CONFIG_RCU_BOOST
d71df90ea   Paul E. McKenney   rcu: add tracing ...
48
  DECLARE_PER_CPU(unsigned int, rcu_cpu_kthread_status);
15ba0ba86   Paul E. McKenney   rcu: add grace-pe...
49
  DECLARE_PER_CPU(unsigned int, rcu_cpu_kthread_cpu);
5ece5bab3   Paul E. McKenney   rcu: Add forward-...
50
  DECLARE_PER_CPU(unsigned int, rcu_cpu_kthread_loops);
d71df90ea   Paul E. McKenney   rcu: add tracing ...
51
52
53
54
55
56
  DECLARE_PER_CPU(char, rcu_cpu_has_work);
  
  static char convert_kthread_status(unsigned int kthread_status)
  {
  	if (kthread_status > RCU_KTHREAD_MAX)
  		return '?';
15ba0ba86   Paul E. McKenney   rcu: add grace-pe...
57
  	return "SRWOY"[kthread_status];
d71df90ea   Paul E. McKenney   rcu: add tracing ...
58
  }
a46e0899e   Paul E. McKenney   rcu: use softirq ...
59
  #endif /* #ifdef CONFIG_RCU_BOOST */
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
60
61
62
63
  static void print_one_rcu_data(struct seq_file *m, struct rcu_data *rdp)
  {
  	if (!rdp->beenonline)
  		return;
20133cfce   Paul E. McKenney   rcu: Stop overflo...
64
  	seq_printf(m, "%3d%cc=%lu g=%lu pq=%d pqc=%lu qp=%d",
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
65
66
67
68
  		   rdp->cpu,
  		   cpu_is_offline(rdp->cpu) ? '!' : ' ',
  		   rdp->completed, rdp->gpnum,
  		   rdp->passed_quiesc, rdp->passed_quiesc_completed,
ef631b0ca   Paul E. McKenney   rcu: Make hierarc...
69
  		   rdp->qs_pending);
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
70
  #ifdef CONFIG_NO_HZ
23b5c8fa0   Paul E. McKenney   rcu: Decrease mem...
71
72
  	seq_printf(m, " dt=%d/%d/%d df=%lu",
  		   atomic_read(&rdp->dynticks->dynticks),
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
73
  		   rdp->dynticks->dynticks_nesting,
23b5c8fa0   Paul E. McKenney   rcu: Decrease mem...
74
  		   rdp->dynticks->dynticks_nmi_nesting,
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
75
76
77
  		   rdp->dynticks_fqs);
  #endif /* #ifdef CONFIG_NO_HZ */
  	seq_printf(m, " of=%lu ri=%lu", rdp->offline_fqs, rdp->resched_ipi);
a46e0899e   Paul E. McKenney   rcu: use softirq ...
78
  	seq_printf(m, " ql=%ld qs=%c%c%c%c",
0ac3d136b   Paul E. McKenney   rcu: add callback...
79
80
81
82
83
84
85
  		   rdp->qlen,
  		   ".N"[rdp->nxttail[RCU_NEXT_READY_TAIL] !=
  			rdp->nxttail[RCU_NEXT_TAIL]],
  		   ".R"[rdp->nxttail[RCU_WAIT_TAIL] !=
  			rdp->nxttail[RCU_NEXT_READY_TAIL]],
  		   ".W"[rdp->nxttail[RCU_DONE_TAIL] !=
  			rdp->nxttail[RCU_WAIT_TAIL]],
a46e0899e   Paul E. McKenney   rcu: use softirq ...
86
87
88
  		   ".D"[&rdp->nxtlist != rdp->nxttail[RCU_DONE_TAIL]]);
  #ifdef CONFIG_RCU_BOOST
  	seq_printf(m, " kt=%d/%c/%d ktl=%x",
d71df90ea   Paul E. McKenney   rcu: add tracing ...
89
90
91
  		   per_cpu(rcu_cpu_has_work, rdp->cpu),
  		   convert_kthread_status(per_cpu(rcu_cpu_kthread_status,
  					  rdp->cpu)),
15ba0ba86   Paul E. McKenney   rcu: add grace-pe...
92
  		   per_cpu(rcu_cpu_kthread_cpu, rdp->cpu),
a46e0899e   Paul E. McKenney   rcu: use softirq ...
93
94
95
  		   per_cpu(rcu_cpu_kthread_loops, rdp->cpu) & 0xffff);
  #endif /* #ifdef CONFIG_RCU_BOOST */
  	seq_printf(m, " b=%ld", rdp->blimit);
269dcc1c2   Paul E. McKenney   rcu: Add tracing ...
96
97
98
  	seq_printf(m, " ci=%lu co=%lu ca=%lu
  ",
  		   rdp->n_cbs_invoked, rdp->n_cbs_orphaned, rdp->n_cbs_adopted);
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
99
100
101
102
103
104
105
106
107
108
109
110
  }
  
  #define PRINT_RCU_DATA(name, func, m) \
  	do { \
  		int _p_r_d_i; \
  		\
  		for_each_possible_cpu(_p_r_d_i) \
  			func(m, &per_cpu(name, _p_r_d_i)); \
  	} while (0)
  
  static int show_rcudata(struct seq_file *m, void *unused)
  {
f41d911f8   Paul E. McKenney   rcu: Merge preemp...
111
112
113
114
115
  #ifdef CONFIG_TREE_PREEMPT_RCU
  	seq_puts(m, "rcu_preempt:
  ");
  	PRINT_RCU_DATA(rcu_preempt_data, print_one_rcu_data, m);
  #endif /* #ifdef CONFIG_TREE_PREEMPT_RCU */
d6714c22b   Paul E. McKenney   rcu: Renamings to...
116
117
118
  	seq_puts(m, "rcu_sched:
  ");
  	PRINT_RCU_DATA(rcu_sched_data, print_one_rcu_data, m);
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
119
120
121
122
123
124
125
126
127
128
  	seq_puts(m, "rcu_bh:
  ");
  	PRINT_RCU_DATA(rcu_bh_data, print_one_rcu_data, m);
  	return 0;
  }
  
  static int rcudata_open(struct inode *inode, struct file *file)
  {
  	return single_open(file, show_rcudata, NULL);
  }
9b2619aff   Paul E. McKenney   rcu: Clean up cod...
129
  static const struct file_operations rcudata_fops = {
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
130
131
132
133
134
135
136
137
138
139
140
  	.owner = THIS_MODULE,
  	.open = rcudata_open,
  	.read = seq_read,
  	.llseek = seq_lseek,
  	.release = single_release,
  };
  
  static void print_one_rcu_data_csv(struct seq_file *m, struct rcu_data *rdp)
  {
  	if (!rdp->beenonline)
  		return;
20133cfce   Paul E. McKenney   rcu: Stop overflo...
141
  	seq_printf(m, "%d,%s,%lu,%lu,%d,%lu,%d",
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
142
  		   rdp->cpu,
5699ed8fc   Paul E. McKenney   rcu: Fix online/o...
143
  		   cpu_is_offline(rdp->cpu) ? "\"N\"" : "\"Y\"",
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
144
145
  		   rdp->completed, rdp->gpnum,
  		   rdp->passed_quiesc, rdp->passed_quiesc_completed,
ef631b0ca   Paul E. McKenney   rcu: Make hierarc...
146
  		   rdp->qs_pending);
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
147
148
  #ifdef CONFIG_NO_HZ
  	seq_printf(m, ",%d,%d,%d,%lu",
23b5c8fa0   Paul E. McKenney   rcu: Decrease mem...
149
  		   atomic_read(&rdp->dynticks->dynticks),
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
150
  		   rdp->dynticks->dynticks_nesting,
23b5c8fa0   Paul E. McKenney   rcu: Decrease mem...
151
  		   rdp->dynticks->dynticks_nmi_nesting,
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
152
153
154
  		   rdp->dynticks_fqs);
  #endif /* #ifdef CONFIG_NO_HZ */
  	seq_printf(m, ",%lu,%lu", rdp->offline_fqs, rdp->resched_ipi);
a46e0899e   Paul E. McKenney   rcu: use softirq ...
155
  	seq_printf(m, ",%ld,\"%c%c%c%c\"", rdp->qlen,
0ac3d136b   Paul E. McKenney   rcu: add callback...
156
157
158
159
160
161
  		   ".N"[rdp->nxttail[RCU_NEXT_READY_TAIL] !=
  			rdp->nxttail[RCU_NEXT_TAIL]],
  		   ".R"[rdp->nxttail[RCU_WAIT_TAIL] !=
  			rdp->nxttail[RCU_NEXT_READY_TAIL]],
  		   ".W"[rdp->nxttail[RCU_DONE_TAIL] !=
  			rdp->nxttail[RCU_WAIT_TAIL]],
a46e0899e   Paul E. McKenney   rcu: use softirq ...
162
163
164
  		   ".D"[&rdp->nxtlist != rdp->nxttail[RCU_DONE_TAIL]]);
  #ifdef CONFIG_RCU_BOOST
  	seq_printf(m, ",%d,\"%c\"",
d71df90ea   Paul E. McKenney   rcu: add tracing ...
165
166
  		   per_cpu(rcu_cpu_has_work, rdp->cpu),
  		   convert_kthread_status(per_cpu(rcu_cpu_kthread_status,
a46e0899e   Paul E. McKenney   rcu: use softirq ...
167
168
169
  					  rdp->cpu)));
  #endif /* #ifdef CONFIG_RCU_BOOST */
  	seq_printf(m, ",%ld", rdp->blimit);
269dcc1c2   Paul E. McKenney   rcu: Add tracing ...
170
171
172
  	seq_printf(m, ",%lu,%lu,%lu
  ",
  		   rdp->n_cbs_invoked, rdp->n_cbs_orphaned, rdp->n_cbs_adopted);
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
173
174
175
176
  }
  
  static int show_rcudata_csv(struct seq_file *m, void *unused)
  {
ef631b0ca   Paul E. McKenney   rcu: Make hierarc...
177
  	seq_puts(m, "\"CPU\",\"Online?\",\"c\",\"g\",\"pq\",\"pqc\",\"pq\",");
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
178
  #ifdef CONFIG_NO_HZ
23b5c8fa0   Paul E. McKenney   rcu: Decrease mem...
179
  	seq_puts(m, "\"dt\",\"dt nesting\",\"dt NMI nesting\",\"df\",");
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
180
  #endif /* #ifdef CONFIG_NO_HZ */
a46e0899e   Paul E. McKenney   rcu: use softirq ...
181
182
183
184
185
186
  	seq_puts(m, "\"of\",\"ri\",\"ql\",\"qs\"");
  #ifdef CONFIG_RCU_BOOST
  	seq_puts(m, "\"kt\",\"ktl\"");
  #endif /* #ifdef CONFIG_RCU_BOOST */
  	seq_puts(m, ",\"b\",\"ci\",\"co\",\"ca\"
  ");
f41d911f8   Paul E. McKenney   rcu: Merge preemp...
187
188
189
190
191
  #ifdef CONFIG_TREE_PREEMPT_RCU
  	seq_puts(m, "\"rcu_preempt:\"
  ");
  	PRINT_RCU_DATA(rcu_preempt_data, print_one_rcu_data_csv, m);
  #endif /* #ifdef CONFIG_TREE_PREEMPT_RCU */
d6714c22b   Paul E. McKenney   rcu: Renamings to...
192
193
194
  	seq_puts(m, "\"rcu_sched:\"
  ");
  	PRINT_RCU_DATA(rcu_sched_data, print_one_rcu_data_csv, m);
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
195
196
197
198
199
200
201
202
203
204
  	seq_puts(m, "\"rcu_bh:\"
  ");
  	PRINT_RCU_DATA(rcu_bh_data, print_one_rcu_data_csv, m);
  	return 0;
  }
  
  static int rcudata_csv_open(struct inode *inode, struct file *file)
  {
  	return single_open(file, show_rcudata_csv, NULL);
  }
9b2619aff   Paul E. McKenney   rcu: Clean up cod...
205
  static const struct file_operations rcudata_csv_fops = {
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
206
207
208
209
210
211
  	.owner = THIS_MODULE,
  	.open = rcudata_csv_open,
  	.read = seq_read,
  	.llseek = seq_lseek,
  	.release = single_release,
  };
0ea1f2ebe   Paul E. McKenney   rcu: Add boosting...
212
213
214
215
  #ifdef CONFIG_RCU_BOOST
  
  static void print_one_rcu_node_boost(struct seq_file *m, struct rcu_node *rnp)
  {
d71df90ea   Paul E. McKenney   rcu: add tracing ...
216
  	seq_printf(m,  "%d:%d tasks=%c%c%c%c kt=%c ntb=%lu neb=%lu nnb=%lu "
0ea1f2ebe   Paul E. McKenney   rcu: Add boosting...
217
218
219
220
221
222
223
  		   "j=%04x bt=%04x
  ",
  		   rnp->grplo, rnp->grphi,
  		   "T."[list_empty(&rnp->blkd_tasks)],
  		   "N."[!rnp->gp_tasks],
  		   "E."[!rnp->exp_tasks],
  		   "B."[!rnp->boost_tasks],
d71df90ea   Paul E. McKenney   rcu: add tracing ...
224
  		   convert_kthread_status(rnp->boost_kthread_status),
0ea1f2ebe   Paul E. McKenney   rcu: Add boosting...
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
  		   rnp->n_tasks_boosted, rnp->n_exp_boosts,
  		   rnp->n_normal_boosts,
  		   (int)(jiffies & 0xffff),
  		   (int)(rnp->boost_time & 0xffff));
  	seq_printf(m, "%s: nt=%lu egt=%lu bt=%lu nb=%lu ny=%lu nos=%lu
  ",
  		   "     balk",
  		   rnp->n_balk_blkd_tasks,
  		   rnp->n_balk_exp_gp_tasks,
  		   rnp->n_balk_boost_tasks,
  		   rnp->n_balk_notblocked,
  		   rnp->n_balk_notyet,
  		   rnp->n_balk_nos);
  }
  
  static int show_rcu_node_boost(struct seq_file *m, void *unused)
  {
  	struct rcu_node *rnp;
  
  	rcu_for_each_leaf_node(&rcu_preempt_state, rnp)
  		print_one_rcu_node_boost(m, rnp);
  	return 0;
  }
  
  static int rcu_node_boost_open(struct inode *inode, struct file *file)
  {
  	return single_open(file, show_rcu_node_boost, NULL);
  }
  
  static const struct file_operations rcu_node_boost_fops = {
  	.owner = THIS_MODULE,
  	.open = rcu_node_boost_open,
  	.read = seq_read,
  	.llseek = seq_lseek,
  	.release = single_release,
  };
  
  /*
   * Create the rcuboost debugfs entry.  Standard error return.
   */
  static int rcu_boost_trace_create_file(struct dentry *rcudir)
  {
  	return !debugfs_create_file("rcuboost", 0444, rcudir, NULL,
  				    &rcu_node_boost_fops);
  }
  
  #else /* #ifdef CONFIG_RCU_BOOST */
  
  static int rcu_boost_trace_create_file(struct dentry *rcudir)
  {
  	return 0;  /* There cannot be an error if we didn't create it! */
  }
  
  #endif /* #else #ifdef CONFIG_RCU_BOOST */
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
279
280
  static void print_one_rcu_state(struct seq_file *m, struct rcu_state *rsp)
  {
20133cfce   Paul E. McKenney   rcu: Stop overflo...
281
  	unsigned long gpnum;
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
282
283
  	int level = 0;
  	struct rcu_node *rnp;
3397e040d   Paul E. McKenney   rcu: Add rnp->blo...
284
  	gpnum = rsp->gpnum;
20133cfce   Paul E. McKenney   rcu: Stop overflo...
285
  	seq_printf(m, "c=%lu g=%lu s=%d jfq=%ld j=%x "
29494be71   Lai Jiangshan   rcu,cleanup: simp...
286
287
  		      "nfqs=%lu/nfqsng=%lu(%lu) fqlh=%lu
  ",
3397e040d   Paul E. McKenney   rcu: Add rnp->blo...
288
  		   rsp->completed, gpnum, rsp->signaled,
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
289
290
291
292
  		   (long)(rsp->jiffies_force_qs - jiffies),
  		   (int)(jiffies & 0xffff),
  		   rsp->n_force_qs, rsp->n_force_qs_ngp,
  		   rsp->n_force_qs - rsp->n_force_qs_ngp,
29494be71   Lai Jiangshan   rcu,cleanup: simp...
293
  		   rsp->n_force_qs_lh);
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
294
295
296
297
298
299
  	for (rnp = &rsp->node[0]; rnp - &rsp->node[0] < NUM_RCU_NODES; rnp++) {
  		if (rnp->level != level) {
  			seq_puts(m, "
  ");
  			level = rnp->level;
  		}
12f5f524c   Paul E. McKenney   rcu: merge TREE_P...
300
  		seq_printf(m, "%lx/%lx %c%c>%c %d:%d ^%d    ",
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
301
  			   rnp->qsmask, rnp->qsmaskinit,
12f5f524c   Paul E. McKenney   rcu: merge TREE_P...
302
303
304
  			   ".G"[rnp->gp_tasks != NULL],
  			   ".E"[rnp->exp_tasks != NULL],
  			   ".T"[!list_empty(&rnp->blkd_tasks)],
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
305
306
307
308
309
310
311
312
  			   rnp->grplo, rnp->grphi, rnp->grpnum);
  	}
  	seq_puts(m, "
  ");
  }
  
  static int show_rcuhier(struct seq_file *m, void *unused)
  {
f41d911f8   Paul E. McKenney   rcu: Merge preemp...
313
314
315
316
317
  #ifdef CONFIG_TREE_PREEMPT_RCU
  	seq_puts(m, "rcu_preempt:
  ");
  	print_one_rcu_state(m, &rcu_preempt_state);
  #endif /* #ifdef CONFIG_TREE_PREEMPT_RCU */
d6714c22b   Paul E. McKenney   rcu: Renamings to...
318
319
320
  	seq_puts(m, "rcu_sched:
  ");
  	print_one_rcu_state(m, &rcu_sched_state);
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
321
322
323
324
325
326
327
328
329
330
  	seq_puts(m, "rcu_bh:
  ");
  	print_one_rcu_state(m, &rcu_bh_state);
  	return 0;
  }
  
  static int rcuhier_open(struct inode *inode, struct file *file)
  {
  	return single_open(file, show_rcuhier, NULL);
  }
9b2619aff   Paul E. McKenney   rcu: Clean up cod...
331
  static const struct file_operations rcuhier_fops = {
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
332
333
334
335
336
337
  	.owner = THIS_MODULE,
  	.open = rcuhier_open,
  	.read = seq_read,
  	.llseek = seq_lseek,
  	.release = single_release,
  };
15ba0ba86   Paul E. McKenney   rcu: add grace-pe...
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
  static void show_one_rcugp(struct seq_file *m, struct rcu_state *rsp)
  {
  	unsigned long flags;
  	unsigned long completed;
  	unsigned long gpnum;
  	unsigned long gpage;
  	unsigned long gpmax;
  	struct rcu_node *rnp = &rsp->node[0];
  
  	raw_spin_lock_irqsave(&rnp->lock, flags);
  	completed = rsp->completed;
  	gpnum = rsp->gpnum;
  	if (rsp->completed == rsp->gpnum)
  		gpage = 0;
  	else
  		gpage = jiffies - rsp->gp_start;
  	gpmax = rsp->gp_max;
  	raw_spin_unlock_irqrestore(&rnp->lock, flags);
  	seq_printf(m, "%s: completed=%ld  gpnum=%lu  age=%ld  max=%ld
  ",
  		   rsp->name, completed, gpnum, gpage, gpmax);
  }
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
360
361
  static int show_rcugp(struct seq_file *m, void *unused)
  {
f41d911f8   Paul E. McKenney   rcu: Merge preemp...
362
  #ifdef CONFIG_TREE_PREEMPT_RCU
15ba0ba86   Paul E. McKenney   rcu: add grace-pe...
363
  	show_one_rcugp(m, &rcu_preempt_state);
f41d911f8   Paul E. McKenney   rcu: Merge preemp...
364
  #endif /* #ifdef CONFIG_TREE_PREEMPT_RCU */
15ba0ba86   Paul E. McKenney   rcu: add grace-pe...
365
366
  	show_one_rcugp(m, &rcu_sched_state);
  	show_one_rcugp(m, &rcu_bh_state);
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
367
368
369
370
371
372
373
  	return 0;
  }
  
  static int rcugp_open(struct inode *inode, struct file *file)
  {
  	return single_open(file, show_rcugp, NULL);
  }
9b2619aff   Paul E. McKenney   rcu: Clean up cod...
374
  static const struct file_operations rcugp_fops = {
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
375
376
377
378
379
380
  	.owner = THIS_MODULE,
  	.open = rcugp_open,
  	.read = seq_read,
  	.llseek = seq_lseek,
  	.release = single_release,
  };
7ba5c840e   Paul E. McKenney   rcu: Add __rcu_pe...
381
382
383
  static void print_one_rcu_pending(struct seq_file *m, struct rcu_data *rdp)
  {
  	seq_printf(m, "%3d%cnp=%ld "
d21670aca   Paul E. McKenney   rcu: reduce the n...
384
385
386
  		   "qsp=%ld rpq=%ld cbr=%ld cng=%ld "
  		   "gpc=%ld gps=%ld nf=%ld nn=%ld
  ",
7ba5c840e   Paul E. McKenney   rcu: Add __rcu_pe...
387
388
389
390
  		   rdp->cpu,
  		   cpu_is_offline(rdp->cpu) ? '!' : ' ',
  		   rdp->n_rcu_pending,
  		   rdp->n_rp_qs_pending,
d21670aca   Paul E. McKenney   rcu: reduce the n...
391
  		   rdp->n_rp_report_qs,
7ba5c840e   Paul E. McKenney   rcu: Add __rcu_pe...
392
393
394
395
396
397
398
399
400
401
402
403
404
405
  		   rdp->n_rp_cb_ready,
  		   rdp->n_rp_cpu_needs_gp,
  		   rdp->n_rp_gp_completed,
  		   rdp->n_rp_gp_started,
  		   rdp->n_rp_need_fqs,
  		   rdp->n_rp_need_nothing);
  }
  
  static void print_rcu_pendings(struct seq_file *m, struct rcu_state *rsp)
  {
  	int cpu;
  	struct rcu_data *rdp;
  
  	for_each_possible_cpu(cpu) {
394f99a90   Lai Jiangshan   rcu: simplify the...
406
  		rdp = per_cpu_ptr(rsp->rda, cpu);
7ba5c840e   Paul E. McKenney   rcu: Add __rcu_pe...
407
408
409
410
411
412
413
  		if (rdp->beenonline)
  			print_one_rcu_pending(m, rdp);
  	}
  }
  
  static int show_rcu_pending(struct seq_file *m, void *unused)
  {
f41d911f8   Paul E. McKenney   rcu: Merge preemp...
414
415
416
417
418
  #ifdef CONFIG_TREE_PREEMPT_RCU
  	seq_puts(m, "rcu_preempt:
  ");
  	print_rcu_pendings(m, &rcu_preempt_state);
  #endif /* #ifdef CONFIG_TREE_PREEMPT_RCU */
d6714c22b   Paul E. McKenney   rcu: Renamings to...
419
420
421
  	seq_puts(m, "rcu_sched:
  ");
  	print_rcu_pendings(m, &rcu_sched_state);
7ba5c840e   Paul E. McKenney   rcu: Add __rcu_pe...
422
423
424
425
426
427
428
429
430
431
  	seq_puts(m, "rcu_bh:
  ");
  	print_rcu_pendings(m, &rcu_bh_state);
  	return 0;
  }
  
  static int rcu_pending_open(struct inode *inode, struct file *file)
  {
  	return single_open(file, show_rcu_pending, NULL);
  }
9b2619aff   Paul E. McKenney   rcu: Clean up cod...
432
  static const struct file_operations rcu_pending_fops = {
7ba5c840e   Paul E. McKenney   rcu: Add __rcu_pe...
433
434
435
436
437
438
  	.owner = THIS_MODULE,
  	.open = rcu_pending_open,
  	.read = seq_read,
  	.llseek = seq_lseek,
  	.release = single_release,
  };
4a2986568   Paul E. McKenney   rcu: make rcutort...
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
  static int show_rcutorture(struct seq_file *m, void *unused)
  {
  	seq_printf(m, "rcutorture test sequence: %lu %s
  ",
  		   rcutorture_testseq >> 1,
  		   (rcutorture_testseq & 0x1) ? "(test in progress)" : "");
  	seq_printf(m, "rcutorture update version number: %lu
  ",
  		   rcutorture_vernum);
  	return 0;
  }
  
  static int rcutorture_open(struct inode *inode, struct file *file)
  {
  	return single_open(file, show_rcutorture, NULL);
  }
  
  static const struct file_operations rcutorture_fops = {
  	.owner = THIS_MODULE,
  	.open = rcutorture_open,
  	.read = seq_read,
  	.llseek = seq_lseek,
  	.release = single_release,
  };
7ba5c840e   Paul E. McKenney   rcu: Add __rcu_pe...
463
  static struct dentry *rcudir;
7ba5c840e   Paul E. McKenney   rcu: Add __rcu_pe...
464

deb7a4181   Paul E. McKenney   rcu: get rid of o...
465
  static int __init rcutree_trace_init(void)
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
466
  {
22f00b69f   Paul E. McKenney   rcu: Use debugfs_...
467
  	struct dentry *retval;
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
468
469
  	rcudir = debugfs_create_dir("rcu", NULL);
  	if (!rcudir)
22f00b69f   Paul E. McKenney   rcu: Use debugfs_...
470
  		goto free_out;
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
471

22f00b69f   Paul E. McKenney   rcu: Use debugfs_...
472
  	retval = debugfs_create_file("rcudata", 0444, rcudir,
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
473
  						NULL, &rcudata_fops);
22f00b69f   Paul E. McKenney   rcu: Use debugfs_...
474
  	if (!retval)
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
475
  		goto free_out;
22f00b69f   Paul E. McKenney   rcu: Use debugfs_...
476
  	retval = debugfs_create_file("rcudata.csv", 0444, rcudir,
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
477
  						NULL, &rcudata_csv_fops);
22f00b69f   Paul E. McKenney   rcu: Use debugfs_...
478
  	if (!retval)
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
479
  		goto free_out;
0ea1f2ebe   Paul E. McKenney   rcu: Add boosting...
480
481
  	if (rcu_boost_trace_create_file(rcudir))
  		goto free_out;
22f00b69f   Paul E. McKenney   rcu: Use debugfs_...
482
483
  	retval = debugfs_create_file("rcugp", 0444, rcudir, NULL, &rcugp_fops);
  	if (!retval)
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
484
  		goto free_out;
22f00b69f   Paul E. McKenney   rcu: Use debugfs_...
485
  	retval = debugfs_create_file("rcuhier", 0444, rcudir,
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
486
  						NULL, &rcuhier_fops);
22f00b69f   Paul E. McKenney   rcu: Use debugfs_...
487
  	if (!retval)
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
488
  		goto free_out;
7ba5c840e   Paul E. McKenney   rcu: Add __rcu_pe...
489

22f00b69f   Paul E. McKenney   rcu: Use debugfs_...
490
  	retval = debugfs_create_file("rcu_pending", 0444, rcudir,
7ba5c840e   Paul E. McKenney   rcu: Add __rcu_pe...
491
  						NULL, &rcu_pending_fops);
22f00b69f   Paul E. McKenney   rcu: Use debugfs_...
492
  	if (!retval)
7ba5c840e   Paul E. McKenney   rcu: Add __rcu_pe...
493
  		goto free_out;
4a2986568   Paul E. McKenney   rcu: make rcutort...
494
495
496
497
498
  
  	retval = debugfs_create_file("rcutorture", 0444, rcudir,
  						NULL, &rcutorture_fops);
  	if (!retval)
  		goto free_out;
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
499
500
  	return 0;
  free_out:
22f00b69f   Paul E. McKenney   rcu: Use debugfs_...
501
  	debugfs_remove_recursive(rcudir);
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
502
503
  	return 1;
  }
deb7a4181   Paul E. McKenney   rcu: get rid of o...
504
  static void __exit rcutree_trace_cleanup(void)
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
505
  {
22f00b69f   Paul E. McKenney   rcu: Use debugfs_...
506
  	debugfs_remove_recursive(rcudir);
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
507
  }
deb7a4181   Paul E. McKenney   rcu: get rid of o...
508
509
  module_init(rcutree_trace_init);
  module_exit(rcutree_trace_cleanup);
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
510
511
512
513
  
  MODULE_AUTHOR("Paul E. McKenney");
  MODULE_DESCRIPTION("Read-Copy Update tracing for hierarchical implementation");
  MODULE_LICENSE("GPL");