Time accounting based on TSC
- as thre are still KERNEL and IDLE entries, time accounting for kernel and idle time works the same as for any other process - everytime we stop accounting for the currently running process, kernel or idle, we read the TSC counter and increment the p_cycles entry. - the process cycles inherently include some of the kernel cycles as we can stop accounting for the process only after we save its context and we start accounting just before we restore its context - this assumes that the system does not scale the CPU frequency which will be true for ... long time ;-)
This commit is contained in:
@@ -36,12 +36,16 @@
|
||||
TEST_INT_IN_KERNEL(4, 0f) ;\
|
||||
\
|
||||
SAVE_PROCESS_CTX(0) ;\
|
||||
push %ebp ;\
|
||||
call cycles_accounting_stop ;\
|
||||
add $4, %esp ;\
|
||||
movl $0, %ebp /* for stack trace */ ;\
|
||||
APIC_IRQ_HANDLER(irq) ;\
|
||||
jmp restart ;\
|
||||
\
|
||||
0: \
|
||||
pusha ;\
|
||||
call cycles_accounting_stop_idle ;\
|
||||
APIC_IRQ_HANDLER(irq) ;\
|
||||
popa ;\
|
||||
iret ;
|
||||
@@ -142,12 +146,16 @@ apic_hwint15:
|
||||
TEST_INT_IN_KERNEL(4, 0f) ;\
|
||||
\
|
||||
SAVE_PROCESS_CTX(0) ;\
|
||||
push %ebp ;\
|
||||
call cycles_accounting_stop ;\
|
||||
add $4, %esp ;\
|
||||
movl $0, %ebp /* for stack trace */ ;\
|
||||
LAPIC_INTR_HANDLER(func) ;\
|
||||
jmp restart ;\
|
||||
\
|
||||
0: \
|
||||
pusha ;\
|
||||
call cycles_accounting_stop_idle ;\
|
||||
LAPIC_INTR_HANDLER(func) ;\
|
||||
popa ;\
|
||||
iret ;
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
#include "../../kernel.h"
|
||||
|
||||
#include "../../clock.h"
|
||||
#include "../../proc.h"
|
||||
#include <minix/u64.h>
|
||||
|
||||
|
||||
#ifdef CONFIG_APIC
|
||||
#include "apic.h"
|
||||
@@ -22,6 +25,9 @@
|
||||
#define TIMER_FREQ 1193182 /* clock frequency for timer in PC and AT */
|
||||
#define TIMER_COUNT(freq) (TIMER_FREQ/(freq)) /* initial value for counter*/
|
||||
|
||||
/* FIXME make it cpu local! */
|
||||
PRIVATE u64_t tsc_ctr_switch; /* when did we switched time accounting */
|
||||
|
||||
PRIVATE irq_hook_t pic_timer_hook; /* interrupt handler hook */
|
||||
|
||||
/*===========================================================================*
|
||||
@@ -119,3 +125,22 @@ PUBLIC int arch_register_local_timer_handler(irq_handler_t handler)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
PUBLIC void cycles_accounting_init(void)
|
||||
{
|
||||
read_tsc_64(&tsc_ctr_switch);
|
||||
}
|
||||
|
||||
PUBLIC void cycles_accounting_stop(struct proc * p)
|
||||
{
|
||||
u64_t tsc;
|
||||
|
||||
read_tsc_64(&tsc);
|
||||
p->p_cycles = add64(p->p_cycles, sub64(tsc, tsc_ctr_switch));
|
||||
tsc_ctr_switch = tsc;
|
||||
}
|
||||
|
||||
PUBLIC void cycles_accounting_stop_idle(void)
|
||||
{
|
||||
cycles_accounting_stop(proc_addr(IDLE));
|
||||
}
|
||||
|
||||
@@ -253,6 +253,9 @@ csinit:
|
||||
TEST_INT_IN_KERNEL(4, 0f) ;\
|
||||
\
|
||||
SAVE_PROCESS_CTX(0) ;\
|
||||
push %ebp ;\
|
||||
call cycles_accounting_stop ;\
|
||||
add $4, %esp ;\
|
||||
movl $0, %ebp /* for stack trace */ ;\
|
||||
PIC_IRQ_HANDLER(irq) ;\
|
||||
movb $END_OF_INT, %al ;\
|
||||
@@ -261,6 +264,7 @@ csinit:
|
||||
\
|
||||
0: \
|
||||
pusha ;\
|
||||
call cycles_accounting_stop_idle ;\
|
||||
PIC_IRQ_HANDLER(irq) ;\
|
||||
movb $END_OF_INT, %al ;\
|
||||
outb $INT_CTL /* reenable interrupts in master pic */ ;\
|
||||
@@ -316,6 +320,9 @@ hwint07:
|
||||
TEST_INT_IN_KERNEL(4, 0f) ;\
|
||||
\
|
||||
SAVE_PROCESS_CTX(0) ;\
|
||||
push %ebp ;\
|
||||
call cycles_accounting_stop ;\
|
||||
add $4, %esp ;\
|
||||
movl $0, %ebp /* for stack trace */ ;\
|
||||
PIC_IRQ_HANDLER(irq) ;\
|
||||
movb $END_OF_INT, %al ;\
|
||||
@@ -325,6 +332,7 @@ hwint07:
|
||||
\
|
||||
0: \
|
||||
pusha ;\
|
||||
call cycles_accounting_stop_idle ;\
|
||||
PIC_IRQ_HANDLER(irq) ;\
|
||||
movb $END_OF_INT, %al ;\
|
||||
outb $INT_CTL /* reenable interrupts in master pic */ ;\
|
||||
@@ -395,6 +403,11 @@ ipc_entry:
|
||||
push %eax
|
||||
push %ecx
|
||||
|
||||
/* stop user process cycles */
|
||||
push %ebp
|
||||
call cycles_accounting_stop
|
||||
add $4, %esp
|
||||
|
||||
/* for stack trace */
|
||||
movl $0, %ebp
|
||||
|
||||
@@ -420,9 +433,6 @@ kernel_call_entry:
|
||||
/* save the pointer to the current process */
|
||||
push %ebp
|
||||
|
||||
/* for stack trace */
|
||||
movl $0, %ebp
|
||||
|
||||
/*
|
||||
* pass the syscall arguments from userspace to the handler.
|
||||
* SAVE_PROCESS_CTX() does not clobber these registers, they are still
|
||||
@@ -430,6 +440,14 @@ kernel_call_entry:
|
||||
*/
|
||||
push %eax
|
||||
|
||||
/* stop user process cycles */
|
||||
push %ebp
|
||||
call cycles_accounting_stop
|
||||
add $4, %esp
|
||||
|
||||
/* for stack trace */
|
||||
movl $0, %ebp
|
||||
|
||||
call kernel_call
|
||||
|
||||
/* restore the current process pointer and save the return value */
|
||||
@@ -458,6 +476,11 @@ exception_entry_from_user:
|
||||
|
||||
SAVE_PROCESS_CTX(8)
|
||||
|
||||
/* stop user process cycles */
|
||||
push %ebp
|
||||
call cycles_accounting_stop
|
||||
add $4, %esp
|
||||
|
||||
/* for stack trace clear %ebp */
|
||||
movl $0, %ebp
|
||||
|
||||
@@ -604,6 +627,10 @@ copr_not_available:
|
||||
jnz 0f /* jump if FPU is already initialized */
|
||||
orw $MF_FPU_INITIALIZED, (%ebx)
|
||||
fninit
|
||||
/* stop user process cycles */
|
||||
push %ebp
|
||||
call cycles_accounting_stop
|
||||
add $4, %esp
|
||||
jmp copr_return
|
||||
0: /* load FPU context for current process */
|
||||
mov %ss:FP_SAVE_AREA_P(%ebp), %eax
|
||||
|
||||
@@ -325,10 +325,10 @@ PRIVATE void printslot(struct proc *pp, int level)
|
||||
|
||||
COL
|
||||
|
||||
kprintf("%d: %s %d prio %d/%d time %d/%d cr3 0x%lx rts %s misc %s",
|
||||
kprintf("%d: %s %d prio %d/%d time %d/%d cycles 0x%x%08x cr3 0x%lx rts %s misc %s",
|
||||
proc_nr(pp), pp->p_name, pp->p_endpoint,
|
||||
pp->p_priority, pp->p_max_priority, pp->p_user_time,
|
||||
pp->p_sys_time, pp->p_seg.p_cr3,
|
||||
pp->p_sys_time, pp->p_cycles.hi, pp->p_cycles.lo, pp->p_seg.p_cr3,
|
||||
rtsflagstr(pp->p_rts_flags), miscflagstr(pp->p_misc_flags));
|
||||
|
||||
if(pp->p_rts_flags & RTS_SENDING) {
|
||||
|
||||
Reference in New Issue
Block a user