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
					
				@ -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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user