diff options
author | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2013-08-09 15:19:29 -0400 |
---|---|---|
committer | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2013-09-23 12:16:14 -0400 |
commit | 63c4db78e80407976e47bccaa2a4d8251b5a10bc (patch) | |
tree | 31b832426eec3bf0e954440afe461b388f84e12d | |
parent | 591c6d1710cd73824057d08eda302cf2a7cfd18a (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.h | 28 | ||||
-rw-r--r-- | kernel/rcutree.c | 18 |
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 | */ |
52 | TRACE_EVENT(rcu_grace_period, | 62 | TRACE_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) { |