diff options
author | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2013-08-15 16:23:23 -0400 |
---|---|---|
committer | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2013-09-23 12:18:16 -0400 |
commit | 69a79bb12a81024d718e73c52e886907a3777b34 (patch) | |
tree | 0beef5d898f1373dbc5b4834d24d676e73ea1da2 | |
parent | 756cbf6befe6f59b0b3e0967d92a66c11e2566ed (diff) |
rcu: Track rcu_nocb_kthread()'s sleeping and awakening
This commit adds event traces to track all of rcu_nocb_kthread()'s
blocking and awakening.
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
-rw-r--r-- | include/trace/events/rcu.h | 4 | ||||
-rw-r--r-- | kernel/rcutree_plugin.h | 15 |
2 files changed, 18 insertions, 1 deletions
diff --git a/include/trace/events/rcu.h b/include/trace/events/rcu.h index 4301cd9e3ee5..a087d82ed431 100644 --- a/include/trace/events/rcu.h +++ b/include/trace/events/rcu.h | |||
@@ -183,8 +183,12 @@ TRACE_EVENT(rcu_grace_period_init, | |||
183 | * "WakeOvf": Wake rcuo kthread, CB list is huge. | 183 | * "WakeOvf": Wake rcuo kthread, CB list is huge. |
184 | * "WakeNot": Don't wake rcuo kthread. | 184 | * "WakeNot": Don't wake rcuo kthread. |
185 | * "WakeNotPoll": Don't wake rcuo kthread because it is polling. | 185 | * "WakeNotPoll": Don't wake rcuo kthread because it is polling. |
186 | * "Poll": Start of new polling cycle for rcu_nocb_poll. | ||
187 | * "Sleep": Sleep waiting for CBs for !rcu_nocb_poll. | ||
186 | * "WokeEmpty": rcuo kthread woke to find empty list. | 188 | * "WokeEmpty": rcuo kthread woke to find empty list. |
187 | * "WokeNonEmpty": rcuo kthread woke to find non-empty list. | 189 | * "WokeNonEmpty": rcuo kthread woke to find non-empty list. |
190 | * "WaitQueue": Enqueue partially done, timed wait for it to complete. | ||
191 | * "WokeQueue": Partial enqueue now complete. | ||
188 | */ | 192 | */ |
189 | TRACE_EVENT(rcu_nocb_wake, | 193 | TRACE_EVENT(rcu_nocb_wake, |
190 | 194 | ||
diff --git a/kernel/rcutree_plugin.h b/kernel/rcutree_plugin.h index 24b01b69be92..21205b185340 100644 --- a/kernel/rcutree_plugin.h +++ b/kernel/rcutree_plugin.h | |||
@@ -2230,6 +2230,7 @@ static void rcu_nocb_wait_gp(struct rcu_data *rdp) | |||
2230 | static int rcu_nocb_kthread(void *arg) | 2230 | static int rcu_nocb_kthread(void *arg) |
2231 | { | 2231 | { |
2232 | int c, cl; | 2232 | int c, cl; |
2233 | bool firsttime = 1; | ||
2233 | struct rcu_head *list; | 2234 | struct rcu_head *list; |
2234 | struct rcu_head *next; | 2235 | struct rcu_head *next; |
2235 | struct rcu_head **tail; | 2236 | struct rcu_head **tail; |
@@ -2238,8 +2239,15 @@ static int rcu_nocb_kthread(void *arg) | |||
2238 | /* Each pass through this loop invokes one batch of callbacks */ | 2239 | /* Each pass through this loop invokes one batch of callbacks */ |
2239 | for (;;) { | 2240 | for (;;) { |
2240 | /* If not polling, wait for next batch of callbacks. */ | 2241 | /* If not polling, wait for next batch of callbacks. */ |
2241 | if (!rcu_nocb_poll) | 2242 | if (!rcu_nocb_poll) { |
2243 | trace_rcu_nocb_wake(rdp->rsp->name, rdp->cpu, | ||
2244 | TPS("Sleep")); | ||
2242 | wait_event_interruptible(rdp->nocb_wq, rdp->nocb_head); | 2245 | wait_event_interruptible(rdp->nocb_wq, rdp->nocb_head); |
2246 | } else if (firsttime) { | ||
2247 | firsttime = 0; | ||
2248 | trace_rcu_nocb_wake(rdp->rsp->name, rdp->cpu, | ||
2249 | TPS("Poll")); | ||
2250 | } | ||
2243 | list = ACCESS_ONCE(rdp->nocb_head); | 2251 | list = ACCESS_ONCE(rdp->nocb_head); |
2244 | if (!list) { | 2252 | if (!list) { |
2245 | if (!rcu_nocb_poll) | 2253 | if (!rcu_nocb_poll) |
@@ -2249,6 +2257,7 @@ static int rcu_nocb_kthread(void *arg) | |||
2249 | flush_signals(current); | 2257 | flush_signals(current); |
2250 | continue; | 2258 | continue; |
2251 | } | 2259 | } |
2260 | firsttime = 1; | ||
2252 | trace_rcu_nocb_wake(rdp->rsp->name, rdp->cpu, | 2261 | trace_rcu_nocb_wake(rdp->rsp->name, rdp->cpu, |
2253 | TPS("WokeNonEmpty")); | 2262 | TPS("WokeNonEmpty")); |
2254 | 2263 | ||
@@ -2271,7 +2280,11 @@ static int rcu_nocb_kthread(void *arg) | |||
2271 | next = list->next; | 2280 | next = list->next; |
2272 | /* Wait for enqueuing to complete, if needed. */ | 2281 | /* Wait for enqueuing to complete, if needed. */ |
2273 | while (next == NULL && &list->next != tail) { | 2282 | while (next == NULL && &list->next != tail) { |
2283 | trace_rcu_nocb_wake(rdp->rsp->name, rdp->cpu, | ||
2284 | TPS("WaitQueue")); | ||
2274 | schedule_timeout_interruptible(1); | 2285 | schedule_timeout_interruptible(1); |
2286 | trace_rcu_nocb_wake(rdp->rsp->name, rdp->cpu, | ||
2287 | TPS("WokeQueue")); | ||
2275 | next = list->next; | 2288 | next = list->next; |
2276 | } | 2289 | } |
2277 | debug_rcu_head_unqueue(list); | 2290 | debug_rcu_head_unqueue(list); |