aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul E. McKenney <paulmck@linux.vnet.ibm.com>2013-08-15 16:23:23 -0400
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>2013-09-23 12:18:16 -0400
commit69a79bb12a81024d718e73c52e886907a3777b34 (patch)
tree0beef5d898f1373dbc5b4834d24d676e73ea1da2
parent756cbf6befe6f59b0b3e0967d92a66c11e2566ed (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.h4
-rw-r--r--kernel/rcutree_plugin.h15
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 */
189TRACE_EVENT(rcu_nocb_wake, 193TRACE_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)
2230static int rcu_nocb_kthread(void *arg) 2230static 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);