WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] Fix Xen idle loop to enter/exit tickless mode in same wa

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] Fix Xen idle loop to enter/exit tickless mode in same way as s390,
From: BitKeeper Bot <riel@xxxxxxxxxxx>
Date: Mon, 30 May 2005 10:18:30 +0000
Delivery-date: Mon, 30 May 2005 11:02:46 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: Xen Development List <xen-devel@xxxxxxxxxxxxxxxxxxx>
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
ChangeSet 1.1159.258.154, 2005/05/30 11:18:30+01:00, kaf24@xxxxxxxxxxxxxxxxxxxx

        Fix Xen idle loop to enter/exit tickless mode in same way as s390,
        which interfaces properly with the RCU subsystem.
        
        This includes a patch that fixes a race in the generic RCU code: it
        was created by IBM for s390, and is being pushed upstream by them.
        
        Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>



 linux-2.6.11-xen-sparse/arch/xen/i386/kernel/process.c |   17 +-----
 linux-2.6.11-xen-sparse/arch/xen/i386/kernel/time.c    |   43 +++++++----------
 patches/linux-2.6.11/rcu-nohz.patch                    |   11 ++++
 3 files changed, 35 insertions(+), 36 deletions(-)


diff -Nru a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/process.c 
b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/process.c
--- a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/process.c    2005-05-30 
07:03:30 -04:00
+++ b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/process.c    2005-05-30 
07:03:30 -04:00
@@ -91,25 +91,18 @@
 EXPORT_SYMBOL(enable_hlt);
 
 /* XXX XEN doesn't use default_idle(), poll_idle(). Use xen_idle() instead. */
-extern int set_timeout_timer(void);
+extern void stop_hz_timer(void);
+extern void start_hz_timer(void);
 void xen_idle(void)
 {
-       int cpu;
-
        local_irq_disable();
 
-       cpu = smp_processor_id();
-       if (rcu_pending(cpu))
-               rcu_check_callbacks(cpu, 0);
-
        if (need_resched()) {
                local_irq_enable();
-       } else if (set_timeout_timer() == 0) {
-               /* NB. Blocking reenable events in a race-free manner. */
-               HYPERVISOR_block();
        } else {
-               local_irq_enable();
-               HYPERVISOR_yield();
+               stop_hz_timer();
+               HYPERVISOR_block(); /* implicit local_irq_enable() */
+               start_hz_timer();
        }
 }
 
diff -Nru a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/time.c 
b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/time.c
--- a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/time.c       2005-05-30 
07:03:30 -04:00
+++ b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/time.c       2005-05-30 
07:03:30 -04:00
@@ -665,36 +665,31 @@
 }
 
 /*
- * This function works out when the the next timer function has to be
- * executed (by looking at the timer list) and sets the Xen one-shot
- * domain timer to the appropriate value. This is typically called in
- * cpu_idle() before the domain blocks.
- * 
- * The function returns a non-0 value on error conditions.
- * 
- * It must be called with interrupts disabled.
+ * stop_hz_timer / start_hz_timer - enter/exit 'tickless mode' on an idle cpu
+ * These functions are based on implementations from arch/s390/kernel/time.c
  */
-int set_timeout_timer(void)
+void stop_hz_timer(void)
 {
-       u64 alarm = 0;
-       int ret = 0;
+       unsigned int cpu = smp_processor_id();
        unsigned long j;
 
-       /*
-        * This is safe against long blocking (since calculations are
-        * not based on TSC deltas). It is also safe against warped
-        * system time since suspend-resume is cooperative and we
-        * would first get locked out. It is safe against normal
-        * updates of jiffies since interrupts are off.
-        */
-       j = next_timer_interrupt();
-       alarm = __jiffies_to_st(j);
+       /* s390 does this /before/ checking rcu_pending(). We copy them. */
+       cpu_set(cpu, nohz_cpu_mask);
 
-       /* Failure is pretty bad, but we'd best soldier on. */
-       if ( HYPERVISOR_set_timer_op(alarm) != 0 )
-               ret = -1;
+       /* Leave ourselves in 'tick mode' if rcu or softirq pending. */
+       if (rcu_pending(cpu) || local_softirq_pending()) {
+               cpu_clear(cpu, nohz_cpu_mask);
+               j = jiffies + 1;
+       } else {
+               j = next_timer_interrupt();
+       }
 
-       return ret;
+       BUG_ON(HYPERVISOR_set_timer_op(__jiffies_to_st(j)) != 0);
+}
+
+void start_hz_timer(void)
+{
+       cpu_clear(smp_processor_id(), nohz_cpu_mask);
 }
 
 void time_suspend(void)
diff -Nru a/patches/linux-2.6.11/rcu-nohz.patch 
b/patches/linux-2.6.11/rcu-nohz.patch
--- /dev/null   Wed Dec 31 16:00:00 196900
+++ b/patches/linux-2.6.11/rcu-nohz.patch       2005-05-30 07:03:30 -04:00
@@ -0,0 +1,16 @@
+diff -ur linux-2.6.11/kernel/rcupdate.c linux-2.6.11-rcu/kernel/rcupdate.c
+--- linux-2.6.11/kernel/rcupdate.c     2005-05-30 10:51:41 +01:00
++++ linux-2.6.11-rcu/kernel/rcupdate.c 2005-05-30 10:53:53 +01:00
+@@ -202,8 +202,11 @@
+  */
+ static void cpu_quiet(int cpu, struct rcu_ctrlblk *rcp, struct rcu_state *rsp)
+ {
++      cpumask_t mask;
++
+       cpu_clear(cpu, rsp->cpumask);
+-      if (cpus_empty(rsp->cpumask)) {
++      cpus_andnot(mask, rsp->cpumask, nohz_cpu_mask);
++      if (cpus_empty(mask)) {
+               /* batch completed ! */
+               rcp->completed = rcp->cur;
+               rcu_start_batch(rcp, rsp, 0);

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>