Skip to contentSkip to conversation

RCU related performance regression in 3.3

DISCUSSION Pascal Chapperon 2 participants 14 messages Apr 27, 2012 – May 18, 2012

Subsystems (3)
lore
Share & tools
lore
#0 lore raw
Quoted 24 lines · Paul E. McKenney
Quoted 17 lines · Pascal Chapperon
Quoted 8 lines · Paul E. McKenney
Quoted 4 lines · Pascal Chapperon

Mount and umount operations are not slower with RCU_FAST_NO_HZ during runtime; systemctl start and stop operations are also not slower. In fact, i couldn't find a single operation slower during runtime with RCU_FAST_NO_HZ.

Your boot-time setup is such that all CPUs are online before the boot-time mount operations take place, right?

Yes :

[ 0.242697] Brought up 8 CPUs
[ 0.242699] Total of 8 processors activated (35118.33 BogoMIPS).
Quoted 4 lines

Struggling to understand
how RCU can tell the difference between post-CPU-bringup boot time and run time...

Quoted 5 lines

systemd is controlling the whole boot process including mount operation (apart root filesystem) and as I can see, uses heavily sockets to do it (not to mention cpu-affinity). It controls also the major part of umount operations. Is it possible that your patch hits a systemd bug ?

Quoted 8 lines

Is it possible that systemd is using network operations that include synchronize_rcu()? Then if you did the same operation from the command line at runtime, you might not see the slowdown.

Is it possible for you to convince systemd to collect RCU event tracing during the slow operation? RCU event tracing is available under /sys/kernel/debug/tracing/rcu.

.
I have collected the RCU event tracing during a slow boot with FAST_NO_HZ (and the same without FAST_NO_HZ, same kernel config). The full logs and associated "systemd-analyze plot" can be found (in comment 32) at :

https://bugzilla.redhat.com/show_bug.cgi?id=806548

With FAST_NO_HZ, almost each rcu_prep_idle is followed by ksoftirqd (75000 ksoftirqd lines with FAST_NO_HZ, 4000 without).

Sorry, the logs are very huge, but I can't figure where are the plots of some interest.

Pascal

#1 lore raw
Quoted 39 lines · Pascal Chapperon
Quoted 24 lines · Paul E. McKenney
Quoted 17 lines · Pascal Chapperon
Quoted 8 lines · Paul E. McKenney
Quoted 4 lines · Pascal Chapperon

Mount and umount operations are not slower with RCU_FAST_NO_HZ during runtime; systemctl start and stop operations are also not slower. In fact, i couldn't find a single operation slower during runtime with RCU_FAST_NO_HZ.

Your boot-time setup is such that all CPUs are online before the boot-time mount operations take place, right?

Yes :

[ 0.242697] Brought up 8 CPUs
[ 0.242699] Total of 8 processors activated (35118.33 BogoMIPS).
Quoted 4 lines

Struggling to understand
how RCU can tell the difference between post-CPU-bringup boot time and run time...

Quoted 5 lines

systemd is controlling the whole boot process including mount operation (apart root filesystem) and as I can see, uses heavily sockets to do it (not to mention cpu-affinity). It controls also the major part of umount operations. Is it possible that your patch hits a systemd bug ?

Quoted 8 lines

Is it possible that systemd is using network operations that include synchronize_rcu()? Then if you did the same operation from the command line at runtime, you might not see the slowdown.

Is it possible for you to convince systemd to collect RCU event tracing during the slow operation? RCU event tracing is available under /sys/kernel/debug/tracing/rcu.

.
I have collected the RCU event tracing during a slow boot with FAST_NO_HZ (and the same without FAST_NO_HZ, same kernel config). The full logs and associated "systemd-analyze plot" can be found (in comment 32) at :

Quoted 7 lines

https://bugzilla.redhat.com/show_bug.cgi?id=806548

With FAST_NO_HZ, almost each rcu_prep_idle is followed by ksoftirqd (75000 ksoftirqd lines with FAST_NO_HZ, 4000 without).

Sorry, the logs are very huge, but I can't figure where are the plots of some interest.

Thank you for collecting them! I clearly will need to do some scripting. ;-)

Thanx, Paul

#2 lore raw
Quoted 42 lines · Paul E. McKenney
Quoted 41 lines · Pascal Chapperon
Quoted 24 lines · Paul E. McKenney
Quoted 17 lines · Pascal Chapperon
Quoted 8 lines · Paul E. McKenney
Quoted 4 lines · Pascal Chapperon

Mount and umount operations are not slower with RCU_FAST_NO_HZ during runtime; systemctl start and stop operations are also not slower. In fact, i couldn't find a single operation slower during runtime with RCU_FAST_NO_HZ.

Your boot-time setup is such that all CPUs are online before the boot-time mount operations take place, right?

Yes :

[ 0.242697] Brought up 8 CPUs
[ 0.242699] Total of 8 processors activated (35118.33 BogoMIPS).
Quoted 4 lines

Struggling to understand
how RCU can tell the difference between post-CPU-bringup boot time and run time...

Quoted 5 lines

systemd is controlling the whole boot process including mount operation (apart root filesystem) and as I can see, uses heavily sockets to do it (not to mention cpu-affinity). It controls also the major part of umount operations. Is it possible that your patch hits a systemd bug ?

Quoted 8 lines

Is it possible that systemd is using network operations that include synchronize_rcu()? Then if you did the same operation from the command line at runtime, you might not see the slowdown.

Is it possible for you to convince systemd to collect RCU event tracing during the slow operation? RCU event tracing is available under /sys/kernel/debug/tracing/rcu.

.
I have collected the RCU event tracing during a slow boot with FAST_NO_HZ (and the same without FAST_NO_HZ, same kernel config). The full logs and associated "systemd-analyze plot" can be found (in comment 32) at :

https://bugzilla.redhat.com/show_bug.cgi?id=806548

Quoted 7 lines
Quoted 5 lines

With FAST_NO_HZ, almost each rcu_prep_idle is followed by ksoftirqd (75000 ksoftirqd lines with FAST_NO_HZ, 4000 without).

Sorry, the logs are very huge, but I can't figure where are the plots of some interest.

Thank you for collecting them! I clearly will need to do some scripting. ;-)

And it appears that your system is migrating timers without waking up the CPU on which the timer was posted. This explains the slowdowns:
RCU assumes that the timer will either fire on the CPU that it was posted on or that that CPU will be awakened when it goes offline. If the timer does not fire on that CPU and that CPU is not otherwise awakened, then that CPU's RCU callbacks can be indefinitely postponed, which could account for the slowdowns that you were seeing.

Please see below for a lightly tested patch that should address this problem, and thank you again for your patient testing efforts!

Thanx, Paul

------------------------------------------------------------------------

rcu: Make RCU_FAST_NO_HZ handle timer migration

The current RCU_FAST_NO_HZ assumes that timers do not migrate unless a CPU goes offline, in which case it assumes that the CPU will have to come out of dyntick-idle mode (cancelling the timer) in order to go offline. This is important because when RCU_FAST_NO_HZ permits a CPU to enter dyntick-idle mode despite having RCU callbacks pending, it posts a timer on that CPU to force a wakeup on that CPU. This wakeup ensures that the CPU will eventually handle the end of the grace period, including invoking its RCU callbacks.

However, Pascal Chapperon's test setup shows that the timer handler rcu_idle_gp_timer_func() really does get invoked in some cases. This is problematic because this can cause the CPU that entered dyntick-idle mode despite still having RCU callbacks pending to remain in dyntick-idle mode indefinitely, which means that its RCU callbacks might never be invoked. This situation can result in grace-period delays or even system hangs, which matches Pascal's observations of slow boot-up and shutdown (https://lkml.org/lkml/2012/4/5/142). See also the bugzilla:

https://bugzilla.redhat.com/show_bug.cgi?id=806548

This commit therefore causes the "should never be invoked" timer handler rcu_idle_gp_timer_func() to use smp_call_function_single() to wake up the CPU for which the timer was intended, allowing that CPU to invoke its RCU callbacks in a timely manner.

---

 include/trace/events/rcu.h |    1 +
 kernel/rcutree_plugin.h    |   23 ++++++++++++++++++++---
 2 files changed, 21 insertions(+), 3 deletions(-)
include/trace/events/rcu.h +1 -0
index aaa55e1..1480900 100644
@@ -292,6 +292,7 @@ TRACE_EVENT(rcu_dyntick,
  *	"More callbacks": Still more callbacks, try again to clear them out.
  *	"Callbacks drained": All callbacks processed, off to dyntick idle!
  *	"Timer": Timer fired to cause CPU to continue processing callbacks.
+ *	"Demigrate": Timer fired on wrong CPU, woke up correct CPU.
  *	"Cleanup after idle": Idle exited, timer canceled.
  */
 TRACE_EVENT(rcu_prep_idle,
kernel/rcutree_plugin.h +20 -3
index dc12efc..bbd064a 100644
@@ -1994,16 +1994,33 @@ static bool rcu_cpu_has_nonlazy_callbacks(int cpu)
 }
 
 /*
+ *
+ */
+void rcu_idle_demigrate(void *unused)
+{
+	trace_rcu_prep_idle("Demigrate");
+}
+
+/*
  * Timer handler used to force CPU to start pushing its remaining RCU
  * callbacks in the case where it entered dyntick-idle mode with callbacks
  * pending.  The hander doesn't really need to do anything because the
  * real work is done upon re-entry to idle, or by the next scheduling-clock
  * interrupt should idle not be re-entered.
+ *
+ * One special case: the timer gets migrated without awakening the CPU
+ * on which the timer was scheduled on.  In this case, we must wake up
+ * that CPU.  We do so with smp_call_function_single().
  */
-static void rcu_idle_gp_timer_func(unsigned long unused)
+static void rcu_idle_gp_timer_func(unsigned long cpu_in)
 {
-	WARN_ON_ONCE(1); /* Getting here can hang the system... */
+	int cpu = (int)cpu_in;
+
 	trace_rcu_prep_idle("Timer");
+	if (cpu != smp_processor_id())
+		smp_call_function_single(cpu, rcu_idle_demigrate, NULL, 0);
+	else
+		WARN_ON_ONCE(1); /* Getting here can hang the system... */
 }
 
 /*
@@ -2012,7 +2029,7 @@ static void rcu_idle_gp_timer_func(unsigned long unused)
 static void rcu_prepare_for_idle_init(int cpu)
 {
 	setup_timer(&per_cpu(rcu_idle_gp_timer, cpu),
-		    rcu_idle_gp_timer_func, 0);
+		    rcu_idle_gp_timer_func, cpu);
 }
 
 /*
#3 lore raw
Quoted 157 lines · Paul E. McKenney
Quoted 42 lines · Paul E. McKenney
Quoted 41 lines · Pascal Chapperon
Quoted 24 lines · Paul E. McKenney
Quoted 17 lines · Pascal Chapperon
Quoted 8 lines · Paul E. McKenney
Quoted 4 lines · Pascal Chapperon

Mount and umount operations are not slower with RCU_FAST_NO_HZ during runtime; systemctl start and stop operations are also not slower. In fact, i couldn't find a single operation slower during runtime with RCU_FAST_NO_HZ.

Your boot-time setup is such that all CPUs are online before the boot-time mount operations take place, right?

Yes :

[ 0.242697] Brought up 8 CPUs
[ 0.242699] Total of 8 processors activated (35118.33 BogoMIPS).
Quoted 4 lines

Struggling to understand
how RCU can tell the difference between post-CPU-bringup boot time and run time...

Quoted 5 lines

systemd is controlling the whole boot process including mount operation (apart root filesystem) and as I can see, uses heavily sockets to do it (not to mention cpu-affinity). It controls also the major part of umount operations. Is it possible that your patch hits a systemd bug ?

Quoted 8 lines

Is it possible that systemd is using network operations that include synchronize_rcu()? Then if you did the same operation from the command line at runtime, you might not see the slowdown.

Is it possible for you to convince systemd to collect RCU event tracing during the slow operation? RCU event tracing is available under /sys/kernel/debug/tracing/rcu.

.
I have collected the RCU event tracing during a slow boot with FAST_NO_HZ (and the same without FAST_NO_HZ, same kernel config). The full logs and associated "systemd-analyze plot" can be found (in comment 32) at :

https://bugzilla.redhat.com/show_bug.cgi?id=806548

Quoted 7 lines
Quoted 5 lines

With FAST_NO_HZ, almost each rcu_prep_idle is followed by ksoftirqd (75000 ksoftirqd lines with FAST_NO_HZ, 4000 without).

Sorry, the logs are very huge, but I can't figure where are the plots of some interest.

Thank you for collecting them! I clearly will need to do some scripting. ;-)

And it appears that your system is migrating timers without waking up the CPU on which the timer was posted. This explains the slowdowns:
RCU assumes that the timer will either fire on the CPU that it was posted on or that that CPU will be awakened when it goes offline. If the timer does not fire on that CPU and that CPU is not otherwise awakened, then that CPU's RCU callbacks can be indefinitely postponed, which could account for the slowdowns that you were seeing.

Please see below for a lightly tested patch that should address this problem, and thank you again for your patient testing efforts!

Thanx, Paul

------------------------------------------------------------------------

rcu: Make RCU_FAST_NO_HZ handle timer migration

The current RCU_FAST_NO_HZ assumes that timers do not migrate unless a CPU goes offline, in which case it assumes that the CPU will have to come out of dyntick-idle mode (cancelling the timer) in order to go offline. This is important because when RCU_FAST_NO_HZ permits a CPU to enter dyntick-idle mode despite having RCU callbacks pending, it posts a timer on that CPU to force a wakeup on that CPU. This wakeup ensures that the CPU will eventually handle the end of the grace period, including invoking its RCU callbacks.

However, Pascal Chapperon's test setup shows that the timer handler rcu_idle_gp_timer_func() really does get invoked in some cases. This is problematic because this can cause the CPU that entered dyntick-idle mode despite still having RCU callbacks pending to remain in dyntick-idle mode indefinitely, which means that its RCU callbacks might never be invoked. This situation can result in grace-period delays or even system hangs, which matches Pascal's observations of slow boot-up and shutdown (https://lkml.org/lkml/2012/4/5/142). See also the bugzilla:

https://bugzilla.redhat.com/show_bug.cgi?id=806548

This commit therefore causes the "should never be invoked" timer handler rcu_idle_gp_timer_func() to use smp_call_function_single() to wake up the CPU for which the timer was intended, allowing that CPU to invoke its RCU callbacks in a timely manner.

---

  include/trace/events/rcu.h |    1 +
  kernel/rcutree_plugin.h    |   23 ++++++++++++++++++++---
  2 files changed, 21 insertions(+), 3 deletions(-)
include/trace/events/rcu.h +1 -0
index aaa55e1..1480900 100644
@@ -292,6 +292,7 @@ TRACE_EVENT(rcu_dyntick,
   *	"More callbacks": Still more callbacks, try again to clear them out.
   *	"Callbacks drained": All callbacks processed, off to dyntick idle!
   *	"Timer": Timer fired to cause CPU to continue processing callbacks.
+ *	"Demigrate": Timer fired on wrong CPU, woke up correct CPU.
   *	"Cleanup after idle": Idle exited, timer canceled.
   */
  TRACE_EVENT(rcu_prep_idle,
kernel/rcutree_plugin.h +19 -2
index dc12efc..bbd064a 100644
@@ -1994,16 +1994,33 @@ static bool rcu_cpu_has_nonlazy_callbacks(int cpu)
  }
 
  /*
+ *
+ */
+void rcu_idle_demigrate(void *unused)
+{
+	trace_rcu_prep_idle("Demigrate");
+}
+
+/*
   * Timer handler used to force CPU to start pushing its remaining RCU
   * callbacks in the case where it entered dyntick-idle mode with callbacks
   * pending.  The hander doesn't really need to do anything because the
   * real work is done upon re-entry to idle, or by the next scheduling-clock
   * interrupt should idle not be re-entered.
+ *
+ * One special case: the timer gets migrated without awakening the CPU
+ * on which the timer was scheduled on.  In this case, we must wake up
+ * that CPU.  We do so with smp_call_function_single().
   */
-static void rcu_idle_gp_timer_func(unsigned long unused)
+static void rcu_idle_gp_timer_func(unsigned long cpu_in)
  {
-	WARN_ON_ONCE(1); /* Getting here can hang the system... */
+	int cpu = (int)cpu_in;
+
  	trace_rcu_prep_idle("Timer");
+	if (cpu != smp_processor_id())
+		smp_call_function_single(cpu, rcu_idle_demigrate, NULL, 0);
+	else
+		WARN_ON_ONCE(1); /* Getting here can hang the system... */
  }
 
  /*

kernel/rcutree_plugin.h static void rcu_idle_gp_timer_func(unsigned long unused) · line 2035

Quoted 8 lines
kernel/rcutree_plugin.h +1 -1
@@ -2012,7 +2029,7 @@ static void rcu_idle_gp_timer_func(unsigned long unused)
  static void rcu_prepare_for_idle_init(int cpu)
  {
  	setup_timer(&per_cpu(rcu_idle_gp_timer, cpu),
-		    rcu_idle_gp_timer_func, 0);
+		    rcu_idle_gp_timer_func, cpu);
  }
 
  /*

Paul, I can't apply your patch on top of master branch; perhaps I need to pull your own git repository ? Among other things, you have:
static void rcu_idle_gp_timer_func(unsigned long unused)
and I have:
static enum hrtimer_restart rcu_idle_gp_timer_func(struct hrtimer *hrtp)

Pascal

#4 lore raw
Quoted 163 lines · Pascal Chapperon
Quoted 162 lines · Paul E. McKenney
Quoted 42 lines · Paul E. McKenney
Quoted 41 lines · Pascal Chapperon
Quoted 24 lines · Paul E. McKenney
Quoted 17 lines · Pascal Chapperon
Quoted 8 lines · Paul E. McKenney
Quoted 4 lines · Pascal Chapperon

Mount and umount operations are not slower with RCU_FAST_NO_HZ during runtime; systemctl start and stop operations are also not slower. In fact, i couldn't find a single operation slower during runtime with RCU_FAST_NO_HZ.

Your boot-time setup is such that all CPUs are online before the boot-time mount operations take place, right?

Yes :

[ 0.242697] Brought up 8 CPUs
[ 0.242699] Total of 8 processors activated (35118.33 BogoMIPS).
Quoted 4 lines

Struggling to understand
how RCU can tell the difference between post-CPU-bringup boot time and run time...

Quoted 5 lines

systemd is controlling the whole boot process including mount operation (apart root filesystem) and as I can see, uses heavily sockets to do it (not to mention cpu-affinity). It controls also the major part of umount operations. Is it possible that your patch hits a systemd bug ?

Quoted 8 lines

Is it possible that systemd is using network operations that include synchronize_rcu()? Then if you did the same operation from the command line at runtime, you might not see the slowdown.

Is it possible for you to convince systemd to collect RCU event tracing during the slow operation? RCU event tracing is available under /sys/kernel/debug/tracing/rcu.

.
I have collected the RCU event tracing during a slow boot with FAST_NO_HZ (and the same without FAST_NO_HZ, same kernel config). The full logs and associated "systemd-analyze plot" can be found (in comment 32) at :

https://bugzilla.redhat.com/show_bug.cgi?id=806548

Quoted 7 lines
Quoted 5 lines

With FAST_NO_HZ, almost each rcu_prep_idle is followed by ksoftirqd (75000 ksoftirqd lines with FAST_NO_HZ, 4000 without).

Sorry, the logs are very huge, but I can't figure where are the plots of some interest.

Thank you for collecting them! I clearly will need to do some scripting. ;-)

And it appears that your system is migrating timers without waking up the CPU on which the timer was posted. This explains the slowdowns:
RCU assumes that the timer will either fire on the CPU that it was posted on or that that CPU will be awakened when it goes offline. If the timer does not fire on that CPU and that CPU is not otherwise awakened, then that CPU's RCU callbacks can be indefinitely postponed, which could account for the slowdowns that you were seeing.

Please see below for a lightly tested patch that should address this problem, and thank you again for your patient testing efforts!

Thanx, Paul

------------------------------------------------------------------------

rcu: Make RCU_FAST_NO_HZ handle timer migration

The current RCU_FAST_NO_HZ assumes that timers do not migrate unless a CPU goes offline, in which case it assumes that the CPU will have to come out of dyntick-idle mode (cancelling the timer) in order to go offline. This is important because when RCU_FAST_NO_HZ permits a CPU to enter dyntick-idle mode despite having RCU callbacks pending, it posts a timer on that CPU to force a wakeup on that CPU. This wakeup ensures that the CPU will eventually handle the end of the grace period, including invoking its RCU callbacks.

However, Pascal Chapperon's test setup shows that the timer handler rcu_idle_gp_timer_func() really does get invoked in some cases. This is problematic because this can cause the CPU that entered dyntick-idle mode despite still having RCU callbacks pending to remain in dyntick-idle mode indefinitely, which means that its RCU callbacks might never be invoked. This situation can result in grace-period delays or even system hangs, which matches Pascal's observations of slow boot-up and shutdown (https://lkml.org/lkml/2012/4/5/142). See also the bugzilla:

https://bugzilla.redhat.com/show_bug.cgi?id=806548

This commit therefore causes the "should never be invoked" timer handler rcu_idle_gp_timer_func() to use smp_call_function_single() to wake up the CPU for which the timer was intended, allowing that CPU to invoke its RCU callbacks in a timely manner.

---

 include/trace/events/rcu.h |    1 +
 kernel/rcutree_plugin.h    |   23 ++++++++++++++++++++---
 2 files changed, 21 insertions(+), 3 deletions(-)
include/trace/events/rcu.h +1 -0
index aaa55e1..1480900 100644
@@ -292,6 +292,7 @@ TRACE_EVENT(rcu_dyntick,
  *	"More callbacks": Still more callbacks, try again to clear them out.
  *	"Callbacks drained": All callbacks processed, off to dyntick idle!
  *	"Timer": Timer fired to cause CPU to continue processing callbacks.
+ *	"Demigrate": Timer fired on wrong CPU, woke up correct CPU.
  *	"Cleanup after idle": Idle exited, timer canceled.
  */
 TRACE_EVENT(rcu_prep_idle,
kernel/rcutree_plugin.h +20 -3
index dc12efc..bbd064a 100644
@@ -1994,16 +1994,33 @@ static bool rcu_cpu_has_nonlazy_callbacks(int cpu)
 }
 
 /*
+ *
+ */
+void rcu_idle_demigrate(void *unused)
+{
+	trace_rcu_prep_idle("Demigrate");
+}
+
+/*
  * Timer handler used to force CPU to start pushing its remaining RCU
  * callbacks in the case where it entered dyntick-idle mode with callbacks
  * pending.  The hander doesn't really need to do anything because the
  * real work is done upon re-entry to idle, or by the next scheduling-clock
  * interrupt should idle not be re-entered.
+ *
+ * One special case: the timer gets migrated without awakening the CPU
+ * on which the timer was scheduled on.  In this case, we must wake up
+ * that CPU.  We do so with smp_call_function_single().
  */
-static void rcu_idle_gp_timer_func(unsigned long unused)
+static void rcu_idle_gp_timer_func(unsigned long cpu_in)
 {
-	WARN_ON_ONCE(1); /* Getting here can hang the system... */
+	int cpu = (int)cpu_in;
+
 	trace_rcu_prep_idle("Timer");
+	if (cpu != smp_processor_id())
+		smp_call_function_single(cpu, rcu_idle_demigrate, NULL, 0);
+	else
+		WARN_ON_ONCE(1); /* Getting here can hang the system... */
 }
 
 /*
@@ -2012,7 +2029,7 @@ static void rcu_idle_gp_timer_func(unsigned long unused)
 static void rcu_prepare_for_idle_init(int cpu)
 {
 	setup_timer(&per_cpu(rcu_idle_gp_timer, cpu),
-		    rcu_idle_gp_timer_func, 0);
+		    rcu_idle_gp_timer_func, cpu);
 }
 
Quoted 9 lines

kernel/rcutree_plugin.h static void rcu_idle_gp_timer_func(unsigned long unused) · line 2035

Quoted 3 lines
kernel/rcutree_plugin.h +0 -0
 /*

Paul, I can't apply your patch on top of master branch; perhaps I need to pull your own git repository ?
Among other things, you have:
static void rcu_idle_gp_timer_func(unsigned long unused)
and I have:
static enum hrtimer_restart rcu_idle_gp_timer_func(struct hrtimer *hrtp)

Here is my RCU_FAST_NO_HZ patch stack on top of v3.4-rc4.

Or you can pull branch fnh.2012.05.01a from:

git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git

Thanx, Paul

------------------------------------------------------------------------

include/trace/events/rcu.h +2 -0
index 3370997..1480900 100644
@@ -292,6 +292,8 @@ TRACE_EVENT(rcu_dyntick,
  *	"More callbacks": Still more callbacks, try again to clear them out.
  *	"Callbacks drained": All callbacks processed, off to dyntick idle!
  *	"Timer": Timer fired to cause CPU to continue processing callbacks.
+ *	"Demigrate": Timer fired on wrong CPU, woke up correct CPU.
+ *	"Cleanup after idle": Idle exited, timer canceled.
  */
 TRACE_EVENT(rcu_prep_idle,
 
kernel/rcutree.c +2 -0
index 1050d6d..403306b 100644
@@ -1829,6 +1829,8 @@ __call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu),
 	rdp->qlen++;
 	if (lazy)
 		rdp->qlen_lazy++;
+	else
+		rcu_idle_count_callbacks_posted();
 
 	if (__is_kfree_rcu_offset((unsigned long)func))
 		trace_rcu_kfree_callback(rsp->name, head, (unsigned long)func,
kernel/rcutree.h +1 -0
index cdd1be0..36ca28e 100644
@@ -471,6 +471,7 @@ static void __cpuinit rcu_prepare_kthreads(int cpu);
 static void rcu_prepare_for_idle_init(int cpu);
 static void rcu_cleanup_after_idle(int cpu);
 static void rcu_prepare_for_idle(int cpu);
+static void rcu_idle_count_callbacks_posted(void);
 static void print_cpu_stall_info_begin(void);
 static void print_cpu_stall_info(struct rcu_state *rsp, int cpu);
 static void print_cpu_stall_info_end(void);
kernel/rcutree_plugin.h +83 -28

183 lines not on this page · raw message

#5 lore raw
Quoted 8 lines · Paul E. McKenney

Here is my RCU_FAST_NO_HZ patch stack on top of v3.4-rc4.

Or you can pull branch fnh.2012.05.01a from:

git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git

Thanx, Paul

I applied your global patch on top of v3.4-rc4. But the slowdown is worse than before : boot sequence took 80s instead 20-30s (12s for initramfs instead of 2s).

I'll send you rcu tracing log in a second mail.

Pascal

#6 lore raw
Quoted 8 lines · Pascal Chapperon
Quoted 6 lines · Paul E. McKenney

Here is my RCU_FAST_NO_HZ patch stack on top of v3.4-rc4.

Or you can pull branch fnh.2012.05.01a from:

git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git

Quoted 7 lines
Quoted 2 lines

Thanx, Paul

I applied your global patch on top of v3.4-rc4. But the slowdown is worse than before : boot sequence took 80s instead 20-30s (12s for initramfs instead of 2s).

I'll send you rcu tracing log in a second mail.

Hmmm... Well, I guess I am glad that I finally did something that had an effect, but I sure wish that the effect had been in the other direction!

Just to make sure I understand: the difference between the 20-30s and the 80s is exactly the patch I sent you?

Thanx, Paul

#7 lore raw
Quoted 17 lines · Paul E. McKenney
Quoted 8 lines · Pascal Chapperon
Quoted 6 lines · Paul E. McKenney

Here is my RCU_FAST_NO_HZ patch stack on top of v3.4-rc4.

Or you can pull branch fnh.2012.05.01a from:

git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git

Quoted 7 lines
Quoted 2 lines

Thanx, Paul

I applied your global patch on top of v3.4-rc4. But the slowdown is worse than before : boot sequence took 80s instead 20-30s (12s for initramfs instead of 2s).

I'll send you rcu tracing log in a second mail.

Quoted 10 lines

Hmmm... Well, I guess I am glad that I finally did something that had an effect, but I sure wish that the effect had been in the other direction!

Just to make sure I understand: the difference between the 20-30s and the 80s is exactly the patch I sent you?

Thanx, Paul

Yes. Exactly same kernel config as in previous results, I applied your patch against v3.4-rc4, and sorry, the result is exactly what I said; I saw that your global patch was quite huge, and addresses things which
are not directly related with the initial patch (commit 7cb92499000e3c86dae653077b1465458a039ef6); maybe a side effect?

However, I'm ready to try this patch on my smaller laptop which supports well CONFIG_FAST_NO_HZ=y and systemd, if you think it can help ?

Another thought: this issue as nothing to do with i7 Hyper-threading capacities ? (as I test core2duo, Pentium ulv in same conditions and I don't encountered any slowdown ?)

Pascal

#8 lore raw
Quoted 35 lines · Pascal Chapperon
Quoted 17 lines · Paul E. McKenney
Quoted 8 lines · Pascal Chapperon
Quoted 6 lines · Paul E. McKenney

Here is my RCU_FAST_NO_HZ patch stack on top of v3.4-rc4.

Or you can pull branch fnh.2012.05.01a from:

git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git

Quoted 7 lines
Quoted 2 lines

Thanx, Paul

I applied your global patch on top of v3.4-rc4. But the slowdown is worse than before : boot sequence took 80s instead 20-30s (12s for initramfs instead of 2s).

I'll send you rcu tracing log in a second mail.

Quoted 10 lines

Hmmm... Well, I guess I am glad that I finally did something that had an effect, but I sure wish that the effect had been in the other direction!

Just to make sure I understand: the difference between the 20-30s and the 80s is exactly the patch I sent you?

Thanx, Paul

Yes. Exactly same kernel config as in previous results, I applied your patch against v3.4-rc4, and sorry, the result is exactly what I said;
I saw that your global patch was quite huge, and addresses things which are not directly related with the initial patch (commit 7cb92499000e3c86dae653077b1465458a039ef6); maybe a side effect?

Quoted 7 lines

However, I'm ready to try this patch on my smaller laptop which supports well CONFIG_FAST_NO_HZ=y and systemd, if you think it can help ?

Another thought: this issue as nothing to do with i7 Hyper-threading capacities ? (as I test core2duo, Pentium ulv in same conditions and I don't encountered any slowdown ?)

Well, one possibility is that your setup starts the jiffies counter at some interesting value. The attached patch (also against v3.4-rc4) applies a bit more paranoia to the initialization to handle this and other possibilities.

Thanx, Paul

------------------------------------------------------------------------

include/trace/events/rcu.h +2 -0
index 3370997..1480900 100644
@@ -292,6 +292,8 @@ TRACE_EVENT(rcu_dyntick,
  *	"More callbacks": Still more callbacks, try again to clear them out.
  *	"Callbacks drained": All callbacks processed, off to dyntick idle!
  *	"Timer": Timer fired to cause CPU to continue processing callbacks.
+ *	"Demigrate": Timer fired on wrong CPU, woke up correct CPU.
+ *	"Cleanup after idle": Idle exited, timer canceled.
  */
 TRACE_EVENT(rcu_prep_idle,
 
kernel/rcutree.c +2 -0
index 1050d6d..403306b 100644
@@ -1829,6 +1829,8 @@ __call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu),
 	rdp->qlen++;
 	if (lazy)
 		rdp->qlen_lazy++;
+	else
+		rcu_idle_count_callbacks_posted();
 
 	if (__is_kfree_rcu_offset((unsigned long)func))
 		trace_rcu_kfree_callback(rsp->name, head, (unsigned long)func,
kernel/rcutree.h +1 -0
index cdd1be0..36ca28e 100644
@@ -471,6 +471,7 @@ static void __cpuinit rcu_prepare_kthreads(int cpu);
 static void rcu_prepare_for_idle_init(int cpu);
 static void rcu_cleanup_after_idle(int cpu);
 static void rcu_prepare_for_idle(int cpu);
+static void rcu_idle_count_callbacks_posted(void);
 static void print_cpu_stall_info_begin(void);
 static void print_cpu_stall_info(struct rcu_state *rsp, int cpu);
 static void print_cpu_stall_info_end(void);
kernel/rcutree_plugin.h +101 -28

203 lines not on this page · raw message

#9 lore raw
Quoted 44 lines · Paul E. McKenney
Quoted 35 lines · Pascal Chapperon
Quoted 17 lines · Paul E. McKenney
Quoted 8 lines · Pascal Chapperon
Quoted 6 lines · Paul E. McKenney

Here is my RCU_FAST_NO_HZ patch stack on top of v3.4-rc4.

Or you can pull branch fnh.2012.05.01a from:

git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git

Quoted 7 lines
Quoted 2 lines

Thanx, Paul

I applied your global patch on top of v3.4-rc4. But the slowdown is worse than before : boot sequence took 80s instead 20-30s (12s for initramfs instead of 2s).

I'll send you rcu tracing log in a second mail.

Quoted 10 lines

Hmmm... Well, I guess I am glad that I finally did something that had an effect, but I sure wish that the effect had been in the other direction!

Just to make sure I understand: the difference between the 20-30s and the 80s is exactly the patch I sent you?

Thanx, Paul

Yes. Exactly same kernel config as in previous results, I applied your patch against v3.4-rc4, and sorry, the result is exactly what I said;
I saw that your global patch was quite huge, and addresses things which are not directly related with the initial patch (commit 7cb92499000e3c86dae653077b1465458a039ef6); maybe a side effect?

Quoted 7 lines

However, I'm ready to try this patch on my smaller laptop which supports well CONFIG_FAST_NO_HZ=y and systemd, if you think it can help ?

Another thought: this issue as nothing to do with i7 Hyper-threading capacities ? (as I test core2duo, Pentium ulv in same conditions and I don't encountered any slowdown ?)

Quoted 8 lines

Well, one possibility is that your setup starts the jiffies counter at some interesting value. The attached patch (also against v3.4-rc4) applies a bit more paranoia to the initialization to handle this and other possibilities.

Thanx, Paul

------------------------------------------------------------------------

I tried your new patch against v3.4-rc5 and saw no improvement :
still 75 s. for the boot sequence.

I'll send you the logs in a second mail.

Pascal

#10 lore raw
In reply to Paul E. McKenney
Quoted 40 lines · Paul E. McKenney
Quoted 39 lines · Pascal Chapperon
Quoted 17 lines · Paul E. McKenney
Quoted 8 lines · Pascal Chapperon
Quoted 6 lines · Paul E. McKenney

Here is my RCU_FAST_NO_HZ patch stack on top of v3.4-rc4.

Or you can pull branch fnh.2012.05.01a from:

git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git

Quoted 7 lines
Quoted 2 lines

Thanx, Paul

I applied your global patch on top of v3.4-rc4. But the slowdown is worse than before : boot sequence took 80s instead 20-30s (12s for initramfs instead of 2s).

I'll send you rcu tracing log in a second mail.

Quoted 10 lines

Hmmm... Well, I guess I am glad that I finally did something that had an effect, but I sure wish that the effect had been in the other direction!

Just to make sure I understand: the difference between the 20-30s and the 80s is exactly the patch I sent you?

Thanx, Paul

Yes. Exactly same kernel config as in previous results, I applied your patch against v3.4-rc4, and sorry, the result is exactly what I said;
I saw that your global patch was quite huge, and addresses things which are not directly related with the initial patch (commit 7cb92499000e3c86dae653077b1465458a039ef6); maybe a side effect?

However, I'm ready to try this patch on my smaller laptop which supports well CONFIG_FAST_NO_HZ=y and systemd, if you think it can help ?

Quoted 8 lines
Quoted 3 lines

Another thought: this issue as nothing to do with i7 Hyper-threading capacities ? (as I test core2duo, Pentium ulv in same conditions and I don't encountered any slowdown ?)

Well, one possibility is that your setup starts the jiffies counter at some interesting value. The attached patch (also against v3.4-rc4) applies a bit more paranoia to the initialization to handle this and other possibilities.

This patchset fixes the problem where RCU_FAST_NO_HZ's timers were being ignored due to the dyntick-idle code having already calculated the CPU's wakeup time (which I sent earlier, mistakenly offlist), but also fixes a botched check in my workaround.

Could you please try it out? This patch is against 3.4-rc4.

Thanx, Paul

------------------------------------------------------------------------

 include/linux/rcutiny.h    |    6 -
 include/linux/rcutree.h    |    2 
 include/trace/events/rcu.h |    3 
 kernel/rcutiny_plugin.h    |    2 
 kernel/rcutree.c           |    6 -
 kernel/rcutree.h           |   15 +++
 kernel/rcutree_plugin.h    |  213 ++++++++++++++++++++++++++++++---------------
 kernel/time/tick-sched.c   |    7 +
 8 files changed, 179 insertions(+), 75 deletions(-)
include/linux/rcutiny.h +4 -2
index e93df77..56048bc 100644
@@ -95,8 +95,9 @@ static inline void exit_rcu(void)
 {
 }
 
-static inline int rcu_needs_cpu(int cpu)
+static inline int rcu_needs_cpu(int cpu, unsigned long *delta_jiffies)
 {
+	*delta_jiffies = ULONG_MAX;
 	return 0;
 }
 
@@ -106,8 +107,9 @@ void rcu_preempt_note_context_switch(void);
 extern void exit_rcu(void);
 int rcu_preempt_needs_cpu(void);
 
-static inline int rcu_needs_cpu(int cpu)
+static inline int rcu_needs_cpu(int cpu, unsigned long *delta_jiffies)
 {
+	*delta_jiffies = ULONG_MAX;
 	return rcu_preempt_needs_cpu();
 }
 
include/linux/rcutree.h +1 -1
index e8ee5dd..06b1939 100644
@@ -32,7 +32,7 @@
 
 extern void rcu_init(void);
 extern void rcu_note_context_switch(int cpu);
-extern int rcu_needs_cpu(int cpu);
+extern int rcu_needs_cpu(int cpu, unsigned long *delta_jiffies);
 extern void rcu_cpu_stall_reset(void);
 
 /*
include/trace/events/rcu.h +3 -0
index 3370997..d274734 100644
@@ -289,9 +289,12 @@ TRACE_EVENT(rcu_dyntick,
  *	"In holdoff": Nothing to do, holding off after unsuccessful attempt.
  *	"Begin holdoff": Attempt failed, don't retry until next jiffy.
  *	"Dyntick with callbacks": Entering dyntick-idle despite callbacks.
+ *	"Dyntick with lazy callbacks": Entering dyntick-idle w/lazy callbacks.
  *	"More callbacks": Still more callbacks, try again to clear them out.
  *	"Callbacks drained": All callbacks processed, off to dyntick idle!
  *	"Timer": Timer fired to cause CPU to continue processing callbacks.
+ *	"Demigrate": Timer fired on wrong CPU, woke up correct CPU.
+ *	"Cleanup after idle": Idle exited, timer canceled.
  */
 TRACE_EVENT(rcu_prep_idle,
 
kernel/rcutiny_plugin.h +0 -2
index 22ecea0..f3b995a 100644
@@ -846,8 +846,6 @@ EXPORT_SYMBOL_GPL(synchronize_rcu_expedited);
  */
 int rcu_preempt_needs_cpu(void)
 {
-	if (!rcu_preempt_running_reader())
-		rcu_preempt_cpu_qs();
 	return rcu_preempt_ctrlblk.rcb.rcucblist != NULL;
 }
 
kernel/rcutree.c +4 -2
index 1050d6d..38300c0 100644
@@ -349,7 +349,7 @@ static void rcu_idle_enter_common(struct rcu_dynticks *rdtp, long long oldval)
 		struct task_struct *idle = idle_task(smp_processor_id());
 
 		trace_rcu_dyntick("Error on entry: not idle task", oldval, 0);
-		ftrace_dump(DUMP_ALL);
+		ftrace_dump(DUMP_ORIG);
 		WARN_ONCE(1, "Current pid: %d comm: %s / Idle pid: %d comm: %s",
 			  current->pid, current->comm,
 			  idle->pid, idle->comm); /* must be idle task! */
@@ -459,7 +459,7 @@ static void rcu_idle_exit_common(struct rcu_dynticks *rdtp, long long oldval)
 
 		trace_rcu_dyntick("Error on exit: not idle task",
 				  oldval, rdtp->dynticks_nesting);
-		ftrace_dump(DUMP_ALL);
+		ftrace_dump(DUMP_ORIG);
 		WARN_ONCE(1, "Current pid: %d comm: %s / Idle pid: %d comm: %s",
 			  current->pid, current->comm,
 			  idle->pid, idle->comm); /* must be idle task! */
@@ -1829,6 +1829,8 @@ __call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu),
 	rdp->qlen++;
 	if (lazy)
 		rdp->qlen_lazy++;
+	else
+		rcu_idle_count_callbacks_posted();
 
 	if (__is_kfree_rcu_offset((unsigned long)func))
 		trace_rcu_kfree_callback(rsp->name, head, (unsigned long)func,
kernel/rcutree.h +15 -0
index cdd1be0..7e914db 100644
@@ -88,6 +88,20 @@ struct rcu_dynticks {
 				    /* Process level is worth LLONG_MAX/2. */
 	int dynticks_nmi_nesting;   /* Track NMI nesting level. */
 	atomic_t dynticks;	    /* Even value for idle, else odd. */
+#ifdef CONFIG_RCU_FAST_NO_HZ
+	int dyntick_drain;	    /* Prepare-for-idle state variable. */
+	unsigned long dyntick_holdoff;
+				    /* No retries for the jiffy of failure. */
+	struct timer_list idle_gp_timer;
+				    /* Wake up CPU sleeping with callbacks. */
+	unsigned long idle_gp_timer_expires;
+				    /* When to wake up CPU (for repost). */
+	bool idle_first_pass;	    /* First pass of attempt to go idle? */
+	unsigned long nonlazy_posted;
+				    /* # times non-lazy CBs posted to CPU. */
+	unsigned long nonlazy_posted_snap;
+				    /* idle-period nonlazy_posted snapshot. */
+#endif /* #ifdef CONFIG_RCU_FAST_NO_HZ */
 };
 
 /* RCU's kthread states for tracing. */
@@ -471,6 +485,7 @@ static void __cpuinit rcu_prepare_kthreads(int cpu);
 static void rcu_prepare_for_idle_init(int cpu);
 static void rcu_cleanup_after_idle(int cpu);
 static void rcu_prepare_for_idle(int cpu);
+static void rcu_idle_count_callbacks_posted(void);
 static void print_cpu_stall_info_begin(void);
 static void print_cpu_stall_info(struct rcu_state *rsp, int cpu);
 static void print_cpu_stall_info_end(void);
kernel/rcutree_plugin.h +146 -67

306 lines not on this page · raw message

kernel/time/tick-sched.c +6 -1
index 6a3a5b9..52f5ebb 100644
@@ -274,6 +274,7 @@ EXPORT_SYMBOL_GPL(get_cpu_iowait_time_us);
 static void tick_nohz_stop_sched_tick(struct tick_sched *ts)
 {
 	unsigned long seq, last_jiffies, next_jiffies, delta_jiffies;
+	unsigned long rcu_delta_jiffies;
 	ktime_t last_update, expires, now;
 	struct clock_event_device *dev = __get_cpu_var(tick_cpu_device).evtdev;
 	u64 time_delta;
@@ -322,7 +323,7 @@ static void tick_nohz_stop_sched_tick(struct tick_sched *ts)
 		time_delta = timekeeping_max_deferment();
 	} while (read_seqretry(&xtime_lock, seq));
 
-	if (rcu_needs_cpu(cpu) || printk_needs_cpu(cpu) ||
+	if (rcu_needs_cpu(cpu, &rcu_delta_jiffies) || printk_needs_cpu(cpu) ||
 	    arch_needs_cpu(cpu)) {
 		next_jiffies = last_jiffies + 1;
 		delta_jiffies = 1;
@@ -330,6 +331,10 @@ static void tick_nohz_stop_sched_tick(struct tick_sched *ts)
 		/* Get the next timer wheel timer */
 		next_jiffies = get_next_timer_interrupt(last_jiffies);
 		delta_jiffies = next_jiffies - last_jiffies;
+		if (rcu_delta_jiffies < delta_jiffies) {
+			next_jiffies = last_jiffies + rcu_delta_jiffies;
+			delta_jiffies = rcu_delta_jiffies;
+		}
 	}
 	/*
 	 * Do not stop the tick, if we are only one off
#11 lore raw
Quoted 50 lines · Paul E. McKenney
Quoted 40 lines · Paul E. McKenney
Quoted 39 lines · Pascal Chapperon
Quoted 17 lines · Paul E. McKenney
Quoted 8 lines · Pascal Chapperon
Quoted 6 lines · Paul E. McKenney

Here is my RCU_FAST_NO_HZ patch stack on top of v3.4-rc4.

Or you can pull branch fnh.2012.05.01a from:

git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git

Quoted 7 lines
Quoted 2 lines

Thanx, Paul

I applied your global patch on top of v3.4-rc4. But the slowdown is worse than before : boot sequence took 80s instead 20-30s (12s for initramfs instead of 2s).

I'll send you rcu tracing log in a second mail.

Quoted 10 lines

Hmmm... Well, I guess I am glad that I finally did something that had an effect, but I sure wish that the effect had been in the other direction!

Just to make sure I understand: the difference between the 20-30s and the 80s is exactly the patch I sent you?

Thanx, Paul

Yes. Exactly same kernel config as in previous results, I applied your patch against v3.4-rc4, and sorry, the result is exactly what I said;
I saw that your global patch was quite huge, and addresses things which are not directly related with the initial patch (commit 7cb92499000e3c86dae653077b1465458a039ef6); maybe a side effect?

However, I'm ready to try this patch on my smaller laptop which supports well CONFIG_FAST_NO_HZ=y and systemd, if you think it can help ?

Quoted 8 lines
Quoted 3 lines

Another thought: this issue as nothing to do with i7 Hyper-threading capacities ? (as I test core2duo, Pentium ulv in same conditions and I don't encountered any slowdown ?)

Well, one possibility is that your setup starts the jiffies counter at some interesting value. The attached patch (also against v3.4-rc4) applies a bit more paranoia to the initialization to handle this and other possibilities.

Quoted 9 lines

This patchset fixes the problem where RCU_FAST_NO_HZ's timers were being ignored due to the dyntick-idle code having already calculated the CPU's wakeup time (which I sent earlier, mistakenly offlist), but also fixes a botched check in my workaround.

Could you please try it out? This patch is against 3.4-rc4.

Thanx, Paul

Hi Paul,

< + if (!rcu_cpu_has_nonlazy_callbacks(cpu))
---

Quoted 1 line

+ if (rcu_cpu_has_nonlazy_callbacks(cpu))

I was a little disappointed by the previous patch (boot sequence still took 72 s.), but this one makes a huge difference ;-) Slowdown during boot or shutdown with CONFIG_RCU_FAST_NO_HZ has disappeared (~ 10 attempts) :

# systemd-analyze
Startup finished in 1990ms (kernel) + 1174ms (initramfs) + 3121ms
(userspace) = 6285ms
.
Do you want the rcu tracing log for this patch ?

Pascal

#12 lore raw
Quoted 66 lines · Pascal Chapperon
Quoted 50 lines · Paul E. McKenney
Quoted 40 lines · Paul E. McKenney
Quoted 39 lines · Pascal Chapperon
Quoted 17 lines · Paul E. McKenney
Quoted 8 lines · Pascal Chapperon
Quoted 6 lines · Paul E. McKenney

Here is my RCU_FAST_NO_HZ patch stack on top of v3.4-rc4.

Or you can pull branch fnh.2012.05.01a from:

git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git

Quoted 7 lines
Quoted 2 lines

Thanx, Paul

I applied your global patch on top of v3.4-rc4. But the slowdown is worse than before : boot sequence took 80s instead 20-30s (12s for initramfs instead of 2s).

I'll send you rcu tracing log in a second mail.

Quoted 10 lines

Hmmm... Well, I guess I am glad that I finally did something that had an effect, but I sure wish that the effect had been in the other direction!

Just to make sure I understand: the difference between the 20-30s and the 80s is exactly the patch I sent you?

Thanx, Paul

Yes. Exactly same kernel config as in previous results, I applied your patch against v3.4-rc4, and sorry, the result is exactly what I said;
I saw that your global patch was quite huge, and addresses things which are not directly related with the initial patch (commit 7cb92499000e3c86dae653077b1465458a039ef6); maybe a side effect?

However, I'm ready to try this patch on my smaller laptop which supports well CONFIG_FAST_NO_HZ=y and systemd, if you think it can help ?

Quoted 8 lines
Quoted 3 lines

Another thought: this issue as nothing to do with i7 Hyper-threading capacities ? (as I test core2duo, Pentium ulv in same conditions and I don't encountered any slowdown ?)

Well, one possibility is that your setup starts the jiffies counter at some interesting value. The attached patch (also against v3.4-rc4) applies a bit more paranoia to the initialization to handle this and other possibilities.

Quoted 9 lines

This patchset fixes the problem where RCU_FAST_NO_HZ's timers were being ignored due to the dyntick-idle code having already calculated the CPU's wakeup time (which I sent earlier, mistakenly offlist), but also fixes a botched check in my workaround.

Could you please try it out? This patch is against 3.4-rc4.

Thanx, Paul

Hi Paul,

< + if (!rcu_cpu_has_nonlazy_callbacks(cpu))
---

Quoted 1 line

+ if (rcu_cpu_has_nonlazy_callbacks(cpu))

Quoted 8 lines

I was a little disappointed by the previous patch (boot sequence still took 72 s.), but this one makes a huge difference ;-) Slowdown during boot or shutdown with CONFIG_RCU_FAST_NO_HZ has disappeared (~ 10 attempts) :

# systemd-analyze
Startup finished in 1990ms (kernel) + 1174ms (initramfs) + 3121ms
(userspace) = 6285ms
.

Very good! And thank you very much for all your testing efforts and for bearing with me through this!

Does this mean that I can add your Tested-by?

Quoted 1 line

Do you want the rcu tracing log for this patch ?

Could you please? Just in case there is some other surprise that I should know about that might not be visible. ;-)

Thanx, Paul

#13 lore raw
Quoted 76 lines · Paul E. McKenney
Quoted 66 lines · Pascal Chapperon
Quoted 50 lines · Paul E. McKenney
Quoted 40 lines · Paul E. McKenney
Quoted 39 lines · Pascal Chapperon
Quoted 17 lines · Paul E. McKenney
Quoted 8 lines · Pascal Chapperon
Quoted 6 lines · Paul E. McKenney

Here is my RCU_FAST_NO_HZ patch stack on top of v3.4-rc4.

Or you can pull branch fnh.2012.05.01a from:

git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git

Quoted 7 lines
Quoted 2 lines

Thanx, Paul

I applied your global patch on top of v3.4-rc4. But the slowdown is worse than before : boot sequence took 80s instead 20-30s (12s for initramfs instead of 2s).

I'll send you rcu tracing log in a second mail.

Quoted 10 lines

Hmmm... Well, I guess I am glad that I finally did something that had an effect, but I sure wish that the effect had been in the other direction!

Just to make sure I understand: the difference between the 20-30s and the 80s is exactly the patch I sent you?

Thanx, Paul

Yes. Exactly same kernel config as in previous results, I applied your patch against v3.4-rc4, and sorry, the result is exactly what I said;
I saw that your global patch was quite huge, and addresses things which are not directly related with the initial patch (commit 7cb92499000e3c86dae653077b1465458a039ef6); maybe a side effect?

However, I'm ready to try this patch on my smaller laptop which supports well CONFIG_FAST_NO_HZ=y and systemd, if you think it can help ?

Quoted 8 lines
Quoted 3 lines

Another thought: this issue as nothing to do with i7 Hyper-threading capacities ? (as I test core2duo, Pentium ulv in same conditions and I don't encountered any slowdown ?)

Well, one possibility is that your setup starts the jiffies counter at some interesting value. The attached patch (also against v3.4-rc4) applies a bit more paranoia to the initialization to handle this and other possibilities.

Quoted 9 lines

This patchset fixes the problem where RCU_FAST_NO_HZ's timers were being ignored due to the dyntick-idle code having already calculated the CPU's wakeup time (which I sent earlier, mistakenly offlist), but also fixes a botched check in my workaround.

Could you please try it out? This patch is against 3.4-rc4.

Thanx, Paul

Hi Paul,

< + if (!rcu_cpu_has_nonlazy_callbacks(cpu))
---

Quoted 1 line

+ if (rcu_cpu_has_nonlazy_callbacks(cpu))

Quoted 8 lines

I was a little disappointed by the previous patch (boot sequence still took 72 s.), but this one makes a huge difference ;-) Slowdown during boot or shutdown with CONFIG_RCU_FAST_NO_HZ has disappeared (~ 10 attempts) :

# systemd-analyze
Startup finished in 1990ms (kernel) + 1174ms (initramfs) + 3121ms
(userspace) = 6285ms
.
Quoted 4 lines

Very good! And thank you very much for all your testing efforts and for bearing with me through this!

Does this mean that I can add your Tested-by?

Yes: the results are good and stable, at least for my hardware. I tried with both a standard fedora 16 kernel configuration and a custom one (hardware optimized, preempted, etc...) and this on over more 20 attempts.
With or without FAST_NO_HZ makes no difference now.

Quoted 7 lines
Quoted 2 lines

Do you want the rcu tracing log for this patch ?

Could you please? Just in case there is some other surprise that I should know about that might not be visible. ;-)

Thanx, Paul

I'll send you the logs in a second mail (offlist).

Pascal