diff options
author | Paul E. McKenney <paul.mckenney@linaro.org> | 2011-04-06 19:01:16 -0400 |
---|---|---|
committer | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2011-05-06 02:16:56 -0400 |
commit | 15ba0ba860871cf74b48b1bb47c26c91a66126f3 (patch) | |
tree | 2043eeca7d6df62fc0ae918b61abada073f81415 /kernel/rcutree_trace.c | |
parent | a9f4793d8900dc5dc09b3951bdcd4731290e06fe (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.c | 37 |
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 | ||
49 | DECLARE_PER_CPU(unsigned int, rcu_cpu_kthread_status); | 49 | DECLARE_PER_CPU(unsigned int, rcu_cpu_kthread_status); |
50 | DECLARE_PER_CPU(unsigned int, rcu_cpu_kthread_cpu); | ||
50 | DECLARE_PER_CPU(char, rcu_cpu_has_work); | 51 | DECLARE_PER_CPU(char, rcu_cpu_has_work); |
51 | 52 | ||
52 | static char convert_kthread_status(unsigned int kthread_status) | 53 | static 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 | ||
59 | static void print_one_rcu_data(struct seq_file *m, struct rcu_data *rdp) | 60 | static 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 | ||
317 | static 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 | |||
315 | static int show_rcugp(struct seq_file *m, void *unused) | 339 | static 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 | ||