diff options
author | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2014-03-12 10:10:41 -0400 |
---|---|---|
committer | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2014-05-14 12:46:09 -0400 |
commit | afea227fd4acf4f097a9e77bbc2f07d4856ebd01 (patch) | |
tree | 9dfd0074fb7d95551701927bac86aa30670dcd43 /kernel/rcu | |
parent | 945fa9c631b04febe295a3a2a00c7e4a3cfb97db (diff) |
rcutorture: Export RCU grace-period kthread wait state to rcutorture
This commit allows rcutorture to print additional state for the
RCU grace-period kthreads in cases where RCU seems reluctant to
start a new grace period.
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Reviewed-by: Josh Triplett <josh@joshtriplett.org>
Diffstat (limited to 'kernel/rcu')
-rw-r--r-- | kernel/rcu/rcutorture.c | 1 | ||||
-rw-r--r-- | kernel/rcu/tree.c | 17 | ||||
-rw-r--r-- | kernel/rcu/tree.h | 8 |
3 files changed, 25 insertions, 1 deletions
diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c index 9decce0f110c..37ae5e1d4a1d 100644 --- a/kernel/rcu/rcutorture.c +++ b/kernel/rcu/rcutorture.c | |||
@@ -1034,6 +1034,7 @@ rcu_torture_printk(char *page) | |||
1034 | "??? Writer stall state %d g%lu c%lu f%#x\n", | 1034 | "??? Writer stall state %d g%lu c%lu f%#x\n", |
1035 | rcu_torture_writer_state, | 1035 | rcu_torture_writer_state, |
1036 | gpnum, completed, flags); | 1036 | gpnum, completed, flags); |
1037 | show_rcu_gp_kthreads(); | ||
1037 | rcutorture_trace_dump(); | 1038 | rcutorture_trace_dump(); |
1038 | } | 1039 | } |
1039 | rtcv_snap = rcu_torture_current_version; | 1040 | rtcv_snap = rcu_torture_current_version; |
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c index 3d15b5a82ae8..93e64381aa2a 100644 --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c | |||
@@ -280,6 +280,21 @@ void rcu_bh_force_quiescent_state(void) | |||
280 | EXPORT_SYMBOL_GPL(rcu_bh_force_quiescent_state); | 280 | EXPORT_SYMBOL_GPL(rcu_bh_force_quiescent_state); |
281 | 281 | ||
282 | /* | 282 | /* |
283 | * Show the state of the grace-period kthreads. | ||
284 | */ | ||
285 | void show_rcu_gp_kthreads(void) | ||
286 | { | ||
287 | struct rcu_state *rsp; | ||
288 | |||
289 | for_each_rcu_flavor(rsp) { | ||
290 | pr_info("%s: wait state: %d ->state: %#lx\n", | ||
291 | rsp->name, rsp->gp_state, rsp->gp_kthread->state); | ||
292 | /* sched_show_task(rsp->gp_kthread); */ | ||
293 | } | ||
294 | } | ||
295 | EXPORT_SYMBOL_GPL(show_rcu_gp_kthreads); | ||
296 | |||
297 | /* | ||
283 | * Record the number of times rcutorture tests have been initiated and | 298 | * Record the number of times rcutorture tests have been initiated and |
284 | * terminated. This information allows the debugfs tracing stats to be | 299 | * terminated. This information allows the debugfs tracing stats to be |
285 | * correlated to the rcutorture messages, even when the rcutorture module | 300 | * correlated to the rcutorture messages, even when the rcutorture module |
@@ -1626,6 +1641,7 @@ static int __noreturn rcu_gp_kthread(void *arg) | |||
1626 | trace_rcu_grace_period(rsp->name, | 1641 | trace_rcu_grace_period(rsp->name, |
1627 | ACCESS_ONCE(rsp->gpnum), | 1642 | ACCESS_ONCE(rsp->gpnum), |
1628 | TPS("reqwait")); | 1643 | TPS("reqwait")); |
1644 | rsp->gp_state = RCU_GP_WAIT_GPS; | ||
1629 | wait_event_interruptible(rsp->gp_wq, | 1645 | wait_event_interruptible(rsp->gp_wq, |
1630 | ACCESS_ONCE(rsp->gp_flags) & | 1646 | ACCESS_ONCE(rsp->gp_flags) & |
1631 | RCU_GP_FLAG_INIT); | 1647 | RCU_GP_FLAG_INIT); |
@@ -1653,6 +1669,7 @@ static int __noreturn rcu_gp_kthread(void *arg) | |||
1653 | trace_rcu_grace_period(rsp->name, | 1669 | trace_rcu_grace_period(rsp->name, |
1654 | ACCESS_ONCE(rsp->gpnum), | 1670 | ACCESS_ONCE(rsp->gpnum), |
1655 | TPS("fqswait")); | 1671 | TPS("fqswait")); |
1672 | rsp->gp_state = RCU_GP_WAIT_FQS; | ||
1656 | ret = wait_event_interruptible_timeout(rsp->gp_wq, | 1673 | ret = wait_event_interruptible_timeout(rsp->gp_wq, |
1657 | ((gf = ACCESS_ONCE(rsp->gp_flags)) & | 1674 | ((gf = ACCESS_ONCE(rsp->gp_flags)) & |
1658 | RCU_GP_FLAG_FQS) || | 1675 | RCU_GP_FLAG_FQS) || |
diff --git a/kernel/rcu/tree.h b/kernel/rcu/tree.h index 75dc3c39a02a..c2fd1e722879 100644 --- a/kernel/rcu/tree.h +++ b/kernel/rcu/tree.h | |||
@@ -406,7 +406,8 @@ struct rcu_state { | |||
406 | unsigned long completed; /* # of last completed gp. */ | 406 | unsigned long completed; /* # of last completed gp. */ |
407 | struct task_struct *gp_kthread; /* Task for grace periods. */ | 407 | struct task_struct *gp_kthread; /* Task for grace periods. */ |
408 | wait_queue_head_t gp_wq; /* Where GP task waits. */ | 408 | wait_queue_head_t gp_wq; /* Where GP task waits. */ |
409 | int gp_flags; /* Commands for GP task. */ | 409 | short gp_flags; /* Commands for GP task. */ |
410 | short gp_state; /* GP kthread sleep state. */ | ||
410 | 411 | ||
411 | /* End of fields guarded by root rcu_node's lock. */ | 412 | /* End of fields guarded by root rcu_node's lock. */ |
412 | 413 | ||
@@ -469,6 +470,11 @@ struct rcu_state { | |||
469 | #define RCU_GP_FLAG_INIT 0x1 /* Need grace-period initialization. */ | 470 | #define RCU_GP_FLAG_INIT 0x1 /* Need grace-period initialization. */ |
470 | #define RCU_GP_FLAG_FQS 0x2 /* Need grace-period quiescent-state forcing. */ | 471 | #define RCU_GP_FLAG_FQS 0x2 /* Need grace-period quiescent-state forcing. */ |
471 | 472 | ||
473 | /* Values for rcu_state structure's gp_flags field. */ | ||
474 | #define RCU_GP_WAIT_INIT 0 /* Initial state. */ | ||
475 | #define RCU_GP_WAIT_GPS 1 /* Wait for grace-period start. */ | ||
476 | #define RCU_GP_WAIT_FQS 2 /* Wait for force-quiescent-state time. */ | ||
477 | |||
472 | extern struct list_head rcu_struct_flavors; | 478 | extern struct list_head rcu_struct_flavors; |
473 | 479 | ||
474 | /* Sequence through rcu_state structures for each RCU flavor. */ | 480 | /* Sequence through rcu_state structures for each RCU flavor. */ |