Blame view

kernel/rcutree_trace.c 9.46 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
34
35
36
37
38
39
40
41
42
43
44
   *
   */
  #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>
  #include <asm/atomic.h>
  #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"
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
47
48
49
50
  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...
51
  	seq_printf(m, "%3d%cc=%lu g=%lu pq=%d pqc=%lu qp=%d",
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
52
53
54
55
  		   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...
56
  		   rdp->qs_pending);
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
  #ifdef CONFIG_NO_HZ
  	seq_printf(m, " dt=%d/%d dn=%d df=%lu",
  		   rdp->dynticks->dynticks,
  		   rdp->dynticks->dynticks_nesting,
  		   rdp->dynticks->dynticks_nmi,
  		   rdp->dynticks_fqs);
  #endif /* #ifdef CONFIG_NO_HZ */
  	seq_printf(m, " of=%lu ri=%lu", rdp->offline_fqs, rdp->resched_ipi);
  	seq_printf(m, " ql=%ld b=%ld
  ", rdp->qlen, rdp->blimit);
  }
  
  #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...
79
80
81
82
83
  #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...
84
85
86
  	seq_puts(m, "rcu_sched:
  ");
  	PRINT_RCU_DATA(rcu_sched_data, print_one_rcu_data, m);
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
87
88
89
90
91
92
93
94
95
96
  	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...
97
  static const struct file_operations rcudata_fops = {
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
98
99
100
101
102
103
104
105
106
107
108
  	.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...
109
  	seq_printf(m, "%d,%s,%lu,%lu,%d,%lu,%d",
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
110
  		   rdp->cpu,
5699ed8fc   Paul E. McKenney   rcu: Fix online/o...
111
  		   cpu_is_offline(rdp->cpu) ? "\"N\"" : "\"Y\"",
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
112
113
  		   rdp->completed, rdp->gpnum,
  		   rdp->passed_quiesc, rdp->passed_quiesc_completed,
ef631b0ca   Paul E. McKenney   rcu: Make hierarc...
114
  		   rdp->qs_pending);
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
115
116
117
118
119
120
121
122
123
124
125
126
127
128
  #ifdef CONFIG_NO_HZ
  	seq_printf(m, ",%d,%d,%d,%lu",
  		   rdp->dynticks->dynticks,
  		   rdp->dynticks->dynticks_nesting,
  		   rdp->dynticks->dynticks_nmi,
  		   rdp->dynticks_fqs);
  #endif /* #ifdef CONFIG_NO_HZ */
  	seq_printf(m, ",%lu,%lu", rdp->offline_fqs, rdp->resched_ipi);
  	seq_printf(m, ",%ld,%ld
  ", rdp->qlen, rdp->blimit);
  }
  
  static int show_rcudata_csv(struct seq_file *m, void *unused)
  {
ef631b0ca   Paul E. McKenney   rcu: Make hierarc...
129
  	seq_puts(m, "\"CPU\",\"Online?\",\"c\",\"g\",\"pq\",\"pqc\",\"pq\",");
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
130
131
132
133
134
  #ifdef CONFIG_NO_HZ
  	seq_puts(m, "\"dt\",\"dt nesting\",\"dn\",\"df\",");
  #endif /* #ifdef CONFIG_NO_HZ */
  	seq_puts(m, "\"of\",\"ri\",\"ql\",\"b\"
  ");
f41d911f8   Paul E. McKenney   rcu: Merge preemp...
135
136
137
138
139
  #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...
140
141
142
  	seq_puts(m, "\"rcu_sched:\"
  ");
  	PRINT_RCU_DATA(rcu_sched_data, print_one_rcu_data_csv, m);
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
143
144
145
146
147
148
149
150
151
152
  	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...
153
  static const struct file_operations rcudata_csv_fops = {
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
154
155
156
157
158
159
160
161
162
  	.owner = THIS_MODULE,
  	.open = rcudata_csv_open,
  	.read = seq_read,
  	.llseek = seq_lseek,
  	.release = single_release,
  };
  
  static void print_one_rcu_state(struct seq_file *m, struct rcu_state *rsp)
  {
20133cfce   Paul E. McKenney   rcu: Stop overflo...
163
  	unsigned long gpnum;
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
164
  	int level = 0;
d9a3da069   Paul E. McKenney   rcu: Add expedite...
165
  	int phase;
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
166
  	struct rcu_node *rnp;
3397e040d   Paul E. McKenney   rcu: Add rnp->blo...
167
  	gpnum = rsp->gpnum;
20133cfce   Paul E. McKenney   rcu: Stop overflo...
168
  	seq_printf(m, "c=%lu g=%lu s=%d jfq=%ld j=%x "
e74f4c456   Paul E. McKenney   rcu: Make hot-unp...
169
170
  		      "nfqs=%lu/nfqsng=%lu(%lu) fqlh=%lu oqlen=%ld
  ",
3397e040d   Paul E. McKenney   rcu: Add rnp->blo...
171
  		   rsp->completed, gpnum, rsp->signaled,
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
172
173
174
175
  		   (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,
e74f4c456   Paul E. McKenney   rcu: Make hot-unp...
176
  		   rsp->n_force_qs_lh, rsp->orphan_qlen);
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
177
178
179
180
181
182
  	for (rnp = &rsp->node[0]; rnp - &rsp->node[0] < NUM_RCU_NODES; rnp++) {
  		if (rnp->level != level) {
  			seq_puts(m, "
  ");
  			level = rnp->level;
  		}
d9a3da069   Paul E. McKenney   rcu: Add expedite...
183
184
  		phase = gpnum & 0x1;
  		seq_printf(m, "%lx/%lx %c%c>%c%c %d:%d ^%d    ",
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
185
  			   rnp->qsmask, rnp->qsmaskinit,
d9a3da069   Paul E. McKenney   rcu: Add expedite...
186
187
188
189
  			   "T."[list_empty(&rnp->blocked_tasks[phase])],
  			   "E."[list_empty(&rnp->blocked_tasks[phase + 2])],
  			   "T."[list_empty(&rnp->blocked_tasks[!phase])],
  			   "E."[list_empty(&rnp->blocked_tasks[!phase + 2])],
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
190
191
192
193
194
195
196
197
  			   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...
198
199
200
201
202
  #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...
203
204
205
  	seq_puts(m, "rcu_sched:
  ");
  	print_one_rcu_state(m, &rcu_sched_state);
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
206
207
208
209
210
211
212
213
214
215
  	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...
216
  static const struct file_operations rcuhier_fops = {
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
217
218
219
220
221
222
223
224
225
  	.owner = THIS_MODULE,
  	.open = rcuhier_open,
  	.read = seq_read,
  	.llseek = seq_lseek,
  	.release = single_release,
  };
  
  static int show_rcugp(struct seq_file *m, void *unused)
  {
f41d911f8   Paul E. McKenney   rcu: Merge preemp...
226
  #ifdef CONFIG_TREE_PREEMPT_RCU
20133cfce   Paul E. McKenney   rcu: Stop overflo...
227
228
  	seq_printf(m, "rcu_preempt: completed=%ld  gpnum=%lu
  ",
f41d911f8   Paul E. McKenney   rcu: Merge preemp...
229
230
  		   rcu_preempt_state.completed, rcu_preempt_state.gpnum);
  #endif /* #ifdef CONFIG_TREE_PREEMPT_RCU */
20133cfce   Paul E. McKenney   rcu: Stop overflo...
231
232
  	seq_printf(m, "rcu_sched: completed=%ld  gpnum=%lu
  ",
d6714c22b   Paul E. McKenney   rcu: Renamings to...
233
  		   rcu_sched_state.completed, rcu_sched_state.gpnum);
20133cfce   Paul E. McKenney   rcu: Stop overflo...
234
235
  	seq_printf(m, "rcu_bh: completed=%ld  gpnum=%lu
  ",
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
236
237
238
239
240
241
242
243
  		   rcu_bh_state.completed, rcu_bh_state.gpnum);
  	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...
244
  static const struct file_operations rcugp_fops = {
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
245
246
247
248
249
250
  	.owner = THIS_MODULE,
  	.open = rcugp_open,
  	.read = seq_read,
  	.llseek = seq_lseek,
  	.release = single_release,
  };
7ba5c840e   Paul E. McKenney   rcu: Add __rcu_pe...
251
252
253
  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...
254
255
256
  		   "qsp=%ld rpq=%ld cbr=%ld cng=%ld "
  		   "gpc=%ld gps=%ld nf=%ld nn=%ld
  ",
7ba5c840e   Paul E. McKenney   rcu: Add __rcu_pe...
257
258
259
260
  		   rdp->cpu,
  		   cpu_is_offline(rdp->cpu) ? '!' : ' ',
  		   rdp->n_rcu_pending,
  		   rdp->n_rp_qs_pending,
d21670aca   Paul E. McKenney   rcu: reduce the n...
261
  		   rdp->n_rp_report_qs,
7ba5c840e   Paul E. McKenney   rcu: Add __rcu_pe...
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
  		   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) {
  		rdp = rsp->rda[cpu];
  		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...
284
285
286
287
288
  #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...
289
290
291
  	seq_puts(m, "rcu_sched:
  ");
  	print_rcu_pendings(m, &rcu_sched_state);
7ba5c840e   Paul E. McKenney   rcu: Add __rcu_pe...
292
293
294
295
296
297
298
299
300
301
  	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...
302
  static const struct file_operations rcu_pending_fops = {
7ba5c840e   Paul E. McKenney   rcu: Add __rcu_pe...
303
304
305
306
307
308
309
310
  	.owner = THIS_MODULE,
  	.open = rcu_pending_open,
  	.read = seq_read,
  	.llseek = seq_lseek,
  	.release = single_release,
  };
  
  static struct dentry *rcudir;
7ba5c840e   Paul E. McKenney   rcu: Add __rcu_pe...
311

64db4cfff   Paul E. McKenney   "Tree RCU": scala...
312
313
  static int __init rcuclassic_trace_init(void)
  {
22f00b69f   Paul E. McKenney   rcu: Use debugfs_...
314
  	struct dentry *retval;
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
315
316
  	rcudir = debugfs_create_dir("rcu", NULL);
  	if (!rcudir)
22f00b69f   Paul E. McKenney   rcu: Use debugfs_...
317
  		goto free_out;
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
318

22f00b69f   Paul E. McKenney   rcu: Use debugfs_...
319
  	retval = debugfs_create_file("rcudata", 0444, rcudir,
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
320
  						NULL, &rcudata_fops);
22f00b69f   Paul E. McKenney   rcu: Use debugfs_...
321
  	if (!retval)
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
322
  		goto free_out;
22f00b69f   Paul E. McKenney   rcu: Use debugfs_...
323
  	retval = debugfs_create_file("rcudata.csv", 0444, rcudir,
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
324
  						NULL, &rcudata_csv_fops);
22f00b69f   Paul E. McKenney   rcu: Use debugfs_...
325
  	if (!retval)
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
326
  		goto free_out;
22f00b69f   Paul E. McKenney   rcu: Use debugfs_...
327
328
  	retval = debugfs_create_file("rcugp", 0444, rcudir, NULL, &rcugp_fops);
  	if (!retval)
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
329
  		goto free_out;
22f00b69f   Paul E. McKenney   rcu: Use debugfs_...
330
  	retval = debugfs_create_file("rcuhier", 0444, rcudir,
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
331
  						NULL, &rcuhier_fops);
22f00b69f   Paul E. McKenney   rcu: Use debugfs_...
332
  	if (!retval)
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
333
  		goto free_out;
7ba5c840e   Paul E. McKenney   rcu: Add __rcu_pe...
334

22f00b69f   Paul E. McKenney   rcu: Use debugfs_...
335
  	retval = debugfs_create_file("rcu_pending", 0444, rcudir,
7ba5c840e   Paul E. McKenney   rcu: Add __rcu_pe...
336
  						NULL, &rcu_pending_fops);
22f00b69f   Paul E. McKenney   rcu: Use debugfs_...
337
  	if (!retval)
7ba5c840e   Paul E. McKenney   rcu: Add __rcu_pe...
338
  		goto free_out;
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
339
340
  	return 0;
  free_out:
22f00b69f   Paul E. McKenney   rcu: Use debugfs_...
341
  	debugfs_remove_recursive(rcudir);
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
342
343
344
345
346
  	return 1;
  }
  
  static void __exit rcuclassic_trace_cleanup(void)
  {
22f00b69f   Paul E. McKenney   rcu: Use debugfs_...
347
  	debugfs_remove_recursive(rcudir);
64db4cfff   Paul E. McKenney   "Tree RCU": scala...
348
349
350
351
352
353
354
355
356
  }
  
  
  module_init(rcuclassic_trace_init);
  module_exit(rcuclassic_trace_cleanup);
  
  MODULE_AUTHOR("Paul E. McKenney");
  MODULE_DESCRIPTION("Read-Copy Update tracing for hierarchical implementation");
  MODULE_LICENSE("GPL");