aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--xen/common/sched_credit2.c36
-rw-r--r--xen/common/schedule.c6
-rw-r--r--xen/include/xen/sched-if.h2
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 *,