Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=7507ba34e827ca3c6bbcd34d20a8df8ba365fca6
Commit:     7507ba34e827ca3c6bbcd34d20a8df8ba365fca6
Parent:     0dc952dc3e6d96d554a19fa7bee3f3b1d55e3cff
Author:     Zachary Amsden <[EMAIL PROTECTED]>
AuthorDate: Mon Mar 5 00:30:34 2007 -0800
Committer:  Linus Torvalds <[EMAIL PROTECTED]>
CommitDate: Mon Mar 5 07:57:52 2007 -0800

    [PATCH] vmi: timer fixes round two
    
    Critical bugfixes for the VMI-Timer code.
    
    1) Do not setup a one shot alarm if we are keeping the periodic alarm
       armed.  Additionally, since the periodic alarm can be run at a lower rate
       than HZ, let's fixup the guard to the no-idle-hz mode appropriately.  
This
       fixes the bug where the no-idle-hz mode might have a higher interrupt 
rate
       than the non-idle case.
    
    2) The interrupt handler can no longer adjust xtime due to nested lock
       acquisition.  Drop this.  We don't need to check for wallclock time at
       every tick, it can be done in userspace instead.
    
    3) Add a bypass to disable noidle operation.  This is useful as a last
       minute workaround, or testing measure.
    
    4) The code to skip the IO_APIC timer testing (no_timer_check) should be
       conditional on IO_APIC, not SMP, since UP kernels can have this 
configured
       in as well.
    
    Signed-off-by: Dan Hecht <[EMAIL PROTECTED]>
    Signed-off-by: Zachary Amsden <[EMAIL PROTECTED]>
    Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
    Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>
---
 arch/i386/kernel/vmi.c     |   23 +++++++++++++----------
 arch/i386/kernel/vmitime.c |   30 +++++++++++-------------------
 2 files changed, 24 insertions(+), 29 deletions(-)

diff --git a/arch/i386/kernel/vmi.c b/arch/i386/kernel/vmi.c
index bb5a7ab..8417f74 100644
--- a/arch/i386/kernel/vmi.c
+++ b/arch/i386/kernel/vmi.c
@@ -54,6 +54,7 @@ static int disable_pse;
 static int disable_sep;
 static int disable_tsc;
 static int disable_mtrr;
+static int disable_noidle;
 
 /* Cached VMI operations */
 struct {
@@ -255,7 +256,6 @@ static void vmi_nop(void)
 }
 
 /* For NO_IDLE_HZ, we stop the clock when halting the kernel */
-#ifdef CONFIG_NO_IDLE_HZ
 static fastcall void vmi_safe_halt(void)
 {
        int idle = vmi_stop_hz_timer();
@@ -266,7 +266,6 @@ static fastcall void vmi_safe_halt(void)
                local_irq_enable();
        }
 }
-#endif
 
 #ifdef CONFIG_DEBUG_PAGE_TYPE
 
@@ -742,12 +741,7 @@ static inline int __init activate_vmi(void)
                     (char *)paravirt_ops.save_fl);
        patch_offset(&irq_save_disable_callout[IRQ_PATCH_DISABLE],
                     (char *)paravirt_ops.irq_disable);
-#ifndef CONFIG_NO_IDLE_HZ
-       para_fill(safe_halt, Halt);
-#else
-       vmi_ops.halt = vmi_get_function(VMI_CALL_Halt);
-       paravirt_ops.safe_halt = vmi_safe_halt;
-#endif
+
        para_fill(wbinvd, WBINVD);
        /* paravirt_ops.read_msr = vmi_rdmsr */
        /* paravirt_ops.write_msr = vmi_wrmsr */
@@ -881,6 +875,12 @@ static inline int __init activate_vmi(void)
 #endif
                custom_sched_clock = vmi_sched_clock;
        }
+       if (!disable_noidle)
+               para_fill(safe_halt, Halt);
+       else {
+               vmi_ops.halt = vmi_get_function(VMI_CALL_Halt);
+               paravirt_ops.safe_halt = vmi_safe_halt;
+       }
 
        /*
         * Alternative instruction rewriting doesn't happen soon enough
@@ -914,9 +914,11 @@ void __init vmi_init(void)
 
        local_irq_save(flags);
        activate_vmi();
-#ifdef CONFIG_SMP
+
+#ifdef CONFIG_X86_IO_APIC
        no_timer_check = 1;
 #endif
+
        local_irq_restore(flags & X86_EFLAGS_IF);
 }
 
@@ -942,7 +944,8 @@ static int __init parse_vmi(char *arg)
        } else if (!strcmp(arg, "disable_mtrr")) {
                clear_bit(X86_FEATURE_MTRR, boot_cpu_data.x86_capability);
                disable_mtrr = 1;
-       }
+       } else if (!strcmp(arg, "disable_noidle"))
+               disable_noidle = 1;
        return 0;
 }
 
diff --git a/arch/i386/kernel/vmitime.c b/arch/i386/kernel/vmitime.c
index 76d2adc..694aa85 100644
--- a/arch/i386/kernel/vmitime.c
+++ b/arch/i386/kernel/vmitime.c
@@ -276,16 +276,13 @@ static void vmi_account_real_cycles(unsigned long long 
cur_real_cycles)
 
        cycles_not_accounted = cur_real_cycles - real_cycles_accounted_system;
        while (cycles_not_accounted >= cycles_per_jiffy) {
-               /* systems wide jiffies and wallclock. */
+               /* systems wide jiffies. */
                do_timer(1);
 
                cycles_not_accounted -= cycles_per_jiffy;
                real_cycles_accounted_system += cycles_per_jiffy;
        }
 
-       if (vmi_timer_ops.wallclock_updated())
-               update_xtime_from_wallclock();
-
        write_sequnlock(&xtime_lock);
 }
 
@@ -380,7 +377,6 @@ int vmi_stop_hz_timer(void)
        unsigned long seq, next;
        unsigned long long real_cycles_expiry;
        int cpu = smp_processor_id();
-       int idle;
 
        BUG_ON(!irqs_disabled());
        if (sysctl_hz_timer != 0)
@@ -388,13 +384,13 @@ int vmi_stop_hz_timer(void)
 
        cpu_set(cpu, nohz_cpu_mask);
        smp_mb();
+
        if (rcu_needs_cpu(cpu) || local_softirq_pending() ||
-           (next = next_timer_interrupt(), time_before_eq(next, jiffies))) {
+           (next = next_timer_interrupt(),
+            time_before_eq(next, jiffies + HZ/CONFIG_VMI_ALARM_HZ))) {
                cpu_clear(cpu, nohz_cpu_mask);
-               next = jiffies;
-               idle = 0;
-       } else
-               idle = 1;
+               return 0;
+       }
 
        /* Convert jiffies to the real cycle counter. */
        do {
@@ -404,17 +400,13 @@ int vmi_stop_hz_timer(void)
        } while (read_seqretry(&xtime_lock, seq));
 
        /* This cpu is going idle. Disable the periodic alarm. */
-       if (idle) {
-               vmi_timer_ops.cancel_alarm(VMI_CYCLES_AVAILABLE);
-               per_cpu(idle_start_jiffies, cpu) = jiffies;
-       }
-
+       vmi_timer_ops.cancel_alarm(VMI_CYCLES_AVAILABLE);
+       per_cpu(idle_start_jiffies, cpu) = jiffies;
        /* Set the real time alarm to expire at the next event. */
        vmi_timer_ops.set_alarm(
-                     VMI_ALARM_WIRING | VMI_ALARM_IS_ONESHOT | VMI_CYCLES_REAL,
-                     real_cycles_expiry, 0);
-
-       return idle;
+               VMI_ALARM_WIRING | VMI_ALARM_IS_ONESHOT | VMI_CYCLES_REAL,
+               real_cycles_expiry, 0);
+       return 1;
 }
 
 static void vmi_reenable_hz_timer(int cpu)
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to