[patch 2/12] s390: idle timer setup.
From: Martin Schwidefsky <[email protected]>
Fix overflow in calculation of the new tod value in stop_hz_timer
and fix wrong virtual timer list idle time in case the virtual
timer is already expired in stop_cpu_timer.
Signed-off-by: Martin Schwidefsky <[email protected]>
diffstat:
arch/s390/kernel/time.c | 12 +++++++++---
arch/s390/kernel/vtime.c | 25 +++++++++++++------------
2 files changed, 22 insertions(+), 15 deletions(-)
diff -urpN linux-2.6/arch/s390/kernel/time.c linux-2.6-patched/arch/s390/kernel/time.c
--- linux-2.6/arch/s390/kernel/time.c 2005-04-22 15:44:44.000000000 +0200
+++ linux-2.6-patched/arch/s390/kernel/time.c 2005-04-22 15:45:00.000000000 +0200
@@ -244,7 +244,7 @@ int sysctl_hz_timer = 1;
*/
static inline void stop_hz_timer(void)
{
- __u64 timer;
+ __u64 timer, todval;
if (sysctl_hz_timer != 0)
return;
@@ -265,8 +265,14 @@ static inline void stop_hz_timer(void)
* for the next event.
*/
timer = (__u64) (next_timer_interrupt() - jiffies) + jiffies_64;
- timer = jiffies_timer_cc + timer * CLK_TICKS_PER_JIFFY;
- asm volatile ("SCKC %0" : : "m" (timer));
+ todval = -1ULL;
+ /* Be careful about overflows. */
+ if (timer < (-1ULL / CLK_TICKS_PER_JIFFY)) {
+ timer = jiffies_timer_cc + timer * CLK_TICKS_PER_JIFFY;
+ if (timer >= jiffies_timer_cc)
+ todval = timer;
+ }
+ asm volatile ("SCKC %0" : : "m" (todval));
}
/*
diff -urpN linux-2.6/arch/s390/kernel/vtime.c linux-2.6-patched/arch/s390/kernel/vtime.c
--- linux-2.6/arch/s390/kernel/vtime.c 2005-04-22 15:44:44.000000000 +0200
+++ linux-2.6-patched/arch/s390/kernel/vtime.c 2005-04-22 15:45:00.000000000 +0200
@@ -122,12 +122,17 @@ static void start_cpu_timer(void)
struct vtimer_queue *vt_list;
vt_list = &per_cpu(virt_cpu_timer, smp_processor_id());
- set_vtimer(vt_list->idle);
+
+ /* CPU timer interrupt is pending, don't reprogramm it */
+ if (vt_list->idle & 1LL<<63)
+ return;
+
+ if (!list_empty(&vt_list->list))
+ set_vtimer(vt_list->idle);
}
static void stop_cpu_timer(void)
{
- __u64 done;
struct vtimer_queue *vt_list;
vt_list = &per_cpu(virt_cpu_timer, smp_processor_id());
@@ -138,21 +143,17 @@ static void stop_cpu_timer(void)
goto fire;
}
- /* store progress */
- asm volatile ("STPT %0" : "=m" (done));
+ /* store the actual expire value */
+ asm volatile ("STPT %0" : "=m" (vt_list->idle));
/*
- * If done is negative we do not stop the CPU timer
- * because we will get instantly an interrupt that
- * will start the CPU timer again.
+ * If the CPU timer is negative we don't reprogramm
+ * it because we will get instantly an interrupt.
*/
- if (done & 1LL<<63)
+ if (vt_list->idle & 1LL<<63)
return;
- else
- vt_list->offset += vt_list->to_expire - done;
- /* save the actual expire value */
- vt_list->idle = done;
+ vt_list->offset += vt_list->to_expire - vt_list->idle;
/*
* We cannot halt the CPU timer, we just write a value that
-
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/
[Index of Archives]
[Kernel Newbies]
[Netfilter]
[Bugtraq]
[Photo]
[Stuff]
[Gimp]
[Yosemite News]
[MIPS Linux]
[ARM Linux]
[Linux Security]
[Linux RAID]
[Video 4 Linux]
[Linux for the blind]
[Linux Resources]