On Wed, Aug 31, 2005 at 10:28:43PM +0530, Srivatsa Vaddagiri wrote:
> Following patches related to dynamic tick are posted in separate mails,
> for convenience of review. The first patch probably applies w/o dynamic
> tick consideration also.
> 
> Patch 3/3  -> Use lost tick information in dyn-tick time recovery 

This patch uses the lost tick information returned by mark_offset()
function in dyn-tick, to recover time.


---

 arch/i386/Kconfig                                                 |    0 
 linux-2.6.13-rc6-mm2-root/arch/i386/kernel/dyn-tick.c             |   11 
++++++--
 linux-2.6.13-rc6-mm2-root/arch/i386/kernel/time.c                 |   13 
++++++----
 linux-2.6.13-rc6-mm2-root/arch/i386/kernel/timers/timer_cyclone.c |    4 ++-
 linux-2.6.13-rc6-mm2-root/arch/i386/kernel/timers/timer_hpet.c    |    4 ++-
 linux-2.6.13-rc6-mm2-root/arch/i386/kernel/timers/timer_none.c    |    3 +-
 linux-2.6.13-rc6-mm2-root/arch/i386/kernel/timers/timer_pit.c     |    3 +-
 linux-2.6.13-rc6-mm2-root/arch/i386/kernel/timers/timer_pm.c      |    6 +++-
 linux-2.6.13-rc6-mm2-root/arch/i386/kernel/timers/timer_tsc.c     |   12 
++++++---
 linux-2.6.13-rc6-mm2-root/include/asm-i386/timer.h                |    2 -
 10 files changed, 40 insertions(+), 18 deletions(-)

diff -puN include/asm-i386/timer.h~drift_fix include/asm-i386/timer.h
--- linux-2.6.13-rc6-mm2/include/asm-i386/timer.h~drift_fix     2005-08-31 
16:36:17.000000000 +0530
+++ linux-2.6.13-rc6-mm2-root/include/asm-i386/timer.h  2005-08-31 
16:36:30.000000000 +0530
@@ -19,7 +19,7 @@
  */
 struct timer_opts {
        char* name;
-       void (*mark_offset)(void);
+       int (*mark_offset)(void);
        unsigned long (*get_offset)(void);
        unsigned long long (*monotonic_clock)(void);
        void (*delay)(unsigned long);
diff -puN arch/i386/kernel/time.c~drift_fix arch/i386/kernel/time.c
--- linux-2.6.13-rc6-mm2/arch/i386/kernel/time.c~drift_fix      2005-08-31 
16:36:17.000000000 +0530
+++ linux-2.6.13-rc6-mm2-root/arch/i386/kernel/time.c   2005-08-31 
16:36:30.000000000 +0530
@@ -253,7 +253,7 @@ EXPORT_SYMBOL(profile_pc);
  * timer_interrupt() needs to keep up the real-time clock,
  * as well as call the "do_timer()" routine every clocktick
  */
-static inline void do_timer_interrupt(int irq, struct pt_regs *regs)
+static inline void do_timer_interrupt(int irq, struct pt_regs *regs, int lost)
 {
 #ifdef CONFIG_X86_IO_APIC
        if (timer_ack) {
@@ -271,7 +271,8 @@ static inline void do_timer_interrupt(in
        }
 #endif
 
-       do_timer_interrupt_hook(regs);
+       if (!dyn_tick_enabled() || lost)
+               do_timer_interrupt_hook(regs);
 
 
        if (MCA_bus) {
@@ -296,6 +297,8 @@ static inline void do_timer_interrupt(in
  */
 irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
+       int lost;
+
        /*
         * Here we are in the timer irq handler. We just have irqs locally
         * disabled but we don't know if the timer_bh is running on the other
@@ -305,9 +308,9 @@ irqreturn_t timer_interrupt(int irq, voi
         */
        write_seqlock(&xtime_lock);
 
-       cur_timer->mark_offset();
- 
-       do_timer_interrupt(irq, regs);
+       lost = cur_timer->mark_offset();
+
+       do_timer_interrupt(irq, regs, lost);
 
        write_sequnlock(&xtime_lock);
        return IRQ_HANDLED;
diff -puN arch/i386/kernel/dyn-tick.c~drift_fix arch/i386/kernel/dyn-tick.c
--- linux-2.6.13-rc6-mm2/arch/i386/kernel/dyn-tick.c~drift_fix  2005-08-31 
16:36:17.000000000 +0530
+++ linux-2.6.13-rc6-mm2-root/arch/i386/kernel/dyn-tick.c       2005-08-31 
16:36:30.000000000 +0530
@@ -92,7 +92,13 @@ void dyn_tick_interrupt(int irq, struct 
 
        if (all_were_sleeping) {
                /* Recover jiffies */
-               cur_timer->mark_offset();
+               if (irq) {
+                       int lost;
+
+                       lost = cur_timer->mark_offset();
+                       if (lost)
+                               do_timer(regs);
+               }
                if (cpu_has_local_apic())
                        enable_pit_timer();
        }
@@ -116,8 +122,7 @@ void dyn_tick_time_init(struct timer_opt
 {
        spin_lock_init(&dyn_tick_lock);
 
-       if (strncmp(cur_timer->name, "tsc", 3) == 0 ||
-           strncmp(cur_timer->name, "pmtmr", 3) == 0) {
+       if (strncmp(cur_timer->name, "pmtmr", 3) == 0) {
                dyn_tick->state |= DYN_TICK_SUITABLE;
                printk(KERN_INFO "dyn-tick: Found suitable timer: %s\n",
                       cur_timer->name);
diff -puN arch/i386/kernel/timers/timer_cyclone.c~drift_fix 
arch/i386/kernel/timers/timer_cyclone.c
--- linux-2.6.13-rc6-mm2/arch/i386/kernel/timers/timer_cyclone.c~drift_fix      
2005-08-31 16:36:17.000000000 +0530
+++ linux-2.6.13-rc6-mm2-root/arch/i386/kernel/timers/timer_cyclone.c   
2005-08-31 16:36:30.000000000 +0530
@@ -45,7 +45,7 @@ static seqlock_t monotonic_lock = SEQLOC
        } while (high != cyclone_timer[1]);
 
 
-static void mark_offset_cyclone(void)
+static int mark_offset_cyclone(void)
 {
        unsigned long lost, delay;
        unsigned long delta = last_cyclone_low;
@@ -101,6 +101,8 @@ static void mark_offset_cyclone(void)
         */
        if (lost && abs(delay - delay_at_last_interrupt) > (900000/HZ))
                jiffies_64++;
+
+       return 1;
 }
 
 static unsigned long get_offset_cyclone(void)
diff -puN arch/i386/kernel/timers/timer_hpet.c~drift_fix 
arch/i386/kernel/timers/timer_hpet.c
--- linux-2.6.13-rc6-mm2/arch/i386/kernel/timers/timer_hpet.c~drift_fix 
2005-08-31 16:36:17.000000000 +0530
+++ linux-2.6.13-rc6-mm2-root/arch/i386/kernel/timers/timer_hpet.c      
2005-08-31 16:36:30.000000000 +0530
@@ -96,7 +96,7 @@ static unsigned long get_offset_hpet(voi
        return edx;
 }
 
-static void mark_offset_hpet(void)
+static int mark_offset_hpet(void)
 {
        unsigned long long this_offset, last_offset;
        unsigned long offset;
@@ -119,6 +119,8 @@ static void mark_offset_hpet(void)
        this_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low;
        monotonic_base += cycles_2_ns(this_offset - last_offset);
        write_sequnlock(&monotonic_lock);
+
+       return 1;
 }
 
 static void delay_hpet(unsigned long loops)
diff -puN arch/i386/kernel/timers/timer_none.c~drift_fix 
arch/i386/kernel/timers/timer_none.c
--- linux-2.6.13-rc6-mm2/arch/i386/kernel/timers/timer_none.c~drift_fix 
2005-08-31 16:36:17.000000000 +0530
+++ linux-2.6.13-rc6-mm2-root/arch/i386/kernel/timers/timer_none.c      
2005-08-31 16:36:30.000000000 +0530
@@ -1,9 +1,10 @@
 #include <linux/init.h>
 #include <asm/timer.h>
 
-static void mark_offset_none(void)
+static int mark_offset_none(void)
 {
        /* nothing needed */
+       return 1;
 }
 
 static unsigned long get_offset_none(void)
diff -puN arch/i386/kernel/timers/timer_pit.c~drift_fix 
arch/i386/kernel/timers/timer_pit.c
--- linux-2.6.13-rc6-mm2/arch/i386/kernel/timers/timer_pit.c~drift_fix  
2005-08-31 16:36:17.000000000 +0530
+++ linux-2.6.13-rc6-mm2-root/arch/i386/kernel/timers/timer_pit.c       
2005-08-31 16:36:30.000000000 +0530
@@ -32,9 +32,10 @@ static int __init init_pit(char* overrid
        return 0;
 }
 
-static void mark_offset_pit(void)
+static int mark_offset_pit(void)
 {
        /* nothing needed */
+       return 1;
 }
 
 static unsigned long long monotonic_clock_pit(void)
diff -puN arch/i386/kernel/timers/timer_pm.c~drift_fix 
arch/i386/kernel/timers/timer_pm.c
--- linux-2.6.13-rc6-mm2/arch/i386/kernel/timers/timer_pm.c~drift_fix   
2005-08-31 16:36:17.000000000 +0530
+++ linux-2.6.13-rc6-mm2-root/arch/i386/kernel/timers/timer_pm.c        
2005-08-31 16:36:30.000000000 +0530
@@ -135,7 +135,7 @@ pm_good:
        setup_pit_timer();
 
        init_cpu_khz();
-       set_dyn_tick_max_skip( (0xFFFFFF / (286 * 1000000)) * 1024 * HZ );
+       set_dyn_tick_max_skip(((0xFFFFFF / 1000000) * 286 * HZ) >> 10);
        return 0;
 }
 
@@ -156,7 +156,7 @@ static inline u32 cyc2us(u32 cycles)
  * this gets called during each timer interrupt
  *   - Called while holding the writer xtime_lock
  */
-static void mark_offset_pmtmr(void)
+static int mark_offset_pmtmr(void)
 {
        u32 lost, delta, deltaus, offset_now;
 
@@ -182,6 +182,8 @@ static void mark_offset_pmtmr(void)
        /* compensate for lost ticks */
        if (lost >= 2)
                jiffies_64 += lost - 1;
+
+       return lost;
 }
 
 static int pmtmr_resume(void)
diff -puN arch/i386/kernel/timers/timer_tsc.c~drift_fix 
arch/i386/kernel/timers/timer_tsc.c
--- linux-2.6.13-rc6-mm2/arch/i386/kernel/timers/timer_tsc.c~drift_fix  
2005-08-31 16:36:17.000000000 +0530
+++ linux-2.6.13-rc6-mm2-root/arch/i386/kernel/timers/timer_tsc.c       
2005-08-31 16:36:30.000000000 +0530
@@ -177,7 +177,7 @@ static inline void update_monotonic_base
 }
 
 #ifdef CONFIG_HPET_TIMER
-static void mark_offset_tsc_hpet(void)
+static int mark_offset_tsc_hpet(void)
 {
        unsigned long long last_offset;
        unsigned long offset, temp, hpet_current;
@@ -221,6 +221,8 @@ static void mark_offset_tsc_hpet(void)
        delay_at_last_interrupt = hpet_current - offset;
        ASM_MUL64_REG(temp, delay_at_last_interrupt,
                        hpet_usec_quotient, delay_at_last_interrupt);
+
+       return 1;
 }
 #endif
 
@@ -347,7 +349,7 @@ int recalibrate_cpu_khz(void)
 }
 EXPORT_SYMBOL(recalibrate_cpu_khz);
 
-static void mark_offset_tsc(void)
+static int mark_offset_tsc(void)
 {
        unsigned long lost,delay;
        unsigned long delta = last_tsc_low;
@@ -456,8 +458,12 @@ static void mark_offset_tsc(void)
         * between tsc and pit reads (as noted when
         * usec delta is > 90% # of usecs/tick)
         */
-       if (lost && abs(delay - delay_at_last_interrupt) > (900000/HZ))
+       if (lost && abs(delay - delay_at_last_interrupt) > (900000/HZ)) {
                jiffies_64++;
+               lost++;
+       }
+
+       return 1;
 }
 
 static int __init init_tsc(char* override)
diff -puN arch/i386/Kconfig~drift_fix arch/i386/Kconfig

_



-- 


Thanks and Regards,
Srivatsa Vaddagiri,
Linux Technology Center,
IBM Software Labs,
Bangalore, INDIA - 560017
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to