[PATCH] s390: idle timer setup

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 <schwidefsky@de.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
Martin Schwidefsky 2005-05-01 08:58:57 -07:00 committed by Linus Torvalds
parent b2c6678c85
commit 4b7e070662
2 changed files with 22 additions and 15 deletions

View File

@ -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));
}
/*

View File

@ -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