diff options
author | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2015-11-17 16:25:21 -0500 |
---|---|---|
committer | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2015-12-04 15:26:53 -0500 |
commit | 72611ab9f5d2d384a04e72d560c9c82463115cbf (patch) | |
tree | 46daecec76847f22b9cc89f80c222fa027122d04 /kernel/rcu/tree.c | |
parent | 73f36f9de8bed78bcda2704a348594c20518b455 (diff) |
rcu: Add more diagnostics to expedited stall warning messages.
This commit adds print statements that check the rcu_node structure to
find which ->expmask bits and which ->exp_tasks structures are blocking
the current expedited grace period.
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Diffstat (limited to 'kernel/rcu/tree.c')
-rw-r--r-- | kernel/rcu/tree.c | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c index bc6b79716a86..6a652d1f3d7f 100644 --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c | |||
@@ -3745,6 +3745,7 @@ static void synchronize_sched_expedited_wait(struct rcu_state *rsp) | |||
3745 | unsigned long jiffies_stall; | 3745 | unsigned long jiffies_stall; |
3746 | unsigned long jiffies_start; | 3746 | unsigned long jiffies_start; |
3747 | unsigned long mask; | 3747 | unsigned long mask; |
3748 | int ndetected; | ||
3748 | struct rcu_node *rnp; | 3749 | struct rcu_node *rnp; |
3749 | struct rcu_node *rnp_root = rcu_get_root(rsp); | 3750 | struct rcu_node *rnp_root = rcu_get_root(rsp); |
3750 | int ret; | 3751 | int ret; |
@@ -3767,14 +3768,16 @@ static void synchronize_sched_expedited_wait(struct rcu_state *rsp) | |||
3767 | } | 3768 | } |
3768 | pr_err("INFO: %s detected expedited stalls on CPUs/tasks: {", | 3769 | pr_err("INFO: %s detected expedited stalls on CPUs/tasks: {", |
3769 | rsp->name); | 3770 | rsp->name); |
3771 | ndetected = 0; | ||
3770 | rcu_for_each_leaf_node(rsp, rnp) { | 3772 | rcu_for_each_leaf_node(rsp, rnp) { |
3771 | (void)rcu_print_task_exp_stall(rnp); | 3773 | ndetected = rcu_print_task_exp_stall(rnp); |
3772 | mask = 1; | 3774 | mask = 1; |
3773 | for (cpu = rnp->grplo; cpu <= rnp->grphi; cpu++, mask <<= 1) { | 3775 | for (cpu = rnp->grplo; cpu <= rnp->grphi; cpu++, mask <<= 1) { |
3774 | struct rcu_data *rdp; | 3776 | struct rcu_data *rdp; |
3775 | 3777 | ||
3776 | if (!(rnp->expmask & mask)) | 3778 | if (!(rnp->expmask & mask)) |
3777 | continue; | 3779 | continue; |
3780 | ndetected++; | ||
3778 | rdp = per_cpu_ptr(rsp->rda, cpu); | 3781 | rdp = per_cpu_ptr(rsp->rda, cpu); |
3779 | pr_cont(" %d-%c%c%c", cpu, | 3782 | pr_cont(" %d-%c%c%c", cpu, |
3780 | "O."[cpu_online(cpu)], | 3783 | "O."[cpu_online(cpu)], |
@@ -3783,8 +3786,23 @@ static void synchronize_sched_expedited_wait(struct rcu_state *rsp) | |||
3783 | } | 3786 | } |
3784 | mask <<= 1; | 3787 | mask <<= 1; |
3785 | } | 3788 | } |
3786 | pr_cont(" } %lu jiffies s: %lu\n", | 3789 | pr_cont(" } %lu jiffies s: %lu root: %#lx/%c\n", |
3787 | jiffies - jiffies_start, rsp->expedited_sequence); | 3790 | jiffies - jiffies_start, rsp->expedited_sequence, |
3791 | rnp_root->expmask, ".T"[!!rnp_root->exp_tasks]); | ||
3792 | if (!ndetected) { | ||
3793 | pr_err("blocking rcu_node structures:"); | ||
3794 | rcu_for_each_node_breadth_first(rsp, rnp) { | ||
3795 | if (rnp == rnp_root) | ||
3796 | continue; /* printed unconditionally */ | ||
3797 | if (sync_rcu_preempt_exp_done(rnp)) | ||
3798 | continue; | ||
3799 | pr_cont(" l=%u:%d-%d:%#lx/%c", | ||
3800 | rnp->level, rnp->grplo, rnp->grphi, | ||
3801 | rnp->expmask, | ||
3802 | ".T"[!!rnp->exp_tasks]); | ||
3803 | } | ||
3804 | pr_cont("\n"); | ||
3805 | } | ||
3788 | rcu_for_each_leaf_node(rsp, rnp) { | 3806 | rcu_for_each_leaf_node(rsp, rnp) { |
3789 | mask = 1; | 3807 | mask = 1; |
3790 | for (cpu = rnp->grplo; cpu <= rnp->grphi; cpu++, mask <<= 1) { | 3808 | for (cpu = rnp->grplo; cpu <= rnp->grphi; cpu++, mask <<= 1) { |