From: Patrick Bridges Date: Tue, 14 Jun 2011 18:57:56 +0000 (-0600) Subject: More timing cleanup X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=33d86eaa5e5081775fd013466393496b476925b0 More timing cleanup --- diff --git a/palacios/src/devices/apic.c b/palacios/src/devices/apic.c index 5d6da5e..508f221 100644 --- a/palacios/src/devices/apic.c +++ b/palacios/src/devices/apic.c @@ -1357,6 +1357,8 @@ static int apic_write(struct guest_info * core, addr_t guest_addr, void * src, u apic->tmr_cur_cnt = op_val; break; case TMR_DIV_CFG_OFFSET: + PrintDebug("apic %u: core %u: setting tmr_div_cfg to 0x%x\n", + apic->lapic_id.val, core->vcpu_id, op_val); apic->tmr_div_cfg.val = op_val; break; @@ -1650,6 +1652,19 @@ static void apic_update_time(struct guest_info * core, } if (apic->tmr_vec_tbl.tmr_mode == APIC_TMR_PERIODIC) { + static unsigned int nexits = 0; + static unsigned int missed_ints = 0; + + nexits++; + missed_ints += tmr_ticks / apic->tmr_init_cnt; + + if ((missed_ints > 0) && (nexits >= 5000)) { + V3_Print("apic %u: core %u: missed %u timer interrupts total in last %u exits.\n", + apic->lapic_id.val, core->vcpu_id, missed_ints, nexits); + missed_ints = 0; + nexits = 0; + } + tmr_ticks = tmr_ticks % apic->tmr_init_cnt; apic->tmr_cur_cnt = apic->tmr_init_cnt - tmr_ticks; } diff --git a/palacios/src/palacios/svm.c b/palacios/src/palacios/svm.c index 6e8bece..7d7b43c 100644 --- a/palacios/src/palacios/svm.c +++ b/palacios/src/palacios/svm.c @@ -463,9 +463,9 @@ int v3_svm_enter(struct guest_info * info) { // disable global interrupts for vm state transition v3_clgi(); - // Update timer devices right before entering the VM. Doing it - // here makes sure the guest sees any timers that fired while - // it was in the VMM + // Update timer devices after being in the VM, with interupts + // disabled, but before doing IRQ updates, so that any interrupts they + //raise get seen immediately. v3_update_timers(info); // Synchronize the guest state to the VMCB @@ -550,13 +550,11 @@ int v3_svm_enter(struct guest_info * info) { info->mem_mode = v3_get_vm_mem_mode(info); /* ** */ - // save exit info here exit_code = guest_ctrl->exit_code; exit_info1 = guest_ctrl->exit_info1; exit_info2 = guest_ctrl->exit_info2; - #ifdef V3_CONFIG_SYMCALL if (info->sym_core_state.symcall_state.sym_call_active == 0) { update_irq_exit_state(info); @@ -565,16 +563,12 @@ int v3_svm_enter(struct guest_info * info) { update_irq_exit_state(info); #endif - // reenable global interrupts after vm exit v3_stgi(); - // Conditionally yield the CPU if the timeslice has expired v3_yield_cond(info); - - if (v3_handle_svm_exit(info, exit_code, exit_info1, exit_info2) != 0) { PrintError("Error in SVM exit handler\n"); PrintError(" last exit was %d\n", v3_last_exit); diff --git a/palacios/src/palacios/vmx.c b/palacios/src/palacios/vmx.c index f26a1ea..5963d93 100644 --- a/palacios/src/palacios/vmx.c +++ b/palacios/src/palacios/vmx.c @@ -749,9 +749,10 @@ int v3_vmx_enter(struct guest_info * info) { // disable global interrupts for vm state transition v3_disable_ints(); - // Update timer devices prior to entering VM. Doing it here - // makes sure the guest sees any timers that fired while it - // was in the VMM + // Update timer devices late after being in the VM so that as much + // of hte time in the VM is accounted for as possible. Also do it before + // updating IRQ entry state so that any interrupts the timers raise get + // handled on the next VM entry. Must be done with interrupts disabled. v3_update_timers(info); if (vmcs_store() != vmx_info->vmcs_ptr_phys) { @@ -842,7 +843,6 @@ int v3_vmx_enter(struct guest_info * info) { exit_log[info->num_exits % 10] = exit_info; - #ifdef V3_CONFIG_SYMCALL if (info->sym_core_state.symcall_state.sym_call_active == 0) { update_irq_exit_state(info);