aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/rcutree_trace.c
diff options
context:
space:
mode:
authorPaul E. McKenney <paul.mckenney@linaro.org>2011-04-06 19:01:16 -0400
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>2011-05-06 02:16:56 -0400
commit15ba0ba860871cf74b48b1bb47c26c91a66126f3 (patch)
tree2043eeca7d6df62fc0ae918b61abada073f81415 /kernel/rcutree_trace.c
parenta9f4793d8900dc5dc09b3951bdcd4731290e06fe (diff)
rcu: add grace-period age and more kthread state to tracing
This commit adds the age in jiffies of the current grace period along with the duration in jiffies of the longest grace period since boot to the rcu/rcugp debugfs file. It also adds an additional "O" state to kthread tracing to differentiate between the kthread waiting due to having nothing to do on the one hand and waiting due to being on the wrong CPU on the other hand. Signed-off-by: Paul E. McKenney <paul.mckenney@linaro.org> Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Diffstat (limited to 'kernel/rcutree_trace.c')
-rw-r--r--kernel/rcutree_trace.c37
1 files changed, 29 insertions, 8 deletions
diff --git a/kernel/rcutree_trace.c b/kernel/rcutree_trace.c
index 3baa235786b5..564b8fef2a7e 100644
--- a/kernel/rcutree_trace.c
+++ b/kernel/rcutree_trace.c
@@ -47,13 +47,14 @@
47#include "rcutree.h" 47#include "rcutree.h"
48 48
49DECLARE_PER_CPU(unsigned int, rcu_cpu_kthread_status); 49DECLARE_PER_CPU(unsigned int, rcu_cpu_kthread_status);
50DECLARE_PER_CPU(unsigned int, rcu_cpu_kthread_cpu);
50DECLARE_PER_CPU(char, rcu_cpu_has_work); 51DECLARE_PER_CPU(char, rcu_cpu_has_work);
51 52
52static char convert_kthread_status(unsigned int kthread_status) 53static char convert_kthread_status(unsigned int kthread_status)
53{ 54{
54 if (kthread_status > RCU_KTHREAD_MAX) 55 if (kthread_status > RCU_KTHREAD_MAX)
55 return '?'; 56 return '?';
56 return "SRWY"[kthread_status]; 57 return "SRWOY"[kthread_status];
57} 58}
58 59
59static void print_one_rcu_data(struct seq_file *m, struct rcu_data *rdp) 60static void print_one_rcu_data(struct seq_file *m, struct rcu_data *rdp)
@@ -74,7 +75,7 @@ static void print_one_rcu_data(struct seq_file *m, struct rcu_data *rdp)
74 rdp->dynticks_fqs); 75 rdp->dynticks_fqs);
75#endif /* #ifdef CONFIG_NO_HZ */ 76#endif /* #ifdef CONFIG_NO_HZ */
76 seq_printf(m, " of=%lu ri=%lu", rdp->offline_fqs, rdp->resched_ipi); 77 seq_printf(m, " of=%lu ri=%lu", rdp->offline_fqs, rdp->resched_ipi);
77 seq_printf(m, " ql=%ld qs=%c%c%c%c kt=%d/%c b=%ld", 78 seq_printf(m, " ql=%ld qs=%c%c%c%c kt=%d/%c/%d b=%ld",
78 rdp->qlen, 79 rdp->qlen,
79 ".N"[rdp->nxttail[RCU_NEXT_READY_TAIL] != 80 ".N"[rdp->nxttail[RCU_NEXT_READY_TAIL] !=
80 rdp->nxttail[RCU_NEXT_TAIL]], 81 rdp->nxttail[RCU_NEXT_TAIL]],
@@ -86,6 +87,7 @@ static void print_one_rcu_data(struct seq_file *m, struct rcu_data *rdp)
86 per_cpu(rcu_cpu_has_work, rdp->cpu), 87 per_cpu(rcu_cpu_has_work, rdp->cpu),
87 convert_kthread_status(per_cpu(rcu_cpu_kthread_status, 88 convert_kthread_status(per_cpu(rcu_cpu_kthread_status,
88 rdp->cpu)), 89 rdp->cpu)),
90 per_cpu(rcu_cpu_kthread_cpu, rdp->cpu),
89 rdp->blimit); 91 rdp->blimit);
90 seq_printf(m, " ci=%lu co=%lu ca=%lu\n", 92 seq_printf(m, " ci=%lu co=%lu ca=%lu\n",
91 rdp->n_cbs_invoked, rdp->n_cbs_orphaned, rdp->n_cbs_adopted); 93 rdp->n_cbs_invoked, rdp->n_cbs_orphaned, rdp->n_cbs_adopted);
@@ -312,16 +314,35 @@ static const struct file_operations rcuhier_fops = {
312 .release = single_release, 314 .release = single_release,
313}; 315};
314 316
317static void show_one_rcugp(struct seq_file *m, struct rcu_state *rsp)
318{
319 unsigned long flags;
320 unsigned long completed;
321 unsigned long gpnum;
322 unsigned long gpage;
323 unsigned long gpmax;
324 struct rcu_node *rnp = &rsp->node[0];
325
326 raw_spin_lock_irqsave(&rnp->lock, flags);
327 completed = rsp->completed;
328 gpnum = rsp->gpnum;
329 if (rsp->completed == rsp->gpnum)
330 gpage = 0;
331 else
332 gpage = jiffies - rsp->gp_start;
333 gpmax = rsp->gp_max;
334 raw_spin_unlock_irqrestore(&rnp->lock, flags);
335 seq_printf(m, "%s: completed=%ld gpnum=%lu age=%ld max=%ld\n",
336 rsp->name, completed, gpnum, gpage, gpmax);
337}
338
315static int show_rcugp(struct seq_file *m, void *unused) 339static int show_rcugp(struct seq_file *m, void *unused)
316{ 340{
317#ifdef CONFIG_TREE_PREEMPT_RCU 341#ifdef CONFIG_TREE_PREEMPT_RCU
318 seq_printf(m, "rcu_preempt: completed=%ld gpnum=%lu\n", 342 show_one_rcugp(m, &rcu_preempt_state);
319 rcu_preempt_state.completed, rcu_preempt_state.gpnum);
320#endif /* #ifdef CONFIG_TREE_PREEMPT_RCU */ 343#endif /* #ifdef CONFIG_TREE_PREEMPT_RCU */
321 seq_printf(m, "rcu_sched: completed=%ld gpnum=%lu\n", 344 show_one_rcugp(m, &rcu_sched_state);
322 rcu_sched_state.completed, rcu_sched_state.gpnum); 345 show_one_rcugp(m, &rcu_bh_state);
323 seq_printf(m, "rcu_bh: completed=%ld gpnum=%lu\n",
324 rcu_bh_state.completed, rcu_bh_state.gpnum);
325 return 0; 346 return 0;
326} 347}
327 348