Add a new timer operation kill_timer(). Effectively the

'opposite' of init_timer(), it marks the end of a timer's
lifetime. After this call the timer will not be pending,
its callback handler will not be running, and future calls
to set_timer() will silently fail.

Signed-off-by: Keir Fraser <keir@xensource.com>
This commit is contained in:
kaf24@firebug.cl.cam.ac.uk committed 2006-01-13 01:03:44 +01:00
1 parent c5c75c2926
commit cc00657854
5 files changed
+80 -45

No files matched your search

+3 -5
View File
@@ -105,13 +105,11 @@ void vmx_relinquish_resources(struct vcpu *v)
destroy_vmcs(&v->arch.arch_vmx);
free_monitor_pagetable(v);
vpit = &v->domain->arch.vmx_platform.vmx_pit;
if ( active_timer(&(vpit->pit_timer)) )
stop_timer(&vpit->pit_timer);
if ( active_timer(&v->arch.arch_vmx.hlt_timer) )
stop_timer(&v->arch.arch_vmx.hlt_timer);
kill_timer(&vpit->pit_timer);
kill_timer(&v->arch.arch_vmx.hlt_timer);
if ( vmx_apic_support(v->domain) && (VLAPIC(v) != NULL) )
{
stop_timer(&VLAPIC(v)->vlapic_timer);
kill_timer(&VLAPIC(v)->vlapic_timer);
xfree(VLAPIC(v));
}
}
+37 -29
View File
@@ -45,9 +45,9 @@ struct bvt_dom_info
limits*/
s32 warp_value; /* virtual time warp */
s_time_t warpl; /* warp limit */
struct timer warp_timer; /* deals with warpl */
struct timer warp_timer; /* deals with warpl */
s_time_t warpu; /* unwarp time requirement */
struct timer unwarp_timer; /* deals with warpu */
struct timer unwarp_timer; /* deals with warpu */
struct bvt_vcpu_info vcpu_inf[MAX_VIRT_CPUS];
};
@@ -168,6 +168,7 @@ static inline u32 calc_evt(struct vcpu *d, u32 avt)
static int bvt_alloc_task(struct vcpu *v)
{
struct domain *d = v->domain;
struct bvt_dom_info *inf;
if ( (d->sched_priv == NULL) )
{
@@ -176,32 +177,12 @@ static int bvt_alloc_task(struct vcpu *v)
memset(d->sched_priv, 0, sizeof(struct bvt_dom_info));
}
v->sched_priv = &BVT_INFO(d)->vcpu_inf[v->vcpu_id];
inf = BVT_INFO(d);
BVT_INFO(d)->vcpu_inf[v->vcpu_id].inf = BVT_INFO(d);
BVT_INFO(d)->vcpu_inf[v->vcpu_id].vcpu = v;
v->sched_priv = &inf->vcpu_inf[v->vcpu_id];
return 0;
}
/*
* Add and remove a domain
*/
static void bvt_add_task(struct vcpu *v)
{
struct bvt_dom_info *inf = BVT_INFO(v->domain);
struct bvt_vcpu_info *einf = EBVT_INFO(v);
ASSERT(inf != NULL);
ASSERT(v != NULL);
/* Allocate per-CPU context if this is the first domain to be added. */
if ( CPU_INFO(v->processor) == NULL )
{
schedule_data[v->processor].sched_priv = xmalloc(struct bvt_cpu_info);
BUG_ON(CPU_INFO(v->processor) == NULL);
INIT_LIST_HEAD(RUNQUEUE(v->processor));
CPU_SVT(v->processor) = 0;
}
inf->vcpu_inf[v->vcpu_id].inf = BVT_INFO(d);
inf->vcpu_inf[v->vcpu_id].vcpu = v;
if ( v->vcpu_id == 0 )
{
@@ -218,7 +199,28 @@ static void bvt_add_task(struct vcpu *v)
init_timer(&inf->unwarp_timer, unwarp_timer_fn, inf, v->processor);
}
einf->vcpu = v;
return 0;
}
/*
* Add and remove a domain
*/
static void bvt_add_task(struct vcpu *v)
{
struct bvt_dom_info *inf = BVT_INFO(v->domain);
struct bvt_vcpu_info *einf = EBVT_INFO(v);
ASSERT(inf != NULL);
ASSERT(v != NULL);
/* Allocate per-CPU context if this is the first domain to be added. */
if ( CPU_INFO(v->processor) == NULL )
{
schedule_data[v->processor].sched_priv = xmalloc(struct bvt_cpu_info);
BUG_ON(CPU_INFO(v->processor) == NULL);
INIT_LIST_HEAD(RUNQUEUE(v->processor));
CPU_SVT(v->processor) = 0;
}
if ( is_idle_vcpu(v) )
{
@@ -305,8 +307,14 @@ static int bvt_set_affinity(struct vcpu *v, cpumask_t *affinity)
*/
static void bvt_free_task(struct domain *d)
{
ASSERT(d->sched_priv != NULL);
xfree(d->sched_priv);
struct bvt_dom_info *inf = BVT_INFO(d);
ASSERT(inf != NULL);
kill_timer(&inf->warp_timer);
kill_timer(&inf->unwarp_timer);
xfree(inf);
}
/* Control the scheduler. */
+2 -2
View File
@@ -156,7 +156,7 @@ void sched_add_domain(struct vcpu *v)
void sched_rem_domain(struct vcpu *v)
{
stop_timer(&v->timer);
kill_timer(&v->timer);
SCHED_OP(rem_task, v);
TRACE_2D(TRC_SCHED_DOM_REM, v->domain->domain_id, v->vcpu_id);
}
@@ -462,7 +462,7 @@ static void s_timer_fn(void *unused)
/* Periodic tick timer: send timer event to current domain */
static void t_timer_fn(void *unused)
{
struct vcpu *v = current;
struct vcpu *v = current;
unsigned int cpu = smp_processor_id();
schedule_data[cpu].tick++;
+29 -9
View File
@@ -29,6 +29,7 @@
struct timers {
spinlock_t lock;
struct timer **heap;
struct timer *running;
} __cacheline_aligned;
struct timers timers[NR_CPUS];
@@ -167,11 +168,11 @@ void set_timer(struct timer *timer, s_time_t expires)
unsigned long flags;
spin_lock_irqsave(&timers[cpu].lock, flags);
ASSERT(timer != NULL);
if ( active_timer(timer) )
__stop_timer(timer);
timer->expires = expires;
__add_timer(timer);
if ( likely(!timer->killed) )
__add_timer(timer);
spin_unlock_irqrestore(&timers[cpu].lock, flags);
}
@@ -182,13 +183,31 @@ void stop_timer(struct timer *timer)
unsigned long flags;
spin_lock_irqsave(&timers[cpu].lock, flags);
ASSERT(timer != NULL);
if ( active_timer(timer) )
__stop_timer(timer);
spin_unlock_irqrestore(&timers[cpu].lock, flags);
}
void kill_timer(struct timer *timer)
{
int cpu = timer->cpu;
unsigned long flags;
BUG_ON(timers[cpu].running == timer);
spin_lock_irqsave(&timers[cpu].lock, flags);
if ( active_timer(timer) )
__stop_timer(timer);
timer->killed = 1;
spin_unlock_irqrestore(&timers[cpu].lock, flags);
for_each_online_cpu ( cpu )
while ( timers[cpu].running == timer )
cpu_relax();
}
static void timer_softirq_action(void)
{
int cpu = smp_processor_id();
@@ -208,19 +227,20 @@ static void timer_softirq_action(void)
{
remove_entry(heap, t);
timers[cpu].running = t;
fn = t->function;
data = t->data;
if ( fn != NULL )
{
spin_unlock_irq(&timers[cpu].lock);
(*fn)(data);
spin_lock_irq(&timers[cpu].lock);
}
spin_unlock_irq(&timers[cpu].lock);
(*fn)(data);
spin_lock_irq(&timers[cpu].lock);
/* Heap may have grown while the lock was released. */
heap = timers[cpu].heap;
}
timers[cpu].running = NULL;
}
while ( !reprogram_timer(GET_HEAP_SIZE(heap) ? heap[1]->expires : 0) );
+9
View File
@@ -22,6 +22,8 @@ struct timer {
void *data;
/* Timer-heap offset. */
unsigned int heap_offset;
/* Has this timer been killed (cannot be activated)? */
int killed;
};
/*
@@ -63,6 +65,13 @@ extern void set_timer(struct timer *timer, s_time_t expires);
*/
extern void stop_timer(struct timer *timer);
/*
* Deactivate a timer and prevent it from being re-set (future calls to
* set_timer will silently fail). When this function returns it is guaranteed
* that the timer callback handler is not running on any CPU.
*/
extern void kill_timer(struct timer *timer);
/*
* Initialisation. Must be called before any other timer function.
*/
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.