X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fs390%2Fkernel%2Ftime.c;h=995e2cd38e773f725d65ddffe1bbd5c56620cff8;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=8f279421646f6da5809c9e7fd6b32c076b6e4551;hpb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;p=linux-2.6.git diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index 8f2794216..995e2cd38 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c @@ -150,28 +150,6 @@ int do_settimeofday(struct timespec *tv) EXPORT_SYMBOL(do_settimeofday); -#ifndef CONFIG_ARCH_S390X - -static inline __u32 -__calculate_ticks(__u64 elapsed) -{ - register_pair rp; - - rp.pair = elapsed >> 1; - asm ("dr %0,%1" : "+d" (rp) : "d" (CLK_TICKS_PER_JIFFY >> 1)); - return rp.subreg.odd; -} - -#else /* CONFIG_ARCH_S390X */ - -static inline __u32 -__calculate_ticks(__u64 elapsed) -{ - return elapsed / CLK_TICKS_PER_JIFFY; -} - -#endif /* CONFIG_ARCH_S390X */ - #ifdef CONFIG_PROFILING #define s390_do_profile(regs) profile_tick(CPU_PROFILING, regs) @@ -187,14 +165,14 @@ __calculate_ticks(__u64 elapsed) void account_ticks(struct pt_regs *regs) { __u64 tmp; - __u32 ticks; + __u32 ticks, xticks; /* Calculate how many ticks have passed. */ if (S390_lowcore.int_clock < S390_lowcore.jiffy_timer) return; tmp = S390_lowcore.int_clock - S390_lowcore.jiffy_timer; if (tmp >= 2*CLK_TICKS_PER_JIFFY) { /* more than two ticks ? */ - ticks = __calculate_ticks(tmp) + 1; + ticks = __div(tmp, CLK_TICKS_PER_JIFFY) + 1; S390_lowcore.jiffy_timer += CLK_TICKS_PER_JIFFY * (__u64) ticks; } else if (tmp >= CLK_TICKS_PER_JIFFY) { @@ -216,11 +194,9 @@ void account_ticks(struct pt_regs *regs) */ write_seqlock(&xtime_lock); if (S390_lowcore.jiffy_timer > xtime_cc) { - __u32 xticks; - tmp = S390_lowcore.jiffy_timer - xtime_cc; if (tmp >= 2*CLK_TICKS_PER_JIFFY) { - xticks = __calculate_ticks(tmp); + xticks = __div(tmp, CLK_TICKS_PER_JIFFY); xtime_cc += (__u64) xticks * CLK_TICKS_PER_JIFFY; } else { xticks = 1; @@ -230,12 +206,18 @@ void account_ticks(struct pt_regs *regs) do_timer(regs); } write_sequnlock(&xtime_lock); - while (ticks--) - update_process_times(user_mode(regs)); #else - while (ticks--) + for (xticks = ticks; xticks > 0; xticks--) do_timer(regs); #endif + +#ifdef CONFIG_VIRT_CPU_ACCOUNTING + account_user_vtime(current); +#else + while (ticks--) + update_process_times(user_mode(regs)); +#endif + s390_do_profile(regs); } @@ -258,18 +240,21 @@ static inline void stop_hz_timer(void) if (sysctl_hz_timer != 0) return; + cpu_set(smp_processor_id(), nohz_cpu_mask); + /* * Leave the clock comparator set up for the next timer * tick if either rcu or a softirq is pending. */ - if (rcu_pending(smp_processor_id()) || local_softirq_pending()) + if (rcu_pending(smp_processor_id()) || local_softirq_pending()) { + cpu_clear(smp_processor_id(), nohz_cpu_mask); return; + } /* * This cpu is going really idle. Set up the clock comparator * for the next event. */ - cpu_set(smp_processor_id(), nohz_cpu_mask); timer = (__u64) (next_timer_interrupt() - jiffies) + jiffies_64; timer = jiffies_timer_cc + timer * CLK_TICKS_PER_JIFFY; asm volatile ("SCKC %0" : : "m" (timer));