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. */ |
