From: Tomas Hruby Date: Wed, 15 Sep 2010 14:10:27 +0000 (+0000) Subject: SMP - CPU local cycles accounting X-Git-Tag: v3.2.0~856 X-Git-Url: http://zhaoyanbai.com/repos/%22http:/www.isc.org/icons/soc.html?a=commitdiff_plain;h=d37b7ebc0bf1b180e832e4b05b663445b63983ec;p=minix.git SMP - CPU local cycles accounting - tsc_ctr_switch is made cpu local - although an x86 specific variable it must be declared globaly as the cpulocal implementation does not allow otherwise --- diff --git a/kernel/arch/i386/arch_clock.c b/kernel/arch/i386/arch_clock.c index 7c2309573..27483fccf 100644 --- a/kernel/arch/i386/arch_clock.c +++ b/kernel/arch/i386/arch_clock.c @@ -27,9 +27,6 @@ #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 */ PRIVATE unsigned probe_ticks; @@ -175,17 +172,17 @@ PUBLIC int arch_register_local_timer_handler(const irq_handler_t handler) PUBLIC void cycles_accounting_init(void) { - read_tsc_64(&tsc_ctr_switch); + read_tsc_64(get_cpulocal_var_ptr(tsc_ctr_switch)); } PUBLIC void context_stop(struct proc * p) { u64_t tsc, tsc_delta; + u64_t * __tsc_ctr_switch = get_cpulocal_var_ptr(tsc_ctr_switch); read_tsc_64(&tsc); - tsc_delta = sub64(tsc, tsc_ctr_switch); + tsc_delta = sub64(tsc, *__tsc_ctr_switch); p->p_cycles = add64(p->p_cycles, tsc_delta); - tsc_ctr_switch = tsc; /* * deduct the just consumed cpu cycles from the cpu time left for this @@ -215,10 +212,17 @@ PUBLIC void context_stop(struct proc * p) * If we stop accounting for KERNEL we must unlock the BKL. If account * for IDLE we must not hold the lock */ - if (p == proc_addr(KERNEL)) + if (p == proc_addr(KERNEL)) { + read_tsc_64(&tsc); + p->p_cycles = add64(p->p_cycles, sub64(tsc, *__tsc_ctr_switch)); BKL_UNLOCK(); - else + } else { BKL_LOCK(); + read_tsc_64(&tsc); + p->p_cycles = add64(p->p_cycles, sub64(tsc, *__tsc_ctr_switch)); + } + + *__tsc_ctr_switch = tsc; } PUBLIC void context_stop_idle(void) diff --git a/kernel/arch/i386/arch_smp.c b/kernel/arch/i386/arch_smp.c index 88b20a7cc..e45d0439a 100644 --- a/kernel/arch/i386/arch_smp.c +++ b/kernel/arch/i386/arch_smp.c @@ -211,7 +211,7 @@ PRIVATE void ap_finish_booting(void) if (app_cpu_init_timer(system_hz)) { panic("FATAL : failed to initialize timer interrupts CPU %d, " - "cannot continue without any clock source!", cpuid); + "cannot continue without any clock source!", cpu); } printf("CPU %d local APIC timer is ticking\n", cpu); diff --git a/kernel/cpulocals.h b/kernel/cpulocals.h index f9faefa9a..fad9ede5c 100644 --- a/kernel/cpulocals.h +++ b/kernel/cpulocals.h @@ -30,6 +30,7 @@ #define get_cpulocal_var(name) CPULOCAL_STRUCT.name #define get_cpulocal_var_ptr(name) &(get_cpulocal_var(name)) #define get_cpu_var(cpu, name) get_cpulocal_var(name) +#define get_cpu_var_ptr(cpu, name) get_cpulocal_var_ptr(name) #endif @@ -74,6 +75,8 @@ DECLARE_CPULOCAL(struct proc *, ptproc); DECLARE_CPULOCAL(struct proc *, run_q_head[NR_SCHED_QUEUES]); /* ptrs to ready list headers */ DECLARE_CPULOCAL(struct proc *, run_q_tail[NR_SCHED_QUEUES]); /* ptrs to ready list tails */ +DECLARE_CPULOCAL(u64_t ,tsc_ctr_switch); /* when did we switched time accounting */ + DECLARE_CPULOCAL_END #endif /* __ASSEMBLY__ */