[S390] boot cputime accounting
Start the cpu time accounting very early to catch the cpu time spent for the initial kernel setup. To make the output of /proc/uptime match the sum of all cpu accounting values of the boot cpu reset xtime and wall_to_monotonic to sane values based on the TOD clock. The values set by timekeeping_init are off by up to a second. Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
parent
b6112ccbff
commit
ab96e798cb
@ -473,7 +473,10 @@ startup:basr %r13,0 # get base
|
|||||||
xc 0x300(256),0x300
|
xc 0x300(256),0x300
|
||||||
l %r1,5f-.LPG0(%r13)
|
l %r1,5f-.LPG0(%r13)
|
||||||
stck 0(%r1)
|
stck 0(%r1)
|
||||||
|
spt 6f-.LPG0(%r13)
|
||||||
|
mvc __LC_LAST_UPDATE_CLOCK(8),0(%r1)
|
||||||
|
mvc __LC_LAST_UPDATE_TIMER(8),6f-.LPG0(%r13)
|
||||||
|
mvc __LC_EXIT_TIMER(8),5f-.LPG0(%r13)
|
||||||
#ifndef CONFIG_MARCH_G5
|
#ifndef CONFIG_MARCH_G5
|
||||||
# check processor version against MARCH_{G5,Z900,Z990,Z9_109,Z10}
|
# check processor version against MARCH_{G5,Z900,Z990,Z9_109,Z10}
|
||||||
stidp __LC_CPUID # store cpuid
|
stidp __LC_CPUID # store cpuid
|
||||||
@ -500,8 +503,11 @@ startup:basr %r13,0 # get base
|
|||||||
|
|
||||||
l %r13,4f-.LPG0(%r13)
|
l %r13,4f-.LPG0(%r13)
|
||||||
b 0(%r13)
|
b 0(%r13)
|
||||||
|
.align 4
|
||||||
4: .long startup_continue
|
4: .long startup_continue
|
||||||
5: .long sched_clock_base_cc
|
5: .long sched_clock_base_cc
|
||||||
|
.align 8
|
||||||
|
6: .long 0x7fffffff,0xffffffff
|
||||||
|
|
||||||
#
|
#
|
||||||
# params at 10400 (setup.h)
|
# params at 10400 (setup.h)
|
||||||
|
@ -434,6 +434,14 @@ setup_lowcore(void)
|
|||||||
#else
|
#else
|
||||||
lc->vdso_per_cpu_data = (unsigned long) &lc->paste[0];
|
lc->vdso_per_cpu_data = (unsigned long) &lc->paste[0];
|
||||||
#endif
|
#endif
|
||||||
|
lc->sync_enter_timer = S390_lowcore.sync_enter_timer;
|
||||||
|
lc->async_enter_timer = S390_lowcore.async_enter_timer;
|
||||||
|
lc->exit_timer = S390_lowcore.exit_timer;
|
||||||
|
lc->user_timer = S390_lowcore.user_timer;
|
||||||
|
lc->system_timer = S390_lowcore.system_timer;
|
||||||
|
lc->steal_timer = S390_lowcore.steal_timer;
|
||||||
|
lc->last_update_timer = S390_lowcore.last_update_timer;
|
||||||
|
lc->last_update_clock = S390_lowcore.last_update_clock;
|
||||||
set_prefix((u32)(unsigned long) lc);
|
set_prefix((u32)(unsigned long) lc);
|
||||||
lowcore_ptr[0] = lc;
|
lowcore_ptr[0] = lc;
|
||||||
}
|
}
|
||||||
|
@ -253,32 +253,52 @@ void update_vsyscall_tz(void)
|
|||||||
*/
|
*/
|
||||||
void __init time_init(void)
|
void __init time_init(void)
|
||||||
{
|
{
|
||||||
|
struct timespec ts;
|
||||||
|
unsigned long flags;
|
||||||
|
cycle_t now;
|
||||||
|
|
||||||
/* Reset time synchronization interfaces. */
|
/* Reset time synchronization interfaces. */
|
||||||
etr_reset();
|
etr_reset();
|
||||||
stp_reset();
|
stp_reset();
|
||||||
|
|
||||||
/* set xtime */
|
|
||||||
tod_to_timeval(sched_clock_base_cc - TOD_UNIX_EPOCH, &xtime);
|
|
||||||
set_normalized_timespec(&wall_to_monotonic,
|
|
||||||
-xtime.tv_sec, -xtime.tv_nsec);
|
|
||||||
|
|
||||||
/* request the clock comparator external interrupt */
|
/* request the clock comparator external interrupt */
|
||||||
if (register_early_external_interrupt(0x1004,
|
if (register_early_external_interrupt(0x1004,
|
||||||
clock_comparator_interrupt,
|
clock_comparator_interrupt,
|
||||||
&ext_int_info_cc) != 0)
|
&ext_int_info_cc) != 0)
|
||||||
panic("Couldn't request external interrupt 0x1004");
|
panic("Couldn't request external interrupt 0x1004");
|
||||||
|
|
||||||
if (clocksource_register(&clocksource_tod) != 0)
|
|
||||||
panic("Could not register TOD clock source");
|
|
||||||
|
|
||||||
/* request the timing alert external interrupt */
|
/* request the timing alert external interrupt */
|
||||||
if (register_early_external_interrupt(0x1406,
|
if (register_early_external_interrupt(0x1406,
|
||||||
timing_alert_interrupt,
|
timing_alert_interrupt,
|
||||||
&ext_int_etr_cc) != 0)
|
&ext_int_etr_cc) != 0)
|
||||||
panic("Couldn't request external interrupt 0x1406");
|
panic("Couldn't request external interrupt 0x1406");
|
||||||
|
|
||||||
|
if (clocksource_register(&clocksource_tod) != 0)
|
||||||
|
panic("Could not register TOD clock source");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The TOD clock is an accurate clock. The xtime should be
|
||||||
|
* initialized in a way that the difference between TOD and
|
||||||
|
* xtime is reasonably small. Too bad that timekeeping_init
|
||||||
|
* sets xtime.tv_nsec to zero. In addition the clock source
|
||||||
|
* change from the jiffies clock source to the TOD clock
|
||||||
|
* source add another error of up to 1/HZ second. The same
|
||||||
|
* function sets wall_to_monotonic to a value that is too
|
||||||
|
* small for /proc/uptime to be accurate.
|
||||||
|
* Reset xtime and wall_to_monotonic to sane values.
|
||||||
|
*/
|
||||||
|
write_seqlock_irqsave(&xtime_lock, flags);
|
||||||
|
now = get_clock();
|
||||||
|
tod_to_timeval(now - TOD_UNIX_EPOCH, &xtime);
|
||||||
|
clocksource_tod.cycle_last = now;
|
||||||
|
clocksource_tod.raw_time = xtime;
|
||||||
|
tod_to_timeval(sched_clock_base_cc - TOD_UNIX_EPOCH, &ts);
|
||||||
|
set_normalized_timespec(&wall_to_monotonic, -ts.tv_sec, -ts.tv_nsec);
|
||||||
|
write_sequnlock_irqrestore(&xtime_lock, flags);
|
||||||
|
|
||||||
/* Enable TOD clock interrupts on the boot cpu. */
|
/* Enable TOD clock interrupts on the boot cpu. */
|
||||||
init_cpu_timer();
|
init_cpu_timer();
|
||||||
|
|
||||||
/* Enable cpu timer interrupts on the boot cpu. */
|
/* Enable cpu timer interrupts on the boot cpu. */
|
||||||
vtime_init();
|
vtime_init();
|
||||||
}
|
}
|
||||||
|
@ -527,16 +527,8 @@ EXPORT_SYMBOL(del_virt_timer);
|
|||||||
*/
|
*/
|
||||||
void init_cpu_vtimer(void)
|
void init_cpu_vtimer(void)
|
||||||
{
|
{
|
||||||
struct thread_info *ti = current_thread_info();
|
|
||||||
struct vtimer_queue *vq;
|
struct vtimer_queue *vq;
|
||||||
|
|
||||||
S390_lowcore.user_timer = ti->user_timer;
|
|
||||||
S390_lowcore.system_timer = ti->system_timer;
|
|
||||||
|
|
||||||
/* kick the virtual timer */
|
|
||||||
asm volatile ("STCK %0" : "=m" (S390_lowcore.last_update_clock));
|
|
||||||
asm volatile ("STPT %0" : "=m" (S390_lowcore.last_update_timer));
|
|
||||||
|
|
||||||
/* initialize per cpu vtimer structure */
|
/* initialize per cpu vtimer structure */
|
||||||
vq = &__get_cpu_var(virt_cpu_timer);
|
vq = &__get_cpu_var(virt_cpu_timer);
|
||||||
INIT_LIST_HEAD(&vq->list);
|
INIT_LIST_HEAD(&vq->list);
|
||||||
|
Loading…
Reference in New Issue
Block a user