diff options
-rw-r--r-- | include/linux/rcutiny.h | 4 | ||||
-rw-r--r-- | include/linux/rcutree.h | 1 | ||||
-rw-r--r-- | kernel/rcu/rcutorture.c | 1 | ||||
-rw-r--r-- | kernel/rcu/tree.c | 17 | ||||
-rw-r--r-- | kernel/rcu/tree.h | 8 |
5 files changed, 30 insertions, 1 deletions
diff --git a/include/linux/rcutiny.h b/include/linux/rcutiny.h index 425c659d54e5..d40a6a451330 100644 --- a/include/linux/rcutiny.h +++ b/include/linux/rcutiny.h | |||
@@ -119,6 +119,10 @@ static inline void rcu_sched_force_quiescent_state(void) | |||
119 | { | 119 | { |
120 | } | 120 | } |
121 | 121 | ||
122 | static inline void show_rcu_gp_kthreads(void) | ||
123 | { | ||
124 | } | ||
125 | |||
122 | static inline void rcu_cpu_stall_reset(void) | 126 | static inline void rcu_cpu_stall_reset(void) |
123 | { | 127 | { |
124 | } | 128 | } |
diff --git a/include/linux/rcutree.h b/include/linux/rcutree.h index a59ca05fd4e3..3e2f5d432743 100644 --- a/include/linux/rcutree.h +++ b/include/linux/rcutree.h | |||
@@ -84,6 +84,7 @@ extern unsigned long rcutorture_vernum; | |||
84 | long rcu_batches_completed(void); | 84 | long rcu_batches_completed(void); |
85 | long rcu_batches_completed_bh(void); | 85 | long rcu_batches_completed_bh(void); |
86 | long rcu_batches_completed_sched(void); | 86 | long rcu_batches_completed_sched(void); |
87 | void show_rcu_gp_kthreads(void); | ||
87 | 88 | ||
88 | void rcu_force_quiescent_state(void); | 89 | void rcu_force_quiescent_state(void); |
89 | void rcu_bh_force_quiescent_state(void); | 90 | void rcu_bh_force_quiescent_state(void); |
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. */ |