On 07/25/2014 07:15 PM, Paul E. McKenney wrote: > On Fri, Jul 25, 2014 at 06:23:41PM -0400, Pranith Kumar wrote: >> Here total is the total number of times we enter th function rcu_report_qs_rsp() >> and unnecessary is the times we call wake_up() unnecessarily. >> case1, 2, 3 are the cases I listed above. >> >> Note that the frequency has gone way up than before, I am not sure why that is. >> >> *ALL* the wakeups seem to be unnecessary from that location. And the >> main reason is that gp_flags is 0. >> >> My rcugp file has the following: >> >> completed=257515 gpnum=257516 age=1 max=1684 >> >> Thoughts? > Hard to believe in the rcutorture case. My guess was that rcutorture was > doing about 9000 wakeups, 2000 of which were unnecessary. Which would > of course still tilt things very much in favor of your patch. > > I am not surprised in the mostly-idle case, as the RCU grace-period > kthread would most likely be the one ending the grace period, which > would therefore almost always be a self-wakeup. > > Any chance of a peek at your debugging code? > > Thanx, Paul > Sure, I am also attaching my dmesg output. Hope it helps! -- Pranith --- kernel/rcu/tree.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c index 946d47b..10ac44e 100644 --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c @@ -1936,8 +1936,27 @@ static bool rcu_start_gp(struct rcu_state *rsp) static void rcu_report_qs_rsp(struct rcu_state *rsp, unsigned long flags) __releases(rcu_get_root(rsp)->lock) { + static unsigned long total_wakeups = 0, unnecessary_wakeups = 0; + static unsigned long case1 = 0, case2 = 0, case3 = 0; + WARN_ON_ONCE(!rcu_gp_in_progress(rsp)); raw_spin_unlock_irqrestore(&rcu_get_root(rsp)->lock, flags); + total_wakeups++; + + if (current == rsp->gp_kthread || + !ACCESS_ONCE(rsp->gp_flags) || + !rsp->gp_kthread) { + + unnecessary_wakeups++; + if (current == rsp->gp_kthread) case1++; + if (!ACCESS_ONCE(rsp->gp_flags)) case2++; + if (!rsp->gp_kthread) case3++; + + if (unnecessary_wakeups % 2000 == 0) + pr_info("Total:%lu, unnecessary:%lu, case1:%lu, case2:%lu, case3:%lu\n", + total_wakeups, unnecessary_wakeups, case1, case2, case3); + + } wake_up(&rsp->gp_wq); /* Memory barrier implied by wake_up() path. */ } -- 2.0.1