78 messages in com.xensource.lists.xen-develRe: [Xen-devel] [PATCH] Add a timer m...| From | Sent On | Attachments |
|---|---|---|
| Shan, Haitao | 30 Oct 2007 07:27 | .patch |
| Keir Fraser | 30 Oct 2007 09:12 | |
| Dave Winchell | 30 Oct 2007 14:15 | .vpt, .c |
| Shan, Haitao | 30 Oct 2007 20:09 | .patch |
| Keir Fraser | 31 Oct 2007 00:09 | |
| Dave Winchell | 01 Nov 2007 14:14 | .patch |
| Dave Winchell | 01 Nov 2007 14:21 | |
| Keir Fraser | 02 Nov 2007 02:40 | |
| Dave Winchell | 02 Nov 2007 08:50 | |
| Keir Fraser | 02 Nov 2007 09:14 | |
| Keir Fraser | 02 Nov 2007 09:35 | |
| Dave Winchell | 02 Nov 2007 11:05 | |
| Dave Winchell | 03 Nov 2007 14:17 | .Other |
| Keir Fraser | 03 Nov 2007 15:31 | .patch |
| Dave Winchell | 05 Nov 2007 06:36 | |
| Dave Winchell | 07 Nov 2007 06:38 | .Other |
| Keir Fraser | 07 Nov 2007 06:39 | |
| Dave Winchell | 07 Nov 2007 08:22 | |
| Keir Fraser | 07 Nov 2007 09:10 | |
| Keir Fraser | 07 Nov 2007 09:28 | |
| Keir Fraser | 07 Nov 2007 09:47 | |
| Dave Winchell | 07 Nov 2007 11:38 | |
| Keir Fraser | 08 Nov 2007 00:07 | |
| Dave Winchell | 08 Nov 2007 06:42 | |
| Keir Fraser | 08 Nov 2007 06:52 | |
| Dave Winchell | 08 Nov 2007 06:57 | |
| Dave Winchell | 08 Nov 2007 07:08 | |
| Dave Winchell | 09 Nov 2007 11:22 | .patch |
| Keir Fraser | 10 Nov 2007 02:54 | |
| Dave Winchell | 12 Nov 2007 07:37 | |
| Dave Winchell | 26 Nov 2007 12:57 | |
| Keir Fraser | 06 Dec 2007 03:56 | |
| Dan Magenheimer | 19 Dec 2007 10:56 | |
| Dave Winchell | 19 Dec 2007 11:32 | |
| Dave Winchell | 19 Dec 2007 11:39 | |
| Dan Magenheimer | 03 Jan 2008 14:57 | |
| Dave Winchell | 03 Jan 2008 15:23 | |
| Dave Winchell | 04 Jan 2008 15:23 | .time |
| Keir Fraser | 08 Jan 2008 06:32 | |
| Dave Winchell | 09 Jan 2008 08:52 | |
| Dan Magenheimer | 09 Jan 2008 09:18 | |
| Keir Fraser | 09 Jan 2008 11:13 | |
| Dan Magenheimer | 25 Jan 2008 15:50 | .png |
| Dave Winchell | 27 Jan 2008 13:21 | |
| Dan Magenheimer | 27 Jan 2008 16:29 | |
| Dave Winchell | 28 Jan 2008 07:20 | |
| Dan Magenheimer | 29 Jan 2008 14:34 | .png |
| Dave Winchell | 30 Jan 2008 07:24 | |
| Deepak Patel | 30 Jan 2008 13:03 | |
| Dave Winchell | 30 Jan 2008 13:44 | |
| Dan Magenheimer | 01 Feb 2008 14:30 | .png |
| Dave Winchell | 04 Feb 2008 12:06 | |
| Dave Winchell | 08 Feb 2008 13:20 | |
| Dave Winchell | 11 Feb 2008 08:52 | .png |
| Dave Winchell | 14 Feb 2008 07:59 | |
| Dan Magenheimer | 14 Feb 2008 08:20 | |
| Dave Winchell | 14 Feb 2008 09:55 | |
| Dan Magenheimer | 15 Feb 2008 08:46 | |
| Dave Winchell | 15 Feb 2008 09:27 | |
| Dave Winchell | 19 Feb 2008 07:26 | |
| Dan Magenheimer | 19 Feb 2008 09:55 | |
| Keir Fraser | 19 Feb 2008 11:29 | |
| Dave Winchell | 19 Feb 2008 12:50 | |
| Dan Magenheimer | 19 Feb 2008 15:37 | |
| Dan Magenheimer | 20 Feb 2008 15:40 | |
| Dan Magenheimer | 25 Feb 2008 08:41 | |
| Dave Winchell | 25 Feb 2008 12:00 | |
| Keir Fraser | 26 Feb 2008 00:25 | |
| Dave Winchell | 26 Feb 2008 06:45 | |
| Keir Fraser | 26 Feb 2008 06:56 | |
| Dave Winchell | 26 Feb 2008 07:48 | |
| Dave Winchell | 05 Mar 2008 07:06 | |
| Keir Fraser | 05 Mar 2008 07:19 | |
| Keir Fraser | 05 Mar 2008 09:20 | |
| Dave Winchell | 05 Mar 2008 09:25 | |
| Dave Winchell | 05 Mar 2008 09:42 | |
| Dan Magenheimer | 05 Mar 2008 09:53 | |
| Dan Magenheimer | 06 Mar 2008 15:35 |
| Subject: | Re: [Xen-devel] [PATCH] Add a timer mode that disables pending missed ticks![]() |
|---|---|
| From: | Keir Fraser (Keir...@cl.cam.ac.uk) |
| Date: | 10/31/2007 12:09:19 AM |
| List: | com.xensource.lists.xen-devel |
I'm going to apply Haitao's no_missed_ticks_fix.patch. If you think fixes are needed apart from that, please provide a unified diff.
-- Keir
On 30/10/07 21:16, "Dave Winchell" <dwin...@virtualiron.com> wrote:
Keir,
Here are my comments on your change. I've attached an updated vpt.c with the changes.
1. For the no_missed_tick_accounting method, we still need the update to pt->scheduled taking into account the time that has elapsed when missed ticks are calculated. missed_ticks (pt_process_missed_ticks) is called from pt_restore_timer() and pt_timer_fn() and, thus, its easiest to put the check for no_missed_tick_accounting method in missed_ticks() itself.
2. In pt_timer_fn you don't want to increment pending_intr_nr beyond 1 for no_missed_tick_accounting option.
thanks, Dave
Keir Fraser wrote:
Applied as c/s 16274. Please take a look and make sure the mode works as you expect.
-- Keir
On 30/10/07 14:28, "Shan, Haitao" <hait...@intel.com> wrote:
Hi, Keir,
This patch adds a new timer mode, in which no missed ticks is calculated. This can be used with latest x86_64 linux guest, since it can pick up missed ticks themselves.
<<no_missed_ticks.patch>>
Best Regards Haitao Shan
------------------------------------------------------------------------ _______________________________________________ Xen-devel mailing list Xen-...@lists.xensource.com http://lists.xensource.com/xen-devel
*** vpt.c.new.c 2007-10-30 16:45:26.000000000 -0400 --- vpt.c 2007-10-30 15:30:57.000000000 -0400 *************** *** 57,73 **** return;
missed_ticks = missed_ticks / (s_time_t) pt->period + 1; ! ! if( !mode_is(pt->vcpu->domain, no_missed_tick_accounting) ) { ! if ( missed_ticks > 1000 ) ! { ! /* TODO: Adjust guest time together */ ! pt->pending_intr_nr++; ! } ! else ! { ! pt->pending_intr_nr += missed_ticks; ! } }
pt->scheduled += missed_ticks * pt->period; --- 57,70 ---- return;
missed_ticks = missed_ticks / (s_time_t) pt->period + 1; ! if ( missed_ticks > 1000 ) ! { ! /* TODO: Adjust guest time together */ ! pt->pending_intr_nr++; ! } ! else ! { ! pt->pending_intr_nr += missed_ticks; }
pt->scheduled += missed_ticks * pt->period; *************** *** 120,126 ****
list_for_each_entry ( pt, head, list ) { ! pt_process_missed_ticks(pt); set_timer(&pt->timer, pt->scheduled); }
--- 117,124 ----
list_for_each_entry ( pt, head, list ) { ! if ( !mode_is(v->domain, no_missed_tick_accounting) ) ! pt_process_missed_ticks(pt); set_timer(&pt->timer, pt->scheduled); }
*************** *** 135,151 ****
pt_lock(pt);
! if (mode_is(pt->vcpu->domain, no_missed_tick_accounting)) { ! if(!pt->pending_intr_nr) ! pt->pending_intr_nr++; ! } ! else ! pt->pending_intr_nr++;
if ( !pt->one_shot ) { pt->scheduled += pt->period; ! pt_process_missed_ticks(pt); set_timer(&pt->timer, pt->scheduled); }
--- 133,152 ----
pt_lock(pt);
! pt->pending_intr_nr++;
if ( !pt->one_shot ) { pt->scheduled += pt->period; ! if ( !mode_is(pt->vcpu->domain, no_missed_tick_accounting) ) ! { ! pt_process_missed_ticks(pt); ! } ! else if ( (NOW() - pt->scheduled) >= 0 ) ! { ! pt->pending_intr_nr++; ! pt->scheduled = NOW() + pt->period; ! } set_timer(&pt->timer, pt->scheduled); }
/* * vpt.c: Virtual Platform Timer * * Copyright (c) 2006, Xiaowei Yang, Intel Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. * * This program is distributed in the hope it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc., 59 Temple * Place - Suite 330, Boston, MA 02111-1307 USA. * */
#include <xen/time.h> #include <asm/hvm/support.h> #include <asm/hvm/vpt.h> #include <asm/event.h>
#define mode_is(d, name) \ ((d)->arch.hvm_domain.params[HVM_PARAM_TIMER_MODE] == HVMPTM_##name)
static void pt_lock(struct periodic_time *pt) { struct vcpu *v;
for ( ; ; ) { v = pt->vcpu; spin_lock(&v->arch.hvm_vcpu.tm_lock); if ( likely(pt->vcpu == v) ) break; spin_unlock(&v->arch.hvm_vcpu.tm_lock); } }
static void pt_unlock(struct periodic_time *pt) { spin_unlock(&pt->vcpu->arch.hvm_vcpu.tm_lock); }
static void pt_process_missed_ticks(struct periodic_time *pt) { s_time_t missed_ticks;
if ( pt->one_shot ) return;
missed_ticks = NOW() - pt->scheduled; if ( missed_ticks <= 0 ) return;
missed_ticks = missed_ticks / (s_time_t) pt->period + 1;
if( !mode_is(pt->vcpu->domain, no_missed_tick_accounting) ) { if ( missed_ticks > 1000 ) { /* TODO: Adjust guest time together */ pt->pending_intr_nr++; } else { pt->pending_intr_nr += missed_ticks; } }
pt->scheduled += missed_ticks * pt->period; }
static void pt_freeze_time(struct vcpu *v) { if ( !mode_is(v->domain, delay_for_missed_ticks) ) return;
v->arch.hvm_vcpu.guest_time = hvm_get_guest_time(v); }
static void pt_thaw_time(struct vcpu *v) { if ( !mode_is(v->domain, delay_for_missed_ticks) ) return;
if ( v->arch.hvm_vcpu.guest_time == 0 ) return;
hvm_set_guest_time(v, v->arch.hvm_vcpu.guest_time); v->arch.hvm_vcpu.guest_time = 0; }
void pt_save_timer(struct vcpu *v) { struct list_head *head = &v->arch.hvm_vcpu.tm_list; struct periodic_time *pt;
if ( test_bit(_VPF_blocked, &v->pause_flags) ) return;
spin_lock(&v->arch.hvm_vcpu.tm_lock);
list_for_each_entry ( pt, head, list ) stop_timer(&pt->timer);
pt_freeze_time(v);
spin_unlock(&v->arch.hvm_vcpu.tm_lock); }
void pt_restore_timer(struct vcpu *v) { struct list_head *head = &v->arch.hvm_vcpu.tm_list; struct periodic_time *pt;
spin_lock(&v->arch.hvm_vcpu.tm_lock);
list_for_each_entry ( pt, head, list ) { pt_process_missed_ticks(pt); set_timer(&pt->timer, pt->scheduled); }
pt_thaw_time(v);
spin_unlock(&v->arch.hvm_vcpu.tm_lock); }
static void pt_timer_fn(void *data) { struct periodic_time *pt = data;
pt_lock(pt);
if (mode_is(pt->vcpu->domain, no_missed_tick_accounting)) { if(!pt->pending_intr_nr) pt->pending_intr_nr++; } else pt->pending_intr_nr++;
if ( !pt->one_shot ) { pt->scheduled += pt->period; pt_process_missed_ticks(pt); set_timer(&pt->timer, pt->scheduled); }
vcpu_kick(pt->vcpu);
pt_unlock(pt); }
void pt_update_irq(struct vcpu *v) { struct list_head *head = &v->arch.hvm_vcpu.tm_list; struct periodic_time *pt; uint64_t max_lag = -1ULL; int irq = -1;
spin_lock(&v->arch.hvm_vcpu.tm_lock);
list_for_each_entry ( pt, head, list ) { if ( !is_isa_irq_masked(v, pt->irq) && pt->pending_intr_nr && ((pt->last_plt_gtime + pt->period_cycles) < max_lag) ) { max_lag = pt->last_plt_gtime + pt->period_cycles; irq = pt->irq; } }
spin_unlock(&v->arch.hvm_vcpu.tm_lock);
if ( is_lvtt(v, irq) ) { vlapic_set_irq(vcpu_vlapic(v), irq, 0); } else if ( irq >= 0 ) { hvm_isa_irq_deassert(v->domain, irq); hvm_isa_irq_assert(v->domain, irq); } }
static struct periodic_time *is_pt_irq( struct vcpu *v, struct hvm_intack intack) { struct list_head *head = &v->arch.hvm_vcpu.tm_list; struct periodic_time *pt; struct RTCState *rtc = &v->domain->arch.hvm_domain.pl_time.vrtc; int vector;
list_for_each_entry ( pt, head, list ) { if ( !pt->pending_intr_nr ) continue;
if ( is_lvtt(v, pt->irq) ) { if ( pt->irq != intack.vector ) continue; return pt; }
vector = get_isa_irq_vector(v, pt->irq, intack.source);
/* RTC irq need special care */ if ( (intack.vector != vector) || ((pt->irq == 8) && !is_rtc_periodic_irq(rtc)) ) continue;
return pt; }
return NULL; }
void pt_intr_post(struct vcpu *v, struct hvm_intack intack) { struct periodic_time *pt; time_cb *cb; void *cb_priv;
spin_lock(&v->arch.hvm_vcpu.tm_lock);
pt = is_pt_irq(v, intack); if ( pt == NULL ) { spin_unlock(&v->arch.hvm_vcpu.tm_lock); return; }
if ( pt->one_shot ) { pt->enabled = 0; list_del(&pt->list); } else { pt->pending_intr_nr--; if ( mode_is(v->domain, no_missed_tick_accounting) ) pt->last_plt_gtime = hvm_get_guest_time(v); else pt->last_plt_gtime += pt->period_cycles; }
if ( mode_is(v->domain, delay_for_missed_ticks) && (hvm_get_guest_time(v) < pt->last_plt_gtime) ) hvm_set_guest_time(v, pt->last_plt_gtime);
cb = pt->cb; cb_priv = pt->priv;
spin_unlock(&v->arch.hvm_vcpu.tm_lock);
if ( cb != NULL ) cb(v, cb_priv); }
void pt_reset(struct vcpu *v) { struct list_head *head = &v->arch.hvm_vcpu.tm_list; struct periodic_time *pt;
spin_lock(&v->arch.hvm_vcpu.tm_lock);
list_for_each_entry ( pt, head, list ) { pt->pending_intr_nr = 0; pt->last_plt_gtime = hvm_get_guest_time(pt->vcpu); pt->scheduled = NOW() + pt->period; set_timer(&pt->timer, pt->scheduled); }
spin_unlock(&v->arch.hvm_vcpu.tm_lock); }
void pt_migrate(struct vcpu *v) { struct list_head *head = &v->arch.hvm_vcpu.tm_list; struct periodic_time *pt;
spin_lock(&v->arch.hvm_vcpu.tm_lock);
list_for_each_entry ( pt, head, list ) migrate_timer(&pt->timer, v->processor);
spin_unlock(&v->arch.hvm_vcpu.tm_lock); }
void create_periodic_time( struct vcpu *v, struct periodic_time *pt, uint64_t period, uint8_t irq, char one_shot, time_cb *cb, void *data) { destroy_periodic_time(pt);
spin_lock(&v->arch.hvm_vcpu.tm_lock);
pt->enabled = 1; pt->pending_intr_nr = 0;
/* Periodic timer must be at least 0.9ms. */ if ( (period < 900000) && !one_shot ) { gdprintk(XENLOG_WARNING, "HVM_PlatformTime: program too small period %"PRIu64"\n", period); period = 900000; }
pt->period = period; pt->vcpu = v; pt->last_plt_gtime = hvm_get_guest_time(pt->vcpu); pt->irq = irq; pt->period_cycles = (u64)period * cpu_khz / 1000000L; pt->one_shot = one_shot; pt->scheduled = NOW() + period; /* * Offset LAPIC ticks from other timer ticks. Otherwise guests which use * LAPIC ticks for process accounting can see long sequences of process * ticks incorrectly accounted to interrupt processing. */ if ( is_lvtt(v, irq) ) pt->scheduled += period >> 1; pt->cb = cb; pt->priv = data;
list_add(&pt->list, &v->arch.hvm_vcpu.tm_list);
init_timer(&pt->timer, pt_timer_fn, pt, v->processor); set_timer(&pt->timer, pt->scheduled);
spin_unlock(&v->arch.hvm_vcpu.tm_lock); }
void destroy_periodic_time(struct periodic_time *pt) { if ( !pt->enabled ) return;
pt_lock(pt); pt->enabled = 0; list_del(&pt->list); pt_unlock(pt);
/* * pt_timer_fn() can run until this kill_timer() returns. We must do this * outside pt_lock() otherwise we can deadlock with pt_timer_fn(). */ kill_timer(&pt->timer); }
_______________________________________________ Xen-devel mailing list Xen-...@lists.xensource.com http://lists.xensource.com/xen-devel





.patch