# HG changeset patch # User George Dunlap # Date 1322758205 0 # Node ID e122485df37b57f58dbf13ec81a18169c0a7e90f # Parent 96bbdc894224821fbc14a33e93b55688920c7fd2 imported patch credit_2.patch diff -r c613d436ca09 xen/common/sched_credit.c --- a/xen/common/sched_credit.c Tue Nov 22 19:03:04 2011 +0000 +++ b/xen/common/sched_credit.c Thu Dec 01 17:15:12 2011 +0000 @@ -115,6 +115,10 @@ static bool_t __read_mostly sched_credit boolean_param("sched_credit_default_yield", sched_credit_default_yield); /* + * Scheduler generic parameters + */ +extern int sched_ratelimit_us; +/* * Physical CPU */ struct csched_pcpu { @@ -1299,10 +1303,15 @@ csched_schedule( struct csched_private *prv = CSCHED_PRIV(ops); struct csched_vcpu *snext; struct task_slice ret; + s_time_t runtime, tslice; + struct schedule_data *sd; CSCHED_STAT_CRANK(schedule); CSCHED_VCPU_CHECK(current); + runtime = now - current->runstate.state_entry_time; + if ( runtime < 0 ) /* Does this ever happen? */ + runtime = 0; if ( !is_idle_vcpu(scurr->vcpu) ) { /* Update credits of a non-idle VCPU. */ @@ -1314,7 +1323,33 @@ csched_schedule( /* Re-instate a boosted idle VCPU as normal-idle. */ scurr->pri = CSCHED_PRI_IDLE; } - + /* If we have schedule rate limiting enabled, check to see + * how long we've run for. */ + + if ( sched_ratelimit_us + && vcpu_runnable(current) + && !is_idle_vcpu(current) + && runtime < MICROSECS(sched_ratelimit_us) ) + { + snext = scurr; + perfc_incr(delay_ms); + /* FIXME: Use prv->tslice_ms if we're also the head of hte queue */ + //tslice = MICROSECS(sched_ratelimit_us); + tslice = MILLISECS(sched_ratelimit_us); + ret.time = tslice; + ret.task = snext->vcpu; + ret.migrated = 0; + CSCHED_VCPU_CHECK(ret.task); + return ret; + } + else + { + /* + * Select next runnable local VCPU (ie top of local runq) + */ + tslice = MILLISECS(CSCHED_MSECS_PER_TSLICE); + } + /* * Select next runnable local VCPU (ie top of local runq) */ @@ -1373,7 +1408,7 @@ csched_schedule( * Return task to run next... */ ret.time = (is_idle_vcpu(snext->vcpu) ? - -1 : MILLISECS(CSCHED_MSECS_PER_TSLICE)); + -1 : tslice); ret.task = snext->vcpu; CSCHED_VCPU_CHECK(ret.task); diff -r c613d436ca09 xen/common/schedule.c --- a/xen/common/schedule.c Tue Nov 22 19:03:04 2011 +0000 +++ b/xen/common/schedule.c Thu Dec 01 17:15:12 2011 +0000 @@ -47,6 +47,10 @@ string_param("sched", opt_sched); bool_t sched_smt_power_savings = 0; boolean_param("sched_smt_power_savings", sched_smt_power_savings); +/* Default scheduling rate limit: 1ms */ +int sched_ratelimit_us = 1000; +integer_param("sched_ratelimit_us", sched_ratelimit_us); + /* Various timer handlers. */ static void s_timer_fn(void *unused); static void vcpu_periodic_timer_fn(void *data); diff -r c613d436ca09 xen/include/xen/perfc_defn.h --- a/xen/include/xen/perfc_defn.h Tue Nov 22 19:03:04 2011 +0000 +++ b/xen/include/xen/perfc_defn.h Thu Dec 01 17:15:12 2011 +0000 @@ -20,6 +20,7 @@ PERFCOUNTER(vcpu_check, "csc PERFCOUNTER(schedule, "csched: schedule") PERFCOUNTER(acct_run, "csched: acct_run") PERFCOUNTER(acct_no_work, "csched: acct_no_work") +PERFCOUNTER(delay_ms, "csched: 1ms delay") PERFCOUNTER(acct_balance, "csched: acct_balance") PERFCOUNTER(acct_reorder, "csched: acct_reorder") PERFCOUNTER(acct_min_credit, "csched: acct_min_credit")