Skip to content

Commit

Permalink
[PATCH] s390: idle timer setup
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Martin Schwidefsky authored and Linus Torvalds committed May 1, 2005
1 parent b2c6678 commit 4b7e070
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 15 deletions.
12 changes: 9 additions & 3 deletions arch/s390/kernel/time.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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));
}

/*
Expand Down
25 changes: 13 additions & 12 deletions arch/s390/kernel/vtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand All @@ -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
Expand Down

0 comments on commit 4b7e070

Please sign in to comment.