diff options
-rw-r--r-- | xen/common/sched_credit2.c | 36 | ||||
-rw-r--r-- | xen/common/schedule.c | 6 | ||||
-rw-r--r-- | xen/include/xen/sched-if.h | 2 |
3 files changed, 24 insertions, 20 deletions
diff --git a/xen/common/sched_credit2.c b/xen/common/sched_credit2.c index 792d662575..517ec8c49c 100644 --- a/xen/common/sched_credit2.c +++ b/xen/common/sched_credit2.c @@ -1352,32 +1352,29 @@ out: static int csched_cpu_pick(const struct scheduler *ops, struct vcpu *vc) { - struct csched_vcpu * const svc = CSCHED_VCPU(vc); int new_cpu; - /* The scheduler interface doesn't have an explicit mechanism to - * involve the choosable scheduler in the migrate process, so we - * infer that a change may happen by the call to cpu_pick, and - * remove it from the old runqueue while the lock for the old - * runqueue is held. It can't be actively waiting to run. It - * will be added to the new runqueue when it next wakes. - * - * If we want to be able to call pick() separately, we need to add - * a mechansim to remove a vcpu from an old processor / runqueue - * before releasing the lock. */ - BUG_ON(__vcpu_on_runq(svc)); - new_cpu = choose_cpu(ops, vc); - /* If we're suggesting moving to a different runqueue, remove it - * from the old runqueue while we have the lock. It will be added - * to the new one when it wakes. */ - if ( svc->rqd != NULL - && RQD(ops, new_cpu) != svc->rqd ) - runq_deassign(ops, vc); return new_cpu; } +static void +csched_vcpu_migrate( + const struct scheduler *ops, struct vcpu *vc, unsigned int new_cpu) +{ + struct csched_vcpu * const svc = CSCHED_VCPU(vc); + struct csched_runqueue_data *trqd; + + /* Check if new_cpu is valid */ + BUG_ON(!cpu_isset(new_cpu, CSCHED_PRIV(ops)->initialized)); + + trqd = RQD(ops, new_cpu); + + if ( trqd != svc->rqd ) + migrate(ops, svc, trqd, NOW()); +} + static int csched_dom_cntl( const struct scheduler *ops, @@ -2121,6 +2118,7 @@ const struct scheduler sched_credit2_def = { .adjust = csched_dom_cntl, .pick_cpu = csched_cpu_pick, + .migrate = csched_vcpu_migrate, .do_schedule = csched_schedule, .context_saved = csched_context_saved, diff --git a/xen/common/schedule.c b/xen/common/schedule.c index dde615ee66..aa8bdd5969 100644 --- a/xen/common/schedule.c +++ b/xen/common/schedule.c @@ -489,7 +489,11 @@ static void vcpu_migrate(struct vcpu *v) * Switch to new CPU, then unlock new and old CPU. This is safe because * the lock pointer cant' change while the current lock is held. */ - v->processor = new_cpu; + if ( VCPU2OP(v)->migrate ) + SCHED_OP(VCPU2OP(v), migrate, v, new_cpu); + else + v->processor = new_cpu; + if ( old_lock != new_lock ) spin_unlock(new_lock); diff --git a/xen/include/xen/sched-if.h b/xen/include/xen/sched-if.h index 486b9fd704..a03ceb1552 100644 --- a/xen/include/xen/sched-if.h +++ b/xen/include/xen/sched-if.h @@ -170,6 +170,8 @@ struct scheduler { bool_t tasklet_work_scheduled); int (*pick_cpu) (const struct scheduler *, struct vcpu *); + void (*migrate) (const struct scheduler *, struct vcpu *, + unsigned int); int (*adjust) (const struct scheduler *, struct domain *, struct xen_domctl_scheduler_op *); int (*adjust_global) (const struct scheduler *, |