diff options
author | Paul E. McKenney <paul.mckenney@linaro.org> | 2011-04-22 21:08:51 -0400 |
---|---|---|
committer | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2011-05-06 02:16:57 -0400 |
commit | 5ece5bab3ed8594ce2c85c6c6e6b82109db36ca7 (patch) | |
tree | c9ef8faa5dbb9e7c82893657e5aa2c1040987f96 | |
parent | 15ba0ba860871cf74b48b1bb47c26c91a66126f3 (diff) |
rcu: Add forward-progress diagnostic for per-CPU kthreads
Increment a per-CPU counter on each pass through rcu_cpu_kthread()'s
service loop, and add it to the rcudata trace output.
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>
-rw-r--r-- | Documentation/RCU/trace.txt | 39 | ||||
-rw-r--r-- | kernel/rcutree.c | 2 | ||||
-rw-r--r-- | kernel/rcutree_trace.c | 4 |
3 files changed, 27 insertions, 18 deletions
diff --git a/Documentation/RCU/trace.txt b/Documentation/RCU/trace.txt index fd4bffb6e8c9..8173cec473aa 100644 --- a/Documentation/RCU/trace.txt +++ b/Documentation/RCU/trace.txt | |||
@@ -33,23 +33,23 @@ rcu/rcuboost: | |||
33 | The output of "cat rcu/rcudata" looks as follows: | 33 | The output of "cat rcu/rcudata" looks as follows: |
34 | 34 | ||
35 | rcu_sched: | 35 | rcu_sched: |
36 | 0!c=423090 g=423091 pq=1 pqc=423090 qp=1 dt=86475/1/0 df=16319 of=163 ri=1519 ql=0 qs=.... kt=0/W b=10 ci=1460693 co=1648 ca=6448 | 36 | 0 c=20972 g=20973 pq=1 pqc=20972 qp=0 dt=545/1/0 df=50 of=0 ri=0 ql=163 qs=NRW. kt=0/W/0 ktl=ebc3 b=10 ci=153737 co=0 ca=0 |
37 | 1!c=423329 g=423330 pq=1 pqc=423329 qp=1 dt=90875/1/0 df=16231 of=157 ri=1249 ql=0 qs=.... kt=0/W b=10 ci=1459002 co=1614 ca=3310 | 37 | 1 c=20972 g=20973 pq=1 pqc=20972 qp=0 dt=967/1/0 df=58 of=0 ri=0 ql=634 qs=NRW. kt=0/W/1 ktl=58c b=10 ci=191037 co=0 ca=0 |
38 | 2!c=423370 g=423371 pq=1 pqc=423370 qp=1 dt=69661/1/0 df=16125 of=163 ri=1469 ql=0 qs=.... kt=0/W b=10 ci=1610701 co=2015 ca=2378 | 38 | 2 c=20972 g=20973 pq=1 pqc=20972 qp=0 dt=1081/1/0 df=175 of=0 ri=0 ql=74 qs=N.W. kt=0/W/2 ktl=da94 b=10 ci=75991 co=0 ca=0 |
39 | 3!c=422967 g=422968 pq=1 pqc=422967 qp=1 dt=70349/1/0 df=12528 of=163 ri=1450 ql=0 qs=.... kt=0/W b=10 ci=1427543 co=1430 ca=897 | 39 | 3 c=20942 g=20943 pq=1 pqc=20942 qp=1 dt=1846/0/0 df=404 of=0 ri=0 ql=0 qs=.... kt=0/W/3 ktl=d1cd b=10 ci=72261 co=0 ca=0 |
40 | 4!c=423196 g=423197 pq=1 pqc=423196 qp=0 dt=38935/1/0 df=10959 of=177 ri=1657 ql=0 qs=.... kt=0/W b=10 ci=1562249 co=1896 ca=533 | 40 | 4 c=20972 g=20973 pq=1 pqc=20972 qp=0 dt=369/1/0 df=83 of=0 ri=0 ql=48 qs=N.W. kt=0/W/4 ktl=e0e7 b=10 ci=128365 co=0 ca=0 |
41 | 5!c=422950 g=422951 pq=1 pqc=422950 qp=0 dt=25127/1/0 df=5895 of=167 ri=1549 ql=0 qs=.... kt=0/W b=10 ci=1777260 co=2137 ca=274 | 41 | 5 c=20972 g=20973 pq=1 pqc=20972 qp=0 dt=381/1/0 df=64 of=0 ri=0 ql=169 qs=NRW. kt=0/W/5 ktl=fb2f b=10 ci=164360 co=0 ca=0 |
42 | 6!c=423396 g=423397 pq=1 pqc=423396 qp=1 dt=22639/1/0 df=4590 of=149 ri=1572 ql=0 qs=.... kt=0/W b=10 ci=1471186 co=1530 ca=243 | 42 | 6 c=20972 g=20973 pq=1 pqc=20972 qp=0 dt=1037/1/0 df=183 of=0 ri=0 ql=62 qs=N.W. kt=0/W/6 ktl=d2ad b=10 ci=65663 co=0 ca=0 |
43 | 7 c=460203 g=460203 pq=1 pqc=460202 qp=0 dt=937087/1/0 df=3298 of=149 ri=1584 ql=6 qs=N.W. kt=0/W b=10 ci=4026154 co=1948 ca=135 | 43 | 7 c=20897 g=20897 pq=1 pqc=20896 qp=0 dt=1572/0/0 df=382 of=0 ri=0 ql=0 qs=.... kt=0/W/7 ktl=cf15 b=10 ci=75006 co=0 ca=0 |
44 | rcu_bh: | 44 | rcu_bh: |
45 | 0!c=18446744073709551494 g=18446744073709551494 pq=0 pqc=18446744073709551493 qp=1 dt=86475/1/0 df=11 of=0 ri=0 ql=0 qs=.... kt=0/W b=10 ci=112 co=0 ca=0 | 45 | 0 c=1480 g=1480 pq=1 pqc=1479 qp=0 dt=545/1/0 df=6 of=0 ri=1 ql=0 qs=.... kt=0/W/0 ktl=ebc3 b=10 ci=0 co=0 ca=0 |
46 | 1!c=18446744073709551496 g=18446744073709551496 pq=1 pqc=18446744073709551495 qp=0 dt=90875/1/0 df=15 of=0 ri=0 ql=0 qs=.... kt=0/W b=10 ci=143 co=0 ca=0 | 46 | 1 c=1480 g=1480 pq=1 pqc=1479 qp=0 dt=967/1/0 df=3 of=0 ri=1 ql=0 qs=.... kt=0/W/1 ktl=58c b=10 ci=151 co=0 ca=0 |
47 | 2!c=18446744073709551496 g=18446744073709551496 pq=1 pqc=18446744073709551495 qp=0 dt=69661/1/0 df=21 of=0 ri=1 ql=0 qs=.... kt=0/W b=10 ci=88 co=0 ca=0 | 47 | 2 c=1480 g=1480 pq=1 pqc=1479 qp=0 dt=1081/1/0 df=6 of=0 ri=1 ql=0 qs=.... kt=0/W/2 ktl=da94 b=10 ci=0 co=0 ca=0 |
48 | 3!c=18446744073709551494 g=18446744073709551494 pq=1 pqc=18446744073709551493 qp=0 dt=70349/1/0 df=13 of=0 ri=0 ql=0 qs=.... kt=0/W b=10 ci=100 co=0 ca=0 | 48 | 3 c=1480 g=1480 pq=1 pqc=1479 qp=0 dt=1846/0/0 df=8 of=0 ri=1 ql=0 qs=.... kt=0/W/3 ktl=d1cd b=10 ci=0 co=0 ca=0 |
49 | 4!c=18446744073709551494 g=18446744073709551494 pq=0 pqc=18446744073709551493 qp=1 dt=38935/1/0 df=17 of=0 ri=0 ql=0 qs=.... kt=0/W b=10 ci=36 co=0 ca=0 | 49 | 4 c=1480 g=1480 pq=1 pqc=1479 qp=0 dt=369/1/0 df=6 of=0 ri=1 ql=0 qs=.... kt=0/W/4 ktl=e0e7 b=10 ci=0 co=0 ca=0 |
50 | 5!c=18446744073709551494 g=18446744073709551494 pq=0 pqc=18446744073709551493 qp=1 dt=25127/1/0 df=7 of=0 ri=0 ql=0 qs=.... kt=0/W b=10 ci=32 co=0 ca=0 | 50 | 5 c=1480 g=1480 pq=1 pqc=1479 qp=0 dt=381/1/0 df=4 of=0 ri=1 ql=0 qs=.... kt=0/W/5 ktl=fb2f b=10 ci=0 co=0 ca=0 |
51 | 6!c=18446744073709551496 g=18446744073709551496 pq=1 pqc=18446744073709551495 qp=0 dt=22639/1/0 df=9 of=0 ri=0 ql=0 qs=.... kt=0/W b=10 ci=44 co=0 ca=0 | 51 | 6 c=1480 g=1480 pq=1 pqc=1479 qp=0 dt=1037/1/0 df=6 of=0 ri=1 ql=0 qs=.... kt=0/W/6 ktl=d2ad b=10 ci=0 co=0 ca=0 |
52 | 7 c=182 g=182 pq=1 pqc=181 qp=0 dt=937087/1/0 df=14 of=0 ri=1 ql=0 qs=.... kt=0/W b=10 ci=627 co=0 ca=0 | 52 | 7 c=1474 g=1474 pq=1 pqc=1473 qp=0 dt=1572/0/0 df=8 of=0 ri=1 ql=0 qs=.... kt=0/W/7 ktl=cf15 b=10 ci=0 co=0 ca=0 |
53 | 53 | ||
54 | The first section lists the rcu_data structures for rcu_sched, the second | 54 | The first section lists the rcu_data structures for rcu_sched, the second |
55 | for rcu_bh. Note that CONFIG_TREE_PREEMPT_RCU kernels will have an | 55 | for rcu_bh. Note that CONFIG_TREE_PREEMPT_RCU kernels will have an |
@@ -160,7 +160,8 @@ o "qs" gives an indication of the state of the callback queue | |||
160 | 160 | ||
161 | o "kt" is the per-CPU kernel-thread state. The digit preceding | 161 | o "kt" is the per-CPU kernel-thread state. The digit preceding |
162 | the first slash is zero if there is no work pending and 1 | 162 | the first slash is zero if there is no work pending and 1 |
163 | otherwise. The character between the slashes is as follows: | 163 | otherwise. The character between the first pair of slashes is |
164 | as follows: | ||
164 | 165 | ||
165 | "S" The kernel thread is stopped, in other words, all | 166 | "S" The kernel thread is stopped, in other words, all |
166 | CPUs corresponding to this rcu_node structure are | 167 | CPUs corresponding to this rcu_node structure are |
@@ -183,6 +184,10 @@ o "kt" is the per-CPU kernel-thread state. The digit preceding | |||
183 | The number after the final slash is the CPU that the kthread | 184 | The number after the final slash is the CPU that the kthread |
184 | is actually running on. | 185 | is actually running on. |
185 | 186 | ||
187 | o "ktl" is the low-order 16 bits (in hexadecimal) of the count of | ||
188 | the number of times that this CPU's per-CPU kthread has gone | ||
189 | through its loop servicing invoke_rcu_cpu_kthread() requests. | ||
190 | |||
186 | o "b" is the batch limit for this CPU. If more than this number | 191 | o "b" is the batch limit for this CPU. If more than this number |
187 | of RCU callbacks is ready to invoke, then the remainder will | 192 | of RCU callbacks is ready to invoke, then the remainder will |
188 | be deferred. | 193 | be deferred. |
diff --git a/kernel/rcutree.c b/kernel/rcutree.c index 27b6d8de82f6..575d6414763e 100644 --- a/kernel/rcutree.c +++ b/kernel/rcutree.c | |||
@@ -93,6 +93,7 @@ EXPORT_SYMBOL_GPL(rcu_scheduler_active); | |||
93 | static DEFINE_PER_CPU(struct task_struct *, rcu_cpu_kthread_task); | 93 | static DEFINE_PER_CPU(struct task_struct *, rcu_cpu_kthread_task); |
94 | DEFINE_PER_CPU(unsigned int, rcu_cpu_kthread_status); | 94 | DEFINE_PER_CPU(unsigned int, rcu_cpu_kthread_status); |
95 | DEFINE_PER_CPU(int, rcu_cpu_kthread_cpu); | 95 | DEFINE_PER_CPU(int, rcu_cpu_kthread_cpu); |
96 | DEFINE_PER_CPU(unsigned int, rcu_cpu_kthread_loops); | ||
96 | static DEFINE_PER_CPU(wait_queue_head_t, rcu_cpu_wq); | 97 | static DEFINE_PER_CPU(wait_queue_head_t, rcu_cpu_wq); |
97 | DEFINE_PER_CPU(char, rcu_cpu_has_work); | 98 | DEFINE_PER_CPU(char, rcu_cpu_has_work); |
98 | static char rcu_kthreads_spawnable; | 99 | static char rcu_kthreads_spawnable; |
@@ -1625,6 +1626,7 @@ static int rcu_cpu_kthread(void *arg) | |||
1625 | break; | 1626 | break; |
1626 | } | 1627 | } |
1627 | *statusp = RCU_KTHREAD_RUNNING; | 1628 | *statusp = RCU_KTHREAD_RUNNING; |
1629 | per_cpu(rcu_cpu_kthread_loops, cpu)++; | ||
1628 | local_irq_save(flags); | 1630 | local_irq_save(flags); |
1629 | work = *workp; | 1631 | work = *workp; |
1630 | *workp = 0; | 1632 | *workp = 0; |
diff --git a/kernel/rcutree_trace.c b/kernel/rcutree_trace.c index 564b8fef2a7e..9678cc3650f5 100644 --- a/kernel/rcutree_trace.c +++ b/kernel/rcutree_trace.c | |||
@@ -48,6 +48,7 @@ | |||
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(unsigned int, rcu_cpu_kthread_cpu); |
51 | DECLARE_PER_CPU(unsigned int, rcu_cpu_kthread_loops); | ||
51 | DECLARE_PER_CPU(char, rcu_cpu_has_work); | 52 | DECLARE_PER_CPU(char, rcu_cpu_has_work); |
52 | 53 | ||
53 | static char convert_kthread_status(unsigned int kthread_status) | 54 | static char convert_kthread_status(unsigned int kthread_status) |
@@ -75,7 +76,7 @@ static void print_one_rcu_data(struct seq_file *m, struct rcu_data *rdp) | |||
75 | rdp->dynticks_fqs); | 76 | rdp->dynticks_fqs); |
76 | #endif /* #ifdef CONFIG_NO_HZ */ | 77 | #endif /* #ifdef CONFIG_NO_HZ */ |
77 | seq_printf(m, " of=%lu ri=%lu", rdp->offline_fqs, rdp->resched_ipi); | 78 | seq_printf(m, " of=%lu ri=%lu", rdp->offline_fqs, rdp->resched_ipi); |
78 | seq_printf(m, " ql=%ld qs=%c%c%c%c kt=%d/%c/%d b=%ld", | 79 | seq_printf(m, " ql=%ld qs=%c%c%c%c kt=%d/%c/%d ktl=%x b=%ld", |
79 | rdp->qlen, | 80 | rdp->qlen, |
80 | ".N"[rdp->nxttail[RCU_NEXT_READY_TAIL] != | 81 | ".N"[rdp->nxttail[RCU_NEXT_READY_TAIL] != |
81 | rdp->nxttail[RCU_NEXT_TAIL]], | 82 | rdp->nxttail[RCU_NEXT_TAIL]], |
@@ -88,6 +89,7 @@ static void print_one_rcu_data(struct seq_file *m, struct rcu_data *rdp) | |||
88 | convert_kthread_status(per_cpu(rcu_cpu_kthread_status, | 89 | convert_kthread_status(per_cpu(rcu_cpu_kthread_status, |
89 | rdp->cpu)), | 90 | rdp->cpu)), |
90 | per_cpu(rcu_cpu_kthread_cpu, rdp->cpu), | 91 | per_cpu(rcu_cpu_kthread_cpu, rdp->cpu), |
92 | per_cpu(rcu_cpu_kthread_loops, rdp->cpu) & 0xffff, | ||
91 | rdp->blimit); | 93 | rdp->blimit); |
92 | seq_printf(m, " ci=%lu co=%lu ca=%lu\n", | 94 | seq_printf(m, " ci=%lu co=%lu ca=%lu\n", |
93 | rdp->n_cbs_invoked, rdp->n_cbs_orphaned, rdp->n_cbs_adopted); | 95 | rdp->n_cbs_invoked, rdp->n_cbs_orphaned, rdp->n_cbs_adopted); |