diff -r 1967c7c290eb xen/common/sched_credit.c --- a/xen/common/sched_credit.c Wed Feb 09 12:03:09 2011 +0000 +++ b/xen/common/sched_credit.c Thu Feb 10 07:39:27 2011 +0100 @@ -50,6 +50,8 @@ (CSCHED_CREDITS_PER_MSEC * CSCHED_MSECS_PER_TSLICE) #define CSCHED_CREDITS_PER_ACCT \ (CSCHED_CREDITS_PER_MSEC * CSCHED_MSECS_PER_TICK * CSCHED_TICKS_PER_ACCT) +#define CSCHED_ACCT_TSLICE \ + (MILLISECS(CSCHED_MSECS_PER_TICK) * CSCHED_TICKS_PER_ACCT) /* @@ -170,6 +172,7 @@ struct csched_private { uint32_t ncpus; struct timer master_ticker; unsigned int master; + int master_active; cpumask_t idlers; cpumask_t cpus; uint32_t weight; @@ -320,6 +323,7 @@ csched_free_pdata(const struct scheduler struct csched_private *prv = CSCHED_PRIV(ops); struct csched_pcpu *spc = pcpu; unsigned long flags; + uint64_t now = NOW(); if ( spc == NULL ) return; @@ -334,10 +338,16 @@ csched_free_pdata(const struct scheduler { prv->master = first_cpu(prv->cpus); migrate_timer(&prv->master_ticker, prv->master); + if ( prv->master_active ) + set_timer(&prv->master_ticker, now + CSCHED_ACCT_TSLICE + - now % CSCHED_ACCT_TSLICE); } kill_timer(&spc->ticker); if ( prv->ncpus == 0 ) + { kill_timer(&prv->master_ticker); + prv->master_active = 0; + } spin_unlock_irqrestore(&prv->lock, flags); @@ -367,12 +377,10 @@ csched_alloc_pdata(const struct schedule { prv->master = cpu; init_timer(&prv->master_ticker, csched_acct, prv, cpu); - set_timer(&prv->master_ticker, NOW() + - MILLISECS(CSCHED_MSECS_PER_TICK) * CSCHED_TICKS_PER_ACCT); + prv->master_active = 0; } init_timer(&spc->ticker, csched_tick, (void *)(unsigned long)cpu, cpu); - set_timer(&spc->ticker, NOW() + MILLISECS(CSCHED_MSECS_PER_TICK)); INIT_LIST_HEAD(&spc->runq); spc->runq_sort_last = prv->runq_sort; @@ -1138,8 +1146,7 @@ csched_acct(void* dummy) prv->runq_sort++; out: - set_timer( &prv->master_ticker, NOW() + - MILLISECS(CSCHED_MSECS_PER_TICK) * CSCHED_TICKS_PER_ACCT ); + set_timer( &prv->master_ticker, NOW() + CSCHED_ACCT_TSLICE ); } static void @@ -1529,24 +1536,39 @@ csched_deinit(const struct scheduler *op xfree(prv); } -static void csched_tick_suspend(const struct scheduler *ops, unsigned int cpu) +static void csched_tick_suspend(const struct scheduler *ops, unsigned int cpu, int temp) { + struct csched_private *prv; struct csched_pcpu *spc; + prv = CSCHED_PRIV(ops); spc = CSCHED_PCPU(cpu); stop_timer(&spc->ticker); + if ( (prv->master == cpu) && !temp ) + { + prv->master = cycle_cpu(prv->master, prv->cpus); + migrate_timer(&prv->master_ticker, prv->master); + } } static void csched_tick_resume(const struct scheduler *ops, unsigned int cpu) { + struct csched_private *prv; struct csched_pcpu *spc; uint64_t now = NOW(); + prv = CSCHED_PRIV(ops); spc = CSCHED_PCPU(cpu); set_timer(&spc->ticker, now + MILLISECS(CSCHED_MSECS_PER_TICK) - now % MILLISECS(CSCHED_MSECS_PER_TICK) ); + if ( (prv->master == cpu) && !prv->master_active ) + { + set_timer(&prv->master_ticker, now + CSCHED_ACCT_TSLICE + - now % CSCHED_ACCT_TSLICE); + prv->master_active = 1; + } } static struct csched_private _csched_priv; diff -r 1967c7c290eb xen/common/schedule.c --- a/xen/common/schedule.c Wed Feb 09 12:03:09 2011 +0000 +++ b/xen/common/schedule.c Thu Feb 10 07:39:27 2011 +0100 @@ -1208,6 +1208,8 @@ static int cpu_schedule_up(unsigned int if ( (ops.alloc_pdata != NULL) && ((sd->sched_priv = ops.alloc_pdata(&ops, cpu)) == NULL) ) return -ENOMEM; + if ( ops.tick_resume != NULL ) + ops.tick_resume(&ops, cpu); return 0; } @@ -1286,6 +1288,8 @@ void __init scheduler_init(void) if ( ops.alloc_pdata && !(this_cpu(schedule_data).sched_priv = ops.alloc_pdata(&ops, 0)) ) BUG(); + if ( ops.tick_resume != NULL ) + ops.tick_resume(&ops, 0); } int schedule_cpu_switch(unsigned int cpu, struct cpupool *c) @@ -1312,7 +1316,7 @@ int schedule_cpu_switch(unsigned int cpu pcpu_schedule_lock_irqsave(cpu, flags); - SCHED_OP(old_ops, tick_suspend, cpu); + SCHED_OP(old_ops, tick_suspend, cpu, 0); vpriv_old = idle->sched_priv; idle->sched_priv = vpriv; per_cpu(scheduler, cpu) = new_ops; @@ -1392,7 +1396,7 @@ void sched_tick_suspend(void) unsigned int cpu = smp_processor_id(); sched = per_cpu(scheduler, cpu); - SCHED_OP(sched, tick_suspend, cpu); + SCHED_OP(sched, tick_suspend, cpu, 1); } void sched_tick_resume(void) diff -r 1967c7c290eb xen/include/xen/sched-if.h --- a/xen/include/xen/sched-if.h Wed Feb 09 12:03:09 2011 +0000 +++ b/xen/include/xen/sched-if.h Thu Feb 10 07:39:27 2011 +0100 @@ -175,7 +175,7 @@ struct scheduler { void (*dump_settings) (const struct scheduler *); void (*dump_cpu_state) (const struct scheduler *, int); - void (*tick_suspend) (const struct scheduler *, unsigned int); + void (*tick_suspend) (const struct scheduler *, unsigned int, int); void (*tick_resume) (const struct scheduler *, unsigned int); };