Blame view

kernel/rcutree_trace.c 13.8 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
49
50
51
  static char convert_kthread_status(unsigned int kthread_status)
  {
  	if (kthread_status > RCU_KTHREAD_MAX)
  		return '?';
15ba0ba86   Paul E. McKenney   rcu: add grace-pe...
52
  	return "SRWOY"[kthread_status];
d71df90ea   Paul E. McKenney   rcu: add tracing ...
53
  }
a46e0899e   Paul E. McKenney   rcu: use softirq ...
54
  #endif /* #ifdef CONFIG_RCU_BOOST */
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
55
56
57
58
  static void print_one_rcu_data(struct seq_file *m, struct rcu_data *rdp)
  {
  	if (!rdp->beenonline)
  		return;
e4cc1f22b   Paul E. McKenney   rcu: Simplify qui...
59
  	seq_printf(m, "%3d%cc=%lu g=%lu pq=%d pgp=%lu qp=%d",
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
60
61
62
  		   rdp->cpu,
  		   cpu_is_offline(rdp->cpu) ? '!' : ' ',
  		   rdp->completed, rdp->gpnum,
e4cc1f22b   Paul E. McKenney   rcu: Simplify qui...
63
  		   rdp->passed_quiesce, rdp->passed_quiesce_gpnum,
ef631b0ca   Paul E. McKenney   rcu: Make hierarc...
64
  		   rdp->qs_pending);
9b2e4f188   Paul E. McKenney   rcu: Track idlene...
65
  	seq_printf(m, " dt=%d/%llx/%d df=%lu",
23b5c8fa0   Paul E. McKenney   rcu: Decrease mem...
66
  		   atomic_read(&rdp->dynticks->dynticks),
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
67
  		   rdp->dynticks->dynticks_nesting,
23b5c8fa0   Paul E. McKenney   rcu: Decrease mem...
68
  		   rdp->dynticks->dynticks_nmi_nesting,
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
69
  		   rdp->dynticks_fqs);
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
70
  	seq_printf(m, " of=%lu ri=%lu", rdp->offline_fqs, rdp->resched_ipi);
a46e0899e   Paul E. McKenney   rcu: use softirq ...
71
  	seq_printf(m, " ql=%ld qs=%c%c%c%c",
0ac3d136b   Paul E. McKenney   rcu: add callback...
72
73
74
75
76
77
78
  		   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 ...
79
80
81
  		   ".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 ...
82
83
84
  		   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...
85
  		   per_cpu(rcu_cpu_kthread_cpu, rdp->cpu),
a46e0899e   Paul E. McKenney   rcu: use softirq ...
86
87
88
  		   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 ...
89
90
91
  	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...
92
93
94
95
96
97
98
99
100
101
102
103
  }
  
  #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...
104
105
106
107
108
  #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...
109
110
111
  	seq_puts(m, "rcu_sched:
  ");
  	PRINT_RCU_DATA(rcu_sched_data, print_one_rcu_data, m);
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
112
113
114
115
116
117
118
119
120
121
  	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...
122
  static const struct file_operations rcudata_fops = {
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
123
124
125
126
127
128
129
130
131
132
133
  	.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...
134
  	seq_printf(m, "%d,%s,%lu,%lu,%d,%lu,%d",
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
135
  		   rdp->cpu,
5699ed8fc   Paul E. McKenney   rcu: Fix online/o...
136
  		   cpu_is_offline(rdp->cpu) ? "\"N\"" : "\"Y\"",
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
137
  		   rdp->completed, rdp->gpnum,
e4cc1f22b   Paul E. McKenney   rcu: Simplify qui...
138
  		   rdp->passed_quiesce, rdp->passed_quiesce_gpnum,
ef631b0ca   Paul E. McKenney   rcu: Make hierarc...
139
  		   rdp->qs_pending);
9b2e4f188   Paul E. McKenney   rcu: Track idlene...
140
  	seq_printf(m, ",%d,%llx,%d,%lu",
23b5c8fa0   Paul E. McKenney   rcu: Decrease mem...
141
  		   atomic_read(&rdp->dynticks->dynticks),
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
142
  		   rdp->dynticks->dynticks_nesting,
23b5c8fa0   Paul E. McKenney   rcu: Decrease mem...
143
  		   rdp->dynticks->dynticks_nmi_nesting,
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
144
  		   rdp->dynticks_fqs);
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
145
  	seq_printf(m, ",%lu,%lu", rdp->offline_fqs, rdp->resched_ipi);
a46e0899e   Paul E. McKenney   rcu: use softirq ...
146
  	seq_printf(m, ",%ld,\"%c%c%c%c\"", rdp->qlen,
0ac3d136b   Paul E. McKenney   rcu: add callback...
147
148
149
150
151
152
  		   ".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 ...
153
154
155
  		   ".D"[&rdp->nxtlist != rdp->nxttail[RCU_DONE_TAIL]]);
  #ifdef CONFIG_RCU_BOOST
  	seq_printf(m, ",%d,\"%c\"",
d71df90ea   Paul E. McKenney   rcu: add tracing ...
156
157
  		   per_cpu(rcu_cpu_has_work, rdp->cpu),
  		   convert_kthread_status(per_cpu(rcu_cpu_kthread_status,
a46e0899e   Paul E. McKenney   rcu: use softirq ...
158
159
160
  					  rdp->cpu)));
  #endif /* #ifdef CONFIG_RCU_BOOST */
  	seq_printf(m, ",%ld", rdp->blimit);
269dcc1c2   Paul E. McKenney   rcu: Add tracing ...
161
162
163
  	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...
164
165
166
167
  }
  
  static int show_rcudata_csv(struct seq_file *m, void *unused)
  {
e4cc1f22b   Paul E. McKenney   rcu: Simplify qui...
168
  	seq_puts(m, "\"CPU\",\"Online?\",\"c\",\"g\",\"pq\",\"pgp\",\"pq\",");
23b5c8fa0   Paul E. McKenney   rcu: Decrease mem...
169
  	seq_puts(m, "\"dt\",\"dt nesting\",\"dt NMI nesting\",\"df\",");
a46e0899e   Paul E. McKenney   rcu: use softirq ...
170
171
172
173
174
175
  	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...
176
177
178
179
180
  #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...
181
182
183
  	seq_puts(m, "\"rcu_sched:\"
  ");
  	PRINT_RCU_DATA(rcu_sched_data, print_one_rcu_data_csv, m);
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
184
185
186
187
188
189
190
191
192
193
  	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...
194
  static const struct file_operations rcudata_csv_fops = {
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
195
196
197
198
199
200
  	.owner = THIS_MODULE,
  	.open = rcudata_csv_open,
  	.read = seq_read,
  	.llseek = seq_lseek,
  	.release = single_release,
  };
0ea1f2ebe   Paul E. McKenney   rcu: Add boosting...
201
202
203
204
  #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 ...
205
  	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...
206
207
208
209
210
211
212
  		   "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 ...
213
  		   convert_kthread_status(rnp->boost_kthread_status),
0ea1f2ebe   Paul E. McKenney   rcu: Add boosting...
214
215
216
217
218
219
220
221
222
223
224
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
  		   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...
268
269
  static void print_one_rcu_state(struct seq_file *m, struct rcu_state *rsp)
  {
20133cfce   Paul E. McKenney   rcu: Stop overflo...
270
  	unsigned long gpnum;
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
271
272
  	int level = 0;
  	struct rcu_node *rnp;
3397e040d   Paul E. McKenney   rcu: Add rnp->blo...
273
  	gpnum = rsp->gpnum;
20133cfce   Paul E. McKenney   rcu: Stop overflo...
274
  	seq_printf(m, "c=%lu g=%lu s=%d jfq=%ld j=%x "
29494be71   Lai Jiangshan   rcu,cleanup: simp...
275
276
  		      "nfqs=%lu/nfqsng=%lu(%lu) fqlh=%lu
  ",
af446b702   Paul E. McKenney   rcu: ->signaled b...
277
  		   rsp->completed, gpnum, rsp->fqs_state,
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
278
279
280
281
  		   (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...
282
  		   rsp->n_force_qs_lh);
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
283
284
285
286
287
288
  	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...
289
  		seq_printf(m, "%lx/%lx %c%c>%c %d:%d ^%d    ",
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
290
  			   rnp->qsmask, rnp->qsmaskinit,
12f5f524c   Paul E. McKenney   rcu: merge TREE_P...
291
292
293
  			   ".G"[rnp->gp_tasks != NULL],
  			   ".E"[rnp->exp_tasks != NULL],
  			   ".T"[!list_empty(&rnp->blkd_tasks)],
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
294
295
296
297
298
299
300
301
  			   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...
302
303
304
305
306
  #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...
307
308
309
  	seq_puts(m, "rcu_sched:
  ");
  	print_one_rcu_state(m, &rcu_sched_state);
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
310
311
312
313
314
315
316
317
318
319
  	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...
320
  static const struct file_operations rcuhier_fops = {
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
321
322
323
324
325
326
  	.owner = THIS_MODULE,
  	.open = rcuhier_open,
  	.read = seq_read,
  	.llseek = seq_lseek,
  	.release = single_release,
  };
15ba0ba86   Paul E. McKenney   rcu: add grace-pe...
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
  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...
349
350
  static int show_rcugp(struct seq_file *m, void *unused)
  {
f41d911f8   Paul E. McKenney   rcu: Merge preemp...
351
  #ifdef CONFIG_TREE_PREEMPT_RCU
15ba0ba86   Paul E. McKenney   rcu: add grace-pe...
352
  	show_one_rcugp(m, &rcu_preempt_state);
f41d911f8   Paul E. McKenney   rcu: Merge preemp...
353
  #endif /* #ifdef CONFIG_TREE_PREEMPT_RCU */
15ba0ba86   Paul E. McKenney   rcu: add grace-pe...
354
355
  	show_one_rcugp(m, &rcu_sched_state);
  	show_one_rcugp(m, &rcu_bh_state);
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
356
357
358
359
360
361
362
  	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...
363
  static const struct file_operations rcugp_fops = {
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
364
365
366
367
368
369
  	.owner = THIS_MODULE,
  	.open = rcugp_open,
  	.read = seq_read,
  	.llseek = seq_lseek,
  	.release = single_release,
  };
7ba5c840e   Paul E. McKenney   rcu: Add __rcu_pe...
370
371
372
  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...
373
374
375
  		   "qsp=%ld rpq=%ld cbr=%ld cng=%ld "
  		   "gpc=%ld gps=%ld nf=%ld nn=%ld
  ",
7ba5c840e   Paul E. McKenney   rcu: Add __rcu_pe...
376
377
378
379
  		   rdp->cpu,
  		   cpu_is_offline(rdp->cpu) ? '!' : ' ',
  		   rdp->n_rcu_pending,
  		   rdp->n_rp_qs_pending,
d21670aca   Paul E. McKenney   rcu: reduce the n...
380
  		   rdp->n_rp_report_qs,
7ba5c840e   Paul E. McKenney   rcu: Add __rcu_pe...
381
382
383
384
385
386
387
388
389
390
391
392
393
394
  		   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...
395
  		rdp = per_cpu_ptr(rsp->rda, cpu);
7ba5c840e   Paul E. McKenney   rcu: Add __rcu_pe...
396
397
398
399
400
401
402
  		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...
403
404
405
406
407
  #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...
408
409
410
  	seq_puts(m, "rcu_sched:
  ");
  	print_rcu_pendings(m, &rcu_sched_state);
7ba5c840e   Paul E. McKenney   rcu: Add __rcu_pe...
411
412
413
414
415
416
417
418
419
420
  	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...
421
  static const struct file_operations rcu_pending_fops = {
7ba5c840e   Paul E. McKenney   rcu: Add __rcu_pe...
422
423
424
425
426
427
  	.owner = THIS_MODULE,
  	.open = rcu_pending_open,
  	.read = seq_read,
  	.llseek = seq_lseek,
  	.release = single_release,
  };
4a2986568   Paul E. McKenney   rcu: make rcutort...
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
  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...
452
  static struct dentry *rcudir;
7ba5c840e   Paul E. McKenney   rcu: Add __rcu_pe...
453

deb7a4181   Paul E. McKenney   rcu: get rid of o...
454
  static int __init rcutree_trace_init(void)
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
455
  {
22f00b69f   Paul E. McKenney   rcu: Use debugfs_...
456
  	struct dentry *retval;
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
457
458
  	rcudir = debugfs_create_dir("rcu", NULL);
  	if (!rcudir)
22f00b69f   Paul E. McKenney   rcu: Use debugfs_...
459
  		goto free_out;
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
460

22f00b69f   Paul E. McKenney   rcu: Use debugfs_...
461
  	retval = debugfs_create_file("rcudata", 0444, rcudir,
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
462
  						NULL, &rcudata_fops);
22f00b69f   Paul E. McKenney   rcu: Use debugfs_...
463
  	if (!retval)
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
464
  		goto free_out;
22f00b69f   Paul E. McKenney   rcu: Use debugfs_...
465
  	retval = debugfs_create_file("rcudata.csv", 0444, rcudir,
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
466
  						NULL, &rcudata_csv_fops);
22f00b69f   Paul E. McKenney   rcu: Use debugfs_...
467
  	if (!retval)
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
468
  		goto free_out;
0ea1f2ebe   Paul E. McKenney   rcu: Add boosting...
469
470
  	if (rcu_boost_trace_create_file(rcudir))
  		goto free_out;
22f00b69f   Paul E. McKenney   rcu: Use debugfs_...
471
472
  	retval = debugfs_create_file("rcugp", 0444, rcudir, NULL, &rcugp_fops);
  	if (!retval)
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
473
  		goto free_out;
22f00b69f   Paul E. McKenney   rcu: Use debugfs_...
474
  	retval = debugfs_create_file("rcuhier", 0444, rcudir,
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
475
  						NULL, &rcuhier_fops);
22f00b69f   Paul E. McKenney   rcu: Use debugfs_...
476
  	if (!retval)
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
477
  		goto free_out;
7ba5c840e   Paul E. McKenney   rcu: Add __rcu_pe...
478

22f00b69f   Paul E. McKenney   rcu: Use debugfs_...
479
  	retval = debugfs_create_file("rcu_pending", 0444, rcudir,
7ba5c840e   Paul E. McKenney   rcu: Add __rcu_pe...
480
  						NULL, &rcu_pending_fops);
22f00b69f   Paul E. McKenney   rcu: Use debugfs_...
481
  	if (!retval)
7ba5c840e   Paul E. McKenney   rcu: Add __rcu_pe...
482
  		goto free_out;
4a2986568   Paul E. McKenney   rcu: make rcutort...
483
484
485
486
487
  
  	retval = debugfs_create_file("rcutorture", 0444, rcudir,
  						NULL, &rcutorture_fops);
  	if (!retval)
  		goto free_out;
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
488
489
  	return 0;
  free_out:
22f00b69f   Paul E. McKenney   rcu: Use debugfs_...
490
  	debugfs_remove_recursive(rcudir);
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
491
492
  	return 1;
  }
deb7a4181   Paul E. McKenney   rcu: get rid of o...
493
  static void __exit rcutree_trace_cleanup(void)
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
494
  {
22f00b69f   Paul E. McKenney   rcu: Use debugfs_...
495
  	debugfs_remove_recursive(rcudir);
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
496
  }
deb7a4181   Paul E. McKenney   rcu: get rid of o...
497
498
  module_init(rcutree_trace_init);
  module_exit(rcutree_trace_cleanup);
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
499
500
501
502
  
  MODULE_AUTHOR("Paul E. McKenney");
  MODULE_DESCRIPTION("Read-Copy Update tracing for hierarchical implementation");
  MODULE_LICENSE("GPL");