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), |
