diff options
| author | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2010-02-22 20:05:05 -0500 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2010-02-25 04:35:02 -0500 |
| commit | 1ed509a225008c9e8c0644fbd22168e09a7383a0 (patch) | |
| tree | db65a58258bb968e7bc922dab14f4f0714a7667e | |
| parent | 6155fec92e85f07d99e9746234496215443ffb0d (diff) | |
rcu: Add RCU_CPU_STALL_VERBOSE to dump detailed per-task information
When RCU detects a grace-period stall, it currently just prints
out the PID of any tasks doing the stalling. This patch adds
RCU_CPU_STALL_VERBOSE, which enables the more-verbose reporting
from sched_show_task().
Suggested-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: laijs@cn.fujitsu.com
Cc: dipankar@in.ibm.com
Cc: mathieu.desnoyers@polymtl.ca
Cc: josh@joshtriplett.org
Cc: dvhltc@us.ibm.com
Cc: niv@us.ibm.com
Cc: peterz@infradead.org
Cc: rostedt@goodmis.org
Cc: Valdis.Kletnieks@vt.edu
Cc: dhowells@redhat.com
LKML-Reference: <1266887105-1528-21-git-send-email-paulmck@linux.vnet.ibm.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
| -rw-r--r-- | kernel/rcutree.c | 4 | ||||
| -rw-r--r-- | kernel/rcutree.h | 1 | ||||
| -rw-r--r-- | kernel/rcutree_plugin.h | 52 | ||||
| -rw-r--r-- | lib/Kconfig.debug | 12 |
4 files changed, 69 insertions, 0 deletions
diff --git a/kernel/rcutree.c b/kernel/rcutree.c index b07be37d2aa3..525d39810616 100644 --- a/kernel/rcutree.c +++ b/kernel/rcutree.c | |||
| @@ -489,6 +489,10 @@ static void print_other_cpu_stall(struct rcu_state *rsp) | |||
| 489 | smp_processor_id(), (long)(jiffies - rsp->gp_start)); | 489 | smp_processor_id(), (long)(jiffies - rsp->gp_start)); |
| 490 | trigger_all_cpu_backtrace(); | 490 | trigger_all_cpu_backtrace(); |
| 491 | 491 | ||
| 492 | /* If so configured, complain about tasks blocking the grace period. */ | ||
| 493 | |||
| 494 | rcu_print_detail_task_stall(rsp); | ||
| 495 | |||
| 492 | force_quiescent_state(rsp, 0); /* Kick them all. */ | 496 | force_quiescent_state(rsp, 0); /* Kick them all. */ |
| 493 | } | 497 | } |
| 494 | 498 | ||
diff --git a/kernel/rcutree.h b/kernel/rcutree.h index 6a82c34ce669..2ceb08388582 100644 --- a/kernel/rcutree.h +++ b/kernel/rcutree.h | |||
| @@ -352,6 +352,7 @@ static void rcu_report_unblock_qs_rnp(struct rcu_node *rnp, | |||
| 352 | unsigned long flags); | 352 | unsigned long flags); |
| 353 | #endif /* #ifdef CONFIG_HOTPLUG_CPU */ | 353 | #endif /* #ifdef CONFIG_HOTPLUG_CPU */ |
| 354 | #ifdef CONFIG_RCU_CPU_STALL_DETECTOR | 354 | #ifdef CONFIG_RCU_CPU_STALL_DETECTOR |
| 355 | static void rcu_print_detail_task_stall(struct rcu_state *rsp); | ||
| 355 | static void rcu_print_task_stall(struct rcu_node *rnp); | 356 | static void rcu_print_task_stall(struct rcu_node *rnp); |
| 356 | #endif /* #ifdef CONFIG_RCU_CPU_STALL_DETECTOR */ | 357 | #endif /* #ifdef CONFIG_RCU_CPU_STALL_DETECTOR */ |
| 357 | static void rcu_preempt_check_blocked_tasks(struct rcu_node *rnp); | 358 | static void rcu_preempt_check_blocked_tasks(struct rcu_node *rnp); |
diff --git a/kernel/rcutree_plugin.h b/kernel/rcutree_plugin.h index aecfe37e0117..3516de7091a1 100644 --- a/kernel/rcutree_plugin.h +++ b/kernel/rcutree_plugin.h | |||
| @@ -312,6 +312,50 @@ EXPORT_SYMBOL_GPL(__rcu_read_unlock); | |||
| 312 | 312 | ||
| 313 | #ifdef CONFIG_RCU_CPU_STALL_DETECTOR | 313 | #ifdef CONFIG_RCU_CPU_STALL_DETECTOR |
| 314 | 314 | ||
| 315 | #ifdef CONFIG_RCU_CPU_STALL_VERBOSE | ||
| 316 | |||
| 317 | /* | ||
| 318 | * Dump detailed information for all tasks blocking the current RCU | ||
| 319 | * grace period on the specified rcu_node structure. | ||
| 320 | */ | ||
| 321 | static void rcu_print_detail_task_stall_rnp(struct rcu_node *rnp) | ||
| 322 | { | ||
| 323 | unsigned long flags; | ||
| 324 | struct list_head *lp; | ||
| 325 | int phase; | ||
| 326 | struct task_struct *t; | ||
| 327 | |||
| 328 | if (rcu_preempted_readers(rnp)) { | ||
| 329 | raw_spin_lock_irqsave(&rnp->lock, flags); | ||
| 330 | phase = rnp->gpnum & 0x1; | ||
| 331 | lp = &rnp->blocked_tasks[phase]; | ||
| 332 | list_for_each_entry(t, lp, rcu_node_entry) | ||
| 333 | sched_show_task(t); | ||
| 334 | raw_spin_unlock_irqrestore(&rnp->lock, flags); | ||
| 335 | } | ||
| 336 | } | ||
| 337 | |||
| 338 | /* | ||
| 339 | * Dump detailed information for all tasks blocking the current RCU | ||
| 340 | * grace period. | ||
| 341 | */ | ||
| 342 | static void rcu_print_detail_task_stall(struct rcu_state *rsp) | ||
| 343 | { | ||
| 344 | struct rcu_node *rnp = rcu_get_root(rsp); | ||
| 345 | |||
| 346 | rcu_print_detail_task_stall_rnp(rnp); | ||
| 347 | rcu_for_each_leaf_node(rsp, rnp) | ||
| 348 | rcu_print_detail_task_stall_rnp(rnp); | ||
| 349 | } | ||
| 350 | |||
| 351 | #else /* #ifdef CONFIG_RCU_CPU_STALL_VERBOSE */ | ||
| 352 | |||
| 353 | static void rcu_print_detail_task_stall(struct rcu_state *rsp) | ||
| 354 | { | ||
| 355 | } | ||
| 356 | |||
| 357 | #endif /* #else #ifdef CONFIG_RCU_CPU_STALL_VERBOSE */ | ||
| 358 | |||
| 315 | /* | 359 | /* |
| 316 | * Scan the current list of tasks blocked within RCU read-side critical | 360 | * Scan the current list of tasks blocked within RCU read-side critical |
| 317 | * sections, printing out the tid of each. | 361 | * sections, printing out the tid of each. |
| @@ -764,6 +808,14 @@ static void rcu_report_unblock_qs_rnp(struct rcu_node *rnp, unsigned long flags) | |||
| 764 | * Because preemptable RCU does not exist, we never have to check for | 808 | * Because preemptable RCU does not exist, we never have to check for |
| 765 | * tasks blocked within RCU read-side critical sections. | 809 | * tasks blocked within RCU read-side critical sections. |
| 766 | */ | 810 | */ |
| 811 | static void rcu_print_detail_task_stall(struct rcu_state *rsp) | ||
| 812 | { | ||
| 813 | } | ||
| 814 | |||
| 815 | /* | ||
| 816 | * Because preemptable RCU does not exist, we never have to check for | ||
| 817 | * tasks blocked within RCU read-side critical sections. | ||
| 818 | */ | ||
| 767 | static void rcu_print_task_stall(struct rcu_node *rnp) | 819 | static void rcu_print_task_stall(struct rcu_node *rnp) |
| 768 | { | 820 | { |
| 769 | } | 821 | } |
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 6af20a8a0a54..4cdab452bfe2 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug | |||
| @@ -781,6 +781,18 @@ config RCU_CPU_STALL_DETECTOR | |||
| 781 | 781 | ||
| 782 | Say Y if you are unsure. | 782 | Say Y if you are unsure. |
| 783 | 783 | ||
| 784 | config RCU_CPU_STALL_VERBOSE | ||
| 785 | bool "Print additional per-task information for RCU_CPU_STALL_DETECTOR" | ||
| 786 | depends on RCU_CPU_STALL_DETECTOR && TREE_PREEMPT_RCU | ||
| 787 | default n | ||
| 788 | help | ||
| 789 | This option causes RCU to printk detailed per-task information | ||
| 790 | for any tasks that are stalling the current RCU grace period. | ||
| 791 | |||
| 792 | Say N if you are unsure. | ||
| 793 | |||
| 794 | Say Y if you want to enable such checks. | ||
| 795 | |||
| 784 | config KPROBES_SANITY_TEST | 796 | config KPROBES_SANITY_TEST |
| 785 | bool "Kprobes sanity tests" | 797 | bool "Kprobes sanity tests" |
| 786 | depends on DEBUG_KERNEL | 798 | depends on DEBUG_KERNEL |
