diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2010-04-21 12:48:03 +0100 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2010-04-21 12:48:03 +0100 |
commit | 78be3dbbfefa43c4ff4a19ae84342b907e0cef4a (patch) | |
tree | 09f193bbd11b37f0a9721e347ab27eeb000dbb13 /xen/common/sched_sedf.c | |
parent | b066d6894d38a2be3f4eb67e974cfdf1275e9da2 (diff) | |
download | xen-78be3dbbfefa43c4ff4a19ae84342b907e0cef4a.tar.gz xen-78be3dbbfefa43c4ff4a19ae84342b907e0cef4a.tar.bz2 xen-78be3dbbfefa43c4ff4a19ae84342b907e0cef4a.zip |
cpupools [1/6]: hypervisor changes
Signed-off-by: Juergen Gross <juergen.gross@ts.fujitsu.com>
Diffstat (limited to 'xen/common/sched_sedf.c')
-rw-r--r-- | xen/common/sched_sedf.c | 144 |
1 files changed, 98 insertions, 46 deletions
diff --git a/xen/common/sched_sedf.c b/xen/common/sched_sedf.c index e2722ea3c2..0defd97f31 100644 --- a/xen/common/sched_sedf.c +++ b/xen/common/sched_sedf.c @@ -21,6 +21,9 @@ printk(_a ); \ } while ( 0 ) +#define SEDF_CPUONLINE(_pool) \ + (((_pool) == NULL) ? &cpupool_free_cpus : &(_pool)->cpu_valid) + #ifndef NDEBUG #define SEDF_STATS #define CHECK(_p) \ @@ -132,7 +135,7 @@ struct sedf_cpu_info { #define sedf_runnable(edom) (!(EDOM_INFO(edom)->status & SEDF_ASLEEP)) -static void sedf_dump_cpu_state(int i); +static void sedf_dump_cpu_state(struct scheduler *ops, int i); static inline int extraq_on(struct vcpu *d, int i) { @@ -329,30 +332,17 @@ static inline void __add_to_runqueue_sort(struct vcpu *v) } -static int sedf_init_vcpu(struct vcpu *v) +static void *sedf_alloc_vdata(struct scheduler *ops, struct vcpu *v, void *dd) { struct sedf_vcpu_info *inf; - if ( (v->sched_priv = xmalloc(struct sedf_vcpu_info)) == NULL ) - return -1; - memset(v->sched_priv, 0, sizeof(struct sedf_vcpu_info)); + inf = xmalloc(struct sedf_vcpu_info); + if ( inf == NULL ) + return NULL; - inf = EDOM_INFO(v); + memset(inf, 0, sizeof(struct sedf_vcpu_info)); inf->vcpu = v; - - /* Allocate per-CPU context if this is the first domain to be added. */ - if ( unlikely(per_cpu(schedule_data, v->processor).sched_priv == NULL) ) - { - per_cpu(schedule_data, v->processor).sched_priv = - xmalloc(struct sedf_cpu_info); - BUG_ON(per_cpu(schedule_data, v->processor).sched_priv == NULL); - memset(CPU_INFO(v->processor), 0, sizeof(*CPU_INFO(v->processor))); - INIT_LIST_HEAD(WAITQ(v->processor)); - INIT_LIST_HEAD(RUNQ(v->processor)); - INIT_LIST_HEAD(EXTRAQ(v->processor,EXTRA_PEN_Q)); - INIT_LIST_HEAD(EXTRAQ(v->processor,EXTRA_UTIL_Q)); - } - + /* Every VCPU gets an equal share of extratime by default. */ inf->deadl_abs = 0; inf->latency = 0; @@ -383,39 +373,88 @@ static int sedf_init_vcpu(struct vcpu *v) } else { - EDOM_INFO(v)->deadl_abs = 0; - EDOM_INFO(v)->status &= ~SEDF_ASLEEP; + inf->deadl_abs = 0; + inf->status &= ~SEDF_ASLEEP; } - return 0; + return inf; +} + +static void * +sedf_alloc_pdata(struct scheduler *ops, int cpu) +{ + struct sedf_cpu_info *spc; + + spc = xmalloc(struct sedf_cpu_info); + BUG_ON(spc == NULL); + memset(spc, 0, sizeof(*spc)); + INIT_LIST_HEAD(&spc->waitq); + INIT_LIST_HEAD(&spc->runnableq); + INIT_LIST_HEAD(&spc->extraq[EXTRA_PEN_Q]); + INIT_LIST_HEAD(&spc->extraq[EXTRA_UTIL_Q]); + + return (void *)spc; +} + +static void +sedf_free_pdata(struct scheduler *ops, void *spc, int cpu) +{ + if ( spc == NULL ) + return; + + xfree(spc); +} + +static void sedf_free_vdata(struct scheduler *ops, void *priv) +{ + xfree(priv); } -static void sedf_destroy_vcpu(struct vcpu *v) +static void sedf_destroy_vcpu(struct scheduler *ops, struct vcpu *v) { - xfree(v->sched_priv); + sedf_free_vdata(ops, v->sched_priv); } -static int sedf_init_domain(struct domain *d) +static void * +sedf_alloc_domdata(struct scheduler *ops, struct domain *d) { - d->sched_priv = xmalloc(struct sedf_dom_info); + void *mem; + + mem = xmalloc(struct sedf_dom_info); + if ( mem == NULL ) + return NULL; + + memset(mem, 0, sizeof(struct sedf_dom_info)); + + return mem; +} + +static int sedf_init_domain(struct scheduler *ops, struct domain *d) +{ + d->sched_priv = sedf_alloc_domdata(ops, d); if ( d->sched_priv == NULL ) return -ENOMEM; - memset(d->sched_priv, 0, sizeof(struct sedf_dom_info)); - return 0; } -static void sedf_destroy_domain(struct domain *d) +static void sedf_free_domdata(struct scheduler *ops, void *data) +{ + xfree(data); +} + +static void sedf_destroy_domain(struct scheduler *ops, struct domain *d) { - xfree(d->sched_priv); + sedf_free_domdata(ops, d->sched_priv); } -static int sedf_pick_cpu(struct vcpu *v) +static int sedf_pick_cpu(struct scheduler *ops, struct vcpu *v) { cpumask_t online_affinity; + cpumask_t *online; - cpus_and(online_affinity, v->cpu_affinity, cpu_online_map); + online = SEDF_CPUONLINE(v->domain->cpupool); + cpus_and(online_affinity, v->cpu_affinity, *online); return first_cpu(online_affinity); } @@ -751,7 +790,7 @@ static struct task_slice sedf_do_extra_schedule( -timeslice for the current period used up -domain on waitqueue has started it's period -and various others ;) in general: determine which domain to run next*/ -static struct task_slice sedf_do_schedule(s_time_t now) +static struct task_slice sedf_do_schedule(struct scheduler *ops, s_time_t now) { int cpu = smp_processor_id(); struct list_head *runq = RUNQ(cpu); @@ -786,6 +825,13 @@ static struct task_slice sedf_do_schedule(s_time_t now) } check_waitq: update_queues(now, runq, waitq); + + if ( unlikely(!cpu_isset(cpu, *SEDF_CPUONLINE(per_cpu(cpupool, cpu)))) ) + { + ret.task = IDLETASK(cpu); + ret.time = SECONDS(1); + goto sched_done; + } /*now simply pick the first domain from the runqueue, which has the earliest deadline, because the list is sorted*/ @@ -824,6 +870,7 @@ static struct task_slice sedf_do_schedule(s_time_t now) extraq, cpu); } + sched_done: /*TODO: Do something USEFUL when this happens and find out, why it still can happen!!!*/ if ( ret.time < 0) @@ -841,7 +888,7 @@ static struct task_slice sedf_do_schedule(s_time_t now) } -static void sedf_sleep(struct vcpu *d) +static void sedf_sleep(struct scheduler *ops, struct vcpu *d) { PRINT(2,"sedf_sleep was called, domain-id %i.%i\n", d->domain->domain_id, d->vcpu_id); @@ -1060,7 +1107,7 @@ static inline int should_switch(struct vcpu *cur, return 1; } -static void sedf_wake(struct vcpu *d) +static void sedf_wake(struct scheduler *ops, struct vcpu *d) { s_time_t now = NOW(); struct sedf_vcpu_info* inf = EDOM_INFO(d); @@ -1213,8 +1260,8 @@ static void sedf_dump_domain(struct vcpu *d) } -/* dumps all domains on hte specified cpu */ -static void sedf_dump_cpu_state(int i) +/* dumps all domains on the specified cpu */ +static void sedf_dump_cpu_state(struct scheduler *ops, int i) { struct list_head *list, *queue, *tmp; struct sedf_vcpu_info *d_inf; @@ -1287,7 +1334,7 @@ static void sedf_dump_cpu_state(int i) /* Adjusts periods and slices of the domains accordingly to their weights. */ -static int sedf_adjust_weights(struct xen_domctl_scheduler_op *cmd) +static int sedf_adjust_weights(struct cpupool *c, struct xen_domctl_scheduler_op *cmd) { struct vcpu *p; struct domain *d; @@ -1308,6 +1355,8 @@ static int sedf_adjust_weights(struct xen_domctl_scheduler_op *cmd) rcu_read_lock(&domlist_read_lock); for_each_domain( d ) { + if ( c != d->cpupool ) + continue; for_each_vcpu( d, p ) { if ( EDOM_INFO(p)->weight ) @@ -1359,7 +1408,7 @@ static int sedf_adjust_weights(struct xen_domctl_scheduler_op *cmd) /* set or fetch domain scheduling parameters */ -static int sedf_adjust(struct domain *p, struct xen_domctl_scheduler_op *op) +static int sedf_adjust(struct scheduler *ops, struct domain *p, struct xen_domctl_scheduler_op *op) { struct vcpu *v; int rc; @@ -1369,9 +1418,6 @@ static int sedf_adjust(struct domain *p, struct xen_domctl_scheduler_op *op) p->domain_id, op->u.sedf.period, op->u.sedf.slice, op->u.sedf.latency, (op->u.sedf.extratime)?"yes":"no"); - if ( !p->vcpu ) - return -EINVAL; - if ( op->cmd == XEN_DOMCTL_SCHEDOP_putinfo ) { /* Check for sane parameters. */ @@ -1421,7 +1467,7 @@ static int sedf_adjust(struct domain *p, struct xen_domctl_scheduler_op *op) } } - rc = sedf_adjust_weights(op); + rc = sedf_adjust_weights(p->cpupool, op); if ( rc ) return rc; @@ -1449,7 +1495,7 @@ static int sedf_adjust(struct domain *p, struct xen_domctl_scheduler_op *op) return 0; } -const struct scheduler sched_sedf_def = { +struct scheduler sched_sedf_def = { .name = "Simple EDF Scheduler", .opt_name = "sedf", .sched_id = XEN_SCHEDULER_SEDF, @@ -1457,9 +1503,15 @@ const struct scheduler sched_sedf_def = { .init_domain = sedf_init_domain, .destroy_domain = sedf_destroy_domain, - .init_vcpu = sedf_init_vcpu, .destroy_vcpu = sedf_destroy_vcpu, + .alloc_vdata = sedf_alloc_vdata, + .free_vdata = sedf_free_vdata, + .alloc_pdata = sedf_alloc_pdata, + .free_pdata = sedf_free_pdata, + .alloc_domdata = sedf_alloc_domdata, + .free_domdata = sedf_free_domdata, + .do_schedule = sedf_do_schedule, .pick_cpu = sedf_pick_cpu, .dump_cpu_state = sedf_dump_cpu_state, |