|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 03/60] xen/sched: let sched_switch_sched() return new lock address
Instead of setting the scheduler percpu lock address in each of the
switch_sched instances of the different schedulers do that in
schedule_cpu_switch() which is the single caller of that function.
For that purpose let sched_switch_sched() just return the new lock
address.
This allows to set the new struct scheduler and struct schedule_data
values in the percpu area in schedule_cpu_switch() instead of the
schedulers, too.
Signed-off-by: Juergen Gross <jgross@xxxxxxxx>
---
xen/common/sched_arinc653.c | 14 ++------------
xen/common/sched_credit.c | 13 ++-----------
xen/common/sched_credit2.c | 15 +++------------
xen/common/sched_null.c | 16 ++++------------
xen/common/sched_rt.c | 12 ++----------
xen/common/schedule.c | 18 +++++++++++++++---
xen/include/xen/sched-if.h | 9 +++++----
7 files changed, 33 insertions(+), 64 deletions(-)
diff --git a/xen/common/sched_arinc653.c b/xen/common/sched_arinc653.c
index a4c6d00b81..72b988ea5f 100644
--- a/xen/common/sched_arinc653.c
+++ b/xen/common/sched_arinc653.c
@@ -630,7 +630,7 @@ a653sched_pick_cpu(const struct scheduler *ops, struct vcpu
*vc)
* @param pdata scheduler specific PCPU data (we don't have any)
* @param vdata scheduler specific VCPU data of the idle vcpu
*/
-static void
+static spinlock_t *
a653_switch_sched(struct scheduler *new_ops, unsigned int cpu,
void *pdata, void *vdata)
{
@@ -641,17 +641,7 @@ a653_switch_sched(struct scheduler *new_ops, unsigned int
cpu,
idle_vcpu[cpu]->sched_priv = vdata;
- per_cpu(scheduler, cpu) = new_ops;
- per_cpu(schedule_data, cpu).sched_priv = NULL; /* no pdata */
-
- /*
- * (Re?)route the lock to its default location. We actually do not use
- * it, but if we leave it pointing to where it does now (i.e., the
- * runqueue lock for this PCPU in the default scheduler), we'd be
- * causing unnecessary contention on that lock (in cases where it is
- * shared among multiple PCPUs, like in Credit2 and RTDS).
- */
- sd->schedule_lock = &sd->_lock;
+ return &sd->_lock;
}
/**
diff --git a/xen/common/sched_credit.c b/xen/common/sched_credit.c
index 7b7facbace..621c408ed0 100644
--- a/xen/common/sched_credit.c
+++ b/xen/common/sched_credit.c
@@ -631,7 +631,7 @@ csched_init_pdata(const struct scheduler *ops, void *pdata,
int cpu)
}
/* Change the scheduler of cpu to us (Credit). */
-static void
+static spinlock_t *
csched_switch_sched(struct scheduler *new_ops, unsigned int cpu,
void *pdata, void *vdata)
{
@@ -653,16 +653,7 @@ csched_switch_sched(struct scheduler *new_ops, unsigned
int cpu,
init_pdata(prv, pdata, cpu);
spin_unlock(&prv->lock);
- per_cpu(scheduler, cpu) = new_ops;
- per_cpu(schedule_data, cpu).sched_priv = pdata;
-
- /*
- * (Re?)route the lock to the per pCPU lock as /last/ thing. In fact,
- * if it is free (and it can be) we want that anyone that manages
- * taking it, finds all the initializations we've done above in place.
- */
- smp_mb();
- sd->schedule_lock = &sd->_lock;
+ return &sd->_lock;
}
#ifndef NDEBUG
diff --git a/xen/common/sched_credit2.c b/xen/common/sched_credit2.c
index 9c1c3b4e08..8e4381d8a7 100644
--- a/xen/common/sched_credit2.c
+++ b/xen/common/sched_credit2.c
@@ -3855,7 +3855,7 @@ csched2_init_pdata(const struct scheduler *ops, void
*pdata, int cpu)
}
/* Change the scheduler of cpu to us (Credit2). */
-static void
+static spinlock_t *
csched2_switch_sched(struct scheduler *new_ops, unsigned int cpu,
void *pdata, void *vdata)
{
@@ -3888,18 +3888,9 @@ csched2_switch_sched(struct scheduler *new_ops, unsigned
int cpu,
*/
ASSERT(per_cpu(schedule_data, cpu).schedule_lock != &prv->rqd[rqi].lock);
- per_cpu(scheduler, cpu) = new_ops;
- per_cpu(schedule_data, cpu).sched_priv = pdata;
-
- /*
- * (Re?)route the lock to the per pCPU lock as /last/ thing. In fact,
- * if it is free (and it can be) we want that anyone that manages
- * taking it, find all the initializations we've done above in place.
- */
- smp_mb();
- per_cpu(schedule_data, cpu).schedule_lock = &prv->rqd[rqi].lock;
-
write_unlock(&prv->lock);
+
+ return &prv->rqd[rqi].lock;
}
static void
diff --git a/xen/common/sched_null.c b/xen/common/sched_null.c
index a59dbb2692..10427b37ab 100644
--- a/xen/common/sched_null.c
+++ b/xen/common/sched_null.c
@@ -381,8 +381,9 @@ static void vcpu_deassign(struct null_private *prv, struct
vcpu *v,
}
/* Change the scheduler of cpu to us (null). */
-static void null_switch_sched(struct scheduler *new_ops, unsigned int cpu,
- void *pdata, void *vdata)
+static spinlock_t *null_switch_sched(struct scheduler *new_ops,
+ unsigned int cpu,
+ void *pdata, void *vdata)
{
struct schedule_data *sd = &per_cpu(schedule_data, cpu);
struct null_private *prv = null_priv(new_ops);
@@ -401,16 +402,7 @@ static void null_switch_sched(struct scheduler *new_ops,
unsigned int cpu,
init_pdata(prv, cpu);
- per_cpu(scheduler, cpu) = new_ops;
- per_cpu(schedule_data, cpu).sched_priv = pdata;
-
- /*
- * (Re?)route the lock to the per pCPU lock as /last/ thing. In fact,
- * if it is free (and it can be) we want that anyone that manages
- * taking it, finds all the initializations we've done above in place.
- */
- smp_mb();
- sd->schedule_lock = &sd->_lock;
+ return &sd->_lock;
}
static void null_vcpu_insert(const struct scheduler *ops, struct vcpu *v)
diff --git a/xen/common/sched_rt.c b/xen/common/sched_rt.c
index f1b81f0373..0acfc3d702 100644
--- a/xen/common/sched_rt.c
+++ b/xen/common/sched_rt.c
@@ -729,7 +729,7 @@ rt_init_pdata(const struct scheduler *ops, void *pdata, int
cpu)
}
/* Change the scheduler of cpu to us (RTDS). */
-static void
+static spinlock_t *
rt_switch_sched(struct scheduler *new_ops, unsigned int cpu,
void *pdata, void *vdata)
{
@@ -761,16 +761,8 @@ rt_switch_sched(struct scheduler *new_ops, unsigned int
cpu,
}
idle_vcpu[cpu]->sched_priv = vdata;
- per_cpu(scheduler, cpu) = new_ops;
- per_cpu(schedule_data, cpu).sched_priv = NULL; /* no pdata */
- /*
- * (Re?)route the lock to the per pCPU lock as /last/ thing. In fact,
- * if it is free (and it can be) we want that anyone that manages
- * taking it, find all the initializations we've done above in place.
- */
- smp_mb();
- per_cpu(schedule_data, cpu).schedule_lock = &prv->lock;
+ return &prv->lock;
}
static void
diff --git a/xen/common/schedule.c b/xen/common/schedule.c
index 4da970c543..6dc96b3cd4 100644
--- a/xen/common/schedule.c
+++ b/xen/common/schedule.c
@@ -1812,7 +1812,8 @@ int schedule_cpu_switch(unsigned int cpu, struct cpupool
*c)
struct scheduler *old_ops = per_cpu(scheduler, cpu);
struct scheduler *new_ops = (c == NULL) ? &ops : c->sched;
struct cpupool *old_pool = per_cpu(cpupool, cpu);
- spinlock_t * old_lock;
+ struct schedule_data *sd = &per_cpu(schedule_data, cpu);
+ spinlock_t *old_lock, *new_lock;
/*
* pCPUs only move from a valid cpupool to free (i.e., out of any pool),
@@ -1870,8 +1871,19 @@ int schedule_cpu_switch(unsigned int cpu, struct cpupool
*c)
old_lock = pcpu_schedule_lock_irq(cpu);
vpriv_old = idle->sched_priv;
- ppriv_old = per_cpu(schedule_data, cpu).sched_priv;
- sched_switch_sched(new_ops, cpu, ppriv, vpriv);
+ ppriv_old = sd->sched_priv;
+ new_lock = sched_switch_sched(new_ops, cpu, ppriv, vpriv);
+
+ per_cpu(scheduler, cpu) = new_ops;
+ sd->sched_priv = ppriv;
+
+ /*
+ * (Re?)route the lock to the per pCPU lock as /last/ thing. In fact,
+ * if it is free (and it can be) we want that anyone that manages
+ * taking it, finds all the initializations we've done above in place.
+ */
+ smp_mb();
+ sd->schedule_lock = new_lock;
/* _Not_ pcpu_schedule_unlock(): schedule_lock may have changed! */
spin_unlock_irq(old_lock);
diff --git a/xen/include/xen/sched-if.h b/xen/include/xen/sched-if.h
index b3c3e189d9..b8e2b2e49e 100644
--- a/xen/include/xen/sched-if.h
+++ b/xen/include/xen/sched-if.h
@@ -153,7 +153,7 @@ struct scheduler {
/* Idempotent. */
void (*free_domdata) (const struct scheduler *, void *);
- void (*switch_sched) (struct scheduler *, unsigned int,
+ spinlock_t * (*switch_sched) (struct scheduler *, unsigned int,
void *, void *);
/* Activate / deactivate vcpus in a cpu pool */
@@ -195,10 +195,11 @@ static inline void sched_deinit(struct scheduler *s)
s->deinit(s);
}
-static inline void sched_switch_sched(struct scheduler *s, unsigned int cpu,
- void *pdata, void *vdata)
+static inline spinlock_t *sched_switch_sched(struct scheduler *s,
+ unsigned int cpu,
+ void *pdata, void *vdata)
{
- s->switch_sched(s, cpu, pdata, vdata);
+ return s->switch_sched(s, cpu, pdata, vdata);
}
static inline void sched_dump_settings(const struct scheduler *s)
--
2.16.4
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |