diff options
author | Paul E. McKenney <paul.mckenney@linaro.org> | 2011-03-29 20:48:28 -0400 |
---|---|---|
committer | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2011-05-06 02:16:56 -0400 |
commit | d71df90eadfc35aa549ff9a850842673febca71f (patch) | |
tree | dd275a3f4848784bc6625574341c11befc1b3823 /kernel/rcutree_trace.c | |
parent | 0ac3d136b2e3cdf1161178223bc5da14a06241d0 (diff) |
rcu: add tracing for RCU's kthread run states.
Add tracing to help debugging situations when RCU's kthreads are not
running but are supposed to be.
Signed-off-by: Paul E. McKenney <paul.mckenney@linaro.org>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Reviewed-by: Josh Triplett <josh@joshtriplett.org>
Diffstat (limited to 'kernel/rcutree_trace.c')
-rw-r--r-- | kernel/rcutree_trace.c | 23 |
1 files changed, 20 insertions, 3 deletions
diff --git a/kernel/rcutree_trace.c b/kernel/rcutree_trace.c index afd262f91262..fc40e89a028c 100644 --- a/kernel/rcutree_trace.c +++ b/kernel/rcutree_trace.c | |||
@@ -46,6 +46,16 @@ | |||
46 | #define RCU_TREE_NONCORE | 46 | #define RCU_TREE_NONCORE |
47 | #include "rcutree.h" | 47 | #include "rcutree.h" |
48 | 48 | ||
49 | DECLARE_PER_CPU(unsigned int, rcu_cpu_kthread_status); | ||
50 | DECLARE_PER_CPU(char, rcu_cpu_has_work); | ||
51 | |||
52 | static char convert_kthread_status(unsigned int kthread_status) | ||
53 | { | ||
54 | if (kthread_status > RCU_KTHREAD_MAX) | ||
55 | return '?'; | ||
56 | return "SRWY"[kthread_status]; | ||
57 | } | ||
58 | |||
49 | static void print_one_rcu_data(struct seq_file *m, struct rcu_data *rdp) | 59 | static void print_one_rcu_data(struct seq_file *m, struct rcu_data *rdp) |
50 | { | 60 | { |
51 | if (!rdp->beenonline) | 61 | if (!rdp->beenonline) |
@@ -64,7 +74,7 @@ static void print_one_rcu_data(struct seq_file *m, struct rcu_data *rdp) | |||
64 | rdp->dynticks_fqs); | 74 | rdp->dynticks_fqs); |
65 | #endif /* #ifdef CONFIG_NO_HZ */ | 75 | #endif /* #ifdef CONFIG_NO_HZ */ |
66 | seq_printf(m, " of=%lu ri=%lu", rdp->offline_fqs, rdp->resched_ipi); | 76 | seq_printf(m, " of=%lu ri=%lu", rdp->offline_fqs, rdp->resched_ipi); |
67 | seq_printf(m, " ql=%ld qs=%c%c%c%c b=%ld", | 77 | seq_printf(m, " ql=%ld qs=%c%c%c%c kt=%d/%c b=%ld", |
68 | rdp->qlen, | 78 | rdp->qlen, |
69 | ".N"[rdp->nxttail[RCU_NEXT_READY_TAIL] != | 79 | ".N"[rdp->nxttail[RCU_NEXT_READY_TAIL] != |
70 | rdp->nxttail[RCU_NEXT_TAIL]], | 80 | rdp->nxttail[RCU_NEXT_TAIL]], |
@@ -73,6 +83,9 @@ static void print_one_rcu_data(struct seq_file *m, struct rcu_data *rdp) | |||
73 | ".W"[rdp->nxttail[RCU_DONE_TAIL] != | 83 | ".W"[rdp->nxttail[RCU_DONE_TAIL] != |
74 | rdp->nxttail[RCU_WAIT_TAIL]], | 84 | rdp->nxttail[RCU_WAIT_TAIL]], |
75 | ".D"[&rdp->nxtlist != rdp->nxttail[RCU_DONE_TAIL]], | 85 | ".D"[&rdp->nxtlist != rdp->nxttail[RCU_DONE_TAIL]], |
86 | per_cpu(rcu_cpu_has_work, rdp->cpu), | ||
87 | convert_kthread_status(per_cpu(rcu_cpu_kthread_status, | ||
88 | rdp->cpu)), | ||
76 | rdp->blimit); | 89 | rdp->blimit); |
77 | seq_printf(m, " ci=%lu co=%lu ca=%lu\n", | 90 | seq_printf(m, " ci=%lu co=%lu ca=%lu\n", |
78 | rdp->n_cbs_invoked, rdp->n_cbs_orphaned, rdp->n_cbs_adopted); | 91 | rdp->n_cbs_invoked, rdp->n_cbs_orphaned, rdp->n_cbs_adopted); |
@@ -130,7 +143,7 @@ static void print_one_rcu_data_csv(struct seq_file *m, struct rcu_data *rdp) | |||
130 | rdp->dynticks_fqs); | 143 | rdp->dynticks_fqs); |
131 | #endif /* #ifdef CONFIG_NO_HZ */ | 144 | #endif /* #ifdef CONFIG_NO_HZ */ |
132 | seq_printf(m, ",%lu,%lu", rdp->offline_fqs, rdp->resched_ipi); | 145 | seq_printf(m, ",%lu,%lu", rdp->offline_fqs, rdp->resched_ipi); |
133 | seq_printf(m, ",%ld,\"%c%c%c%c\",%ld", rdp->qlen, | 146 | seq_printf(m, ",%ld,\"%c%c%c%c\",%d,\"%c\",%ld", rdp->qlen, |
134 | ".N"[rdp->nxttail[RCU_NEXT_READY_TAIL] != | 147 | ".N"[rdp->nxttail[RCU_NEXT_READY_TAIL] != |
135 | rdp->nxttail[RCU_NEXT_TAIL]], | 148 | rdp->nxttail[RCU_NEXT_TAIL]], |
136 | ".R"[rdp->nxttail[RCU_WAIT_TAIL] != | 149 | ".R"[rdp->nxttail[RCU_WAIT_TAIL] != |
@@ -138,6 +151,9 @@ static void print_one_rcu_data_csv(struct seq_file *m, struct rcu_data *rdp) | |||
138 | ".W"[rdp->nxttail[RCU_DONE_TAIL] != | 151 | ".W"[rdp->nxttail[RCU_DONE_TAIL] != |
139 | rdp->nxttail[RCU_WAIT_TAIL]], | 152 | rdp->nxttail[RCU_WAIT_TAIL]], |
140 | ".D"[&rdp->nxtlist != rdp->nxttail[RCU_DONE_TAIL]], | 153 | ".D"[&rdp->nxtlist != rdp->nxttail[RCU_DONE_TAIL]], |
154 | per_cpu(rcu_cpu_has_work, rdp->cpu), | ||
155 | convert_kthread_status(per_cpu(rcu_cpu_kthread_status, | ||
156 | rdp->cpu)), | ||
141 | rdp->blimit); | 157 | rdp->blimit); |
142 | seq_printf(m, ",%lu,%lu,%lu\n", | 158 | seq_printf(m, ",%lu,%lu,%lu\n", |
143 | rdp->n_cbs_invoked, rdp->n_cbs_orphaned, rdp->n_cbs_adopted); | 159 | rdp->n_cbs_invoked, rdp->n_cbs_orphaned, rdp->n_cbs_adopted); |
@@ -178,13 +194,14 @@ static const struct file_operations rcudata_csv_fops = { | |||
178 | 194 | ||
179 | static void print_one_rcu_node_boost(struct seq_file *m, struct rcu_node *rnp) | 195 | static void print_one_rcu_node_boost(struct seq_file *m, struct rcu_node *rnp) |
180 | { | 196 | { |
181 | seq_printf(m, "%d:%d tasks=%c%c%c%c ntb=%lu neb=%lu nnb=%lu " | 197 | seq_printf(m, "%d:%d tasks=%c%c%c%c kt=%c ntb=%lu neb=%lu nnb=%lu " |
182 | "j=%04x bt=%04x\n", | 198 | "j=%04x bt=%04x\n", |
183 | rnp->grplo, rnp->grphi, | 199 | rnp->grplo, rnp->grphi, |
184 | "T."[list_empty(&rnp->blkd_tasks)], | 200 | "T."[list_empty(&rnp->blkd_tasks)], |
185 | "N."[!rnp->gp_tasks], | 201 | "N."[!rnp->gp_tasks], |
186 | "E."[!rnp->exp_tasks], | 202 | "E."[!rnp->exp_tasks], |
187 | "B."[!rnp->boost_tasks], | 203 | "B."[!rnp->boost_tasks], |
204 | convert_kthread_status(rnp->boost_kthread_status), | ||
188 | rnp->n_tasks_boosted, rnp->n_exp_boosts, | 205 | rnp->n_tasks_boosted, rnp->n_exp_boosts, |
189 | rnp->n_normal_boosts, | 206 | rnp->n_normal_boosts, |
190 | (int)(jiffies & 0xffff), | 207 | (int)(jiffies & 0xffff), |