kernel: scheduling fix for ARM
. make read_tsc_64 use the free-running clock, significantly improving scheduling behaviour Change-Id: Idf6a12f6e26be7fe3b3664c278cae846d8b2a442
This commit is contained in:
parent
af18db5668
commit
8ea66915f2
3 changed files with 37 additions and 23 deletions
|
@ -52,13 +52,13 @@ void cycles_accounting_init(void)
|
|||
|
||||
void context_stop(struct proc * p)
|
||||
{
|
||||
u64_t tsc, tsc_delta;
|
||||
u64_t tsc;
|
||||
u32_t tsc_delta;
|
||||
u64_t * __tsc_ctr_switch = get_cpulocal_var_ptr(tsc_ctr_switch);
|
||||
|
||||
read_tsc_64(&tsc);
|
||||
p->p_cycles = add64(p->p_cycles, sub64(tsc, *__tsc_ctr_switch));
|
||||
|
||||
tsc_delta = sub64(tsc, *__tsc_ctr_switch);
|
||||
tsc_delta = tsc - *__tsc_ctr_switch;
|
||||
p->p_cycles += tsc_delta;
|
||||
|
||||
if(kbill_ipc) {
|
||||
kbill_ipc->p_kipc_cycles =
|
||||
|
@ -79,18 +79,11 @@ void context_stop(struct proc * p)
|
|||
*/
|
||||
if (p->p_endpoint >= 0) {
|
||||
#if DEBUG_RACE
|
||||
make_zero64(p->p_cpu_time_left);
|
||||
p->p_cpu_time_left = 0;
|
||||
#else
|
||||
/* if (tsc_delta < p->p_cpu_time_left) in 64bit */
|
||||
if (ex64hi(tsc_delta) < ex64hi(p->p_cpu_time_left) ||
|
||||
(ex64hi(tsc_delta) == ex64hi(p->p_cpu_time_left) &&
|
||||
ex64lo(tsc_delta) < ex64lo(p->p_cpu_time_left)))
|
||||
{
|
||||
p->p_cpu_time_left = sub64(p->p_cpu_time_left, tsc_delta);
|
||||
}
|
||||
else {
|
||||
make_zero64(p->p_cpu_time_left);
|
||||
}
|
||||
if (tsc_delta < p->p_cpu_time_left) {
|
||||
p->p_cpu_time_left -= tsc_delta;
|
||||
} else p->p_cpu_time_left = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -29,6 +29,8 @@ static int freepdes[MAXFREEPDES];
|
|||
|
||||
static u32_t phys_get32(phys_bytes v);
|
||||
|
||||
extern vir_bytes omap3_gptimer10_base = OMAP3_GPTIMER10_BASE;
|
||||
|
||||
void mem_clear_mapcache(void)
|
||||
{
|
||||
int i;
|
||||
|
@ -763,7 +765,7 @@ int arch_phys_map_reply(const int index, const vir_bytes addr)
|
|||
return OK;
|
||||
}
|
||||
else if (index == frclock_index) {
|
||||
minix_kerninfo.minix_frclock = addr;
|
||||
omap3_gptimer10_base = minix_kerninfo.minix_frclock = addr;
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,9 @@
|
|||
#include "omap_intr.h"
|
||||
|
||||
static irq_hook_t omap3_timer_hook; /* interrupt handler hook */
|
||||
static u64_t tsc;
|
||||
static u64_t high_frc;
|
||||
|
||||
vir_bytes omap3_gptimer10_base;
|
||||
|
||||
int omap3_register_timer_handler(const irq_handler_t handler)
|
||||
{
|
||||
|
@ -90,6 +92,23 @@ void omap3_timer_stop()
|
|||
mmio_clear(OMAP3_GPTIMER1_TCLR, OMAP3_TCLR_ST);
|
||||
}
|
||||
|
||||
static u32_t read_frc(void)
|
||||
{
|
||||
u32_t frc = *(u32_t *) ((char *) omap3_gptimer10_base + OMAP3_TCRR);
|
||||
return frc;
|
||||
}
|
||||
|
||||
static void frc_overflow_check(void)
|
||||
{
|
||||
static int prev_frc_valid;
|
||||
static u32_t prev_frc;
|
||||
u32_t cur_frc = read_frc();
|
||||
if(prev_frc_valid && prev_frc > cur_frc)
|
||||
high_frc++;
|
||||
prev_frc = cur_frc;
|
||||
prev_frc_valid = 1;
|
||||
}
|
||||
|
||||
void omap3_timer_int_handler()
|
||||
{
|
||||
/* Clear all interrupts */
|
||||
|
@ -98,15 +117,15 @@ void omap3_timer_int_handler()
|
|||
tisr = OMAP3_TISR_MAT_IT_FLAG | OMAP3_TISR_OVF_IT_FLAG |
|
||||
OMAP3_TISR_TCAR_IT_FLAG;
|
||||
mmio_write(OMAP3_GPTIMER1_TISR, tisr);
|
||||
tsc++;
|
||||
|
||||
frc_overflow_check();
|
||||
}
|
||||
|
||||
/* Don't use libminlib's read_tsc_64, but our own version instead. We emulate
|
||||
* the ARM Cycle Counter (CCNT) with 1 cycle per ms. We can't rely on the
|
||||
* actual counter hardware to be working (i.e., qemu doesn't emulate it at all)
|
||||
*/
|
||||
/* Use the free running clock as TSC */
|
||||
void read_tsc_64(u64_t *t)
|
||||
{
|
||||
*t = tsc;
|
||||
u32_t now;
|
||||
frc_overflow_check();
|
||||
now = read_frc();
|
||||
*t = (u64_t) now + (high_frc << 32);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue