aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul E. McKenney <paulmck@linux.vnet.ibm.com>2013-08-09 15:19:29 -0400
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>2013-09-23 12:16:14 -0400
commit63c4db78e80407976e47bccaa2a4d8251b5a10bc (patch)
tree31b832426eec3bf0e954440afe461b388f84e12d
parent591c6d1710cd73824057d08eda302cf2a7cfd18a (diff)
rcu: Add tracing to rcu_gp_kthread()
This commit adds tracing to the rcu_gp_kthread() function in order to help trace down hangs potentially involving this kthread. Reported-by: Clark Williams <williams@redhat.com> Reported-by: Carsten Emde <C.Emde@osadl.org> Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
-rw-r--r--include/trace/events/rcu.h28
-rw-r--r--kernel/rcutree.c18
2 files changed, 37 insertions, 9 deletions
diff --git a/include/trace/events/rcu.h b/include/trace/events/rcu.h
index ee2376cfaab3..60077e12093c 100644
--- a/include/trace/events/rcu.h
+++ b/include/trace/events/rcu.h
@@ -39,15 +39,25 @@ TRACE_EVENT(rcu_utilization,
39#if defined(CONFIG_TREE_RCU) || defined(CONFIG_TREE_PREEMPT_RCU) 39#if defined(CONFIG_TREE_RCU) || defined(CONFIG_TREE_PREEMPT_RCU)
40 40
41/* 41/*
42 * Tracepoint for grace-period events: starting and ending a grace 42 * Tracepoint for grace-period events. Takes a string identifying the
43 * period ("start" and "end", respectively), a CPU noting the start 43 * RCU flavor, the grace-period number, and a string identifying the
44 * of a new grace period or the end of an old grace period ("cpustart" 44 * grace-period-related event as follows:
45 * and "cpuend", respectively), a CPU passing through a quiescent 45 *
46 * state ("cpuqs"), a CPU coming online or going offline ("cpuonl" 46 * "AccReadyCB": CPU acclerates new callbacks to RCU_NEXT_READY_TAIL.
47 * and "cpuofl", respectively), a CPU being kicked for being too 47 * "AccWaitCB": CPU accelerates new callbacks to RCU_WAIT_TAIL.
48 * long in dyntick-idle mode ("kick"), a CPU accelerating its new 48 * "start": Start a grace period.
49 * callbacks to RCU_NEXT_READY_TAIL ("AccReadyCB"), and a CPU 49 * "cpustart": CPU first notices a grace-period start.
50 * accelerating its new callbacks to RCU_WAIT_TAIL ("AccWaitCB"). 50 * "cpuqs": CPU passes through a quiescent state.
51 * "cpuonl": CPU comes online.
52 * "cpuofl": CPU goes offline.
53 * "reqwait": GP kthread sleeps waiting for grace-period request.
54 * "reqwaitsig": GP kthread awakened by signal from reqwait state.
55 * "fqswait": GP kthread waiting until time to force quiescent states.
56 * "fqsstart": GP kthread starts forcing quiescent states.
57 * "fqsend": GP kthread done forcing quiescent states.
58 * "fqswaitsig": GP kthread awakened by signal from fqswait state.
59 * "end": End a grace period.
60 * "cpuend": CPU first notices a grace-period end.
51 */ 61 */
52TRACE_EVENT(rcu_grace_period, 62TRACE_EVENT(rcu_grace_period,
53 63
diff --git a/kernel/rcutree.c b/kernel/rcutree.c
index 6d028fdbf86c..78d371526667 100644
--- a/kernel/rcutree.c
+++ b/kernel/rcutree.c
@@ -1480,6 +1480,9 @@ static int __noreturn rcu_gp_kthread(void *arg)
1480 1480
1481 /* Handle grace-period start. */ 1481 /* Handle grace-period start. */
1482 for (;;) { 1482 for (;;) {
1483 trace_rcu_grace_period(rsp->name,
1484 ACCESS_ONCE(rsp->gpnum),
1485 TPS("reqwait"));
1483 wait_event_interruptible(rsp->gp_wq, 1486 wait_event_interruptible(rsp->gp_wq,
1484 ACCESS_ONCE(rsp->gp_flags) & 1487 ACCESS_ONCE(rsp->gp_flags) &
1485 RCU_GP_FLAG_INIT); 1488 RCU_GP_FLAG_INIT);
@@ -1487,6 +1490,9 @@ static int __noreturn rcu_gp_kthread(void *arg)
1487 break; 1490 break;
1488 cond_resched(); 1491 cond_resched();
1489 flush_signals(current); 1492 flush_signals(current);
1493 trace_rcu_grace_period(rsp->name,
1494 ACCESS_ONCE(rsp->gpnum),
1495 TPS("reqwaitsig"));
1490 } 1496 }
1491 1497
1492 /* Handle quiescent-state forcing. */ 1498 /* Handle quiescent-state forcing. */
@@ -1500,6 +1506,9 @@ static int __noreturn rcu_gp_kthread(void *arg)
1500 for (;;) { 1506 for (;;) {
1501 if (!ret) 1507 if (!ret)
1502 rsp->jiffies_force_qs = jiffies + j; 1508 rsp->jiffies_force_qs = jiffies + j;
1509 trace_rcu_grace_period(rsp->name,
1510 ACCESS_ONCE(rsp->gpnum),
1511 TPS("fqswait"));
1503 ret = wait_event_interruptible_timeout(rsp->gp_wq, 1512 ret = wait_event_interruptible_timeout(rsp->gp_wq,
1504 ((gf = ACCESS_ONCE(rsp->gp_flags)) & 1513 ((gf = ACCESS_ONCE(rsp->gp_flags)) &
1505 RCU_GP_FLAG_FQS) || 1514 RCU_GP_FLAG_FQS) ||
@@ -1513,12 +1522,21 @@ static int __noreturn rcu_gp_kthread(void *arg)
1513 /* If time for quiescent-state forcing, do it. */ 1522 /* If time for quiescent-state forcing, do it. */
1514 if (ULONG_CMP_GE(jiffies, rsp->jiffies_force_qs) || 1523 if (ULONG_CMP_GE(jiffies, rsp->jiffies_force_qs) ||
1515 (gf & RCU_GP_FLAG_FQS)) { 1524 (gf & RCU_GP_FLAG_FQS)) {
1525 trace_rcu_grace_period(rsp->name,
1526 ACCESS_ONCE(rsp->gpnum),
1527 TPS("fqsstart"));
1516 fqs_state = rcu_gp_fqs(rsp, fqs_state); 1528 fqs_state = rcu_gp_fqs(rsp, fqs_state);
1529 trace_rcu_grace_period(rsp->name,
1530 ACCESS_ONCE(rsp->gpnum),
1531 TPS("fqsend"));
1517 cond_resched(); 1532 cond_resched();
1518 } else { 1533 } else {
1519 /* Deal with stray signal. */ 1534 /* Deal with stray signal. */
1520 cond_resched(); 1535 cond_resched();
1521 flush_signals(current); 1536 flush_signals(current);
1537 trace_rcu_grace_period(rsp->name,
1538 ACCESS_ONCE(rsp->gpnum),
1539 TPS("fqswaitsig"));
1522 } 1540 }
1523 j = jiffies_till_next_fqs; 1541 j = jiffies_till_next_fqs;
1524 if (j > HZ) { 1542 if (j > HZ) {