From: Dario Faggioli <dario.faggioli@citrix.com>
To: xen-devel@lists.xenproject.org
Cc: Juergen Gross <jgross@suse.com>,
George Dunlap <george.dunlap@eu.citrix.com>,
Jan Beulich <JBeulich@suse.com>
Subject: [PATCH v3 3/6] xen: sched: clarify use cases of schedule_cpu_switch()
Date: Fri, 30 Oct 2015 00:04:28 +0100 [thread overview]
Message-ID: <20151029230427.25219.2409.stgit@Solace.station> (raw)
In-Reply-To: <20151029225158.25219.4625.stgit@Solace.station>
schedule_cpu_switch() is meant to be only used for moving
pCPUs from a cpupool to no cpupool, and from there back
to a cpupool, *not* to move them directly from one cpupool
to another.
This is something that is reflected in the way it is
implemented, and should be kept in mind when looking at
it. However, that is not that clear, by just the look of
it.
Make it more evident by:
- adding commentary and ASSERT()s;
- update the cpupool per-CPU variable (mapping pCPUs to
pools) directly in schedule_cpu_switch(), rather than
in various places in cpupool.c.
Signed-off-by: Dario Faggioli <dario.faggioli@citrix.com>
Acked-by: Juergen Gross <jgross@suse.com>
---
Cc: George Dunlap <george.dunlap@eu.citrix.com>
Cc: Jan Beulich <JBeulich@suse.com>
---
Changes from v2:
* updating of per_cpu(cpupool, cpu) is now done in
schedule_cpu_switch(), as suggested during review.
Changes from v1:
* new patch, was not there in v1;
---
xen/common/cpupool.c | 7 -------
xen/common/schedule.c | 31 ++++++++++++++++++++++++++++++-
2 files changed, 30 insertions(+), 8 deletions(-)
diff --git a/xen/common/cpupool.c b/xen/common/cpupool.c
index e79850b..8e7b723 100644
--- a/xen/common/cpupool.c
+++ b/xen/common/cpupool.c
@@ -261,19 +261,13 @@ int cpupool_move_domain(struct domain *d, struct cpupool *c)
static int cpupool_assign_cpu_locked(struct cpupool *c, unsigned int cpu)
{
int ret;
- struct cpupool *old;
struct domain *d;
if ( (cpupool_moving_cpu == cpu) && (c != cpupool_cpu_moving) )
return -EBUSY;
- old = per_cpu(cpupool, cpu);
- per_cpu(cpupool, cpu) = c;
ret = schedule_cpu_switch(cpu, c);
if ( ret )
- {
- per_cpu(cpupool, cpu) = old;
return ret;
- }
cpumask_clear_cpu(cpu, &cpupool_free_cpus);
if (cpupool_moving_cpu == cpu)
@@ -326,7 +320,6 @@ static long cpupool_unassign_cpu_helper(void *info)
cpumask_clear_cpu(cpu, &cpupool_free_cpus);
goto out;
}
- per_cpu(cpupool, cpu) = NULL;
cpupool_moving_cpu = -1;
cpupool_put(cpupool_cpu_moving);
cpupool_cpu_moving = NULL;
diff --git a/xen/common/schedule.c b/xen/common/schedule.c
index 80d6fb7..9f5e12b 100644
--- a/xen/common/schedule.c
+++ b/xen/common/schedule.c
@@ -1486,6 +1486,17 @@ void __init scheduler_init(void)
BUG();
}
+/*
+ * Move a pCPU outside of the influence of the scheduler of its current
+ * cpupool, or subject it to the scheduler of a new cpupool.
+ *
+ * For the pCPUs that are removed from their cpupool, their scheduler becomes
+ * &ops (the default scheduler, selected at boot, which also services the
+ * default cpupool). However, as these pCPUs are not really part of any pool,
+ * there won't be any scheduling event on them, not even from the default
+ * scheduler. Basically, they will just sit idle until they are explicitly
+ * added back to a cpupool.
+ */
int schedule_cpu_switch(unsigned int cpu, struct cpupool *c)
{
struct vcpu *idle;
@@ -1493,9 +1504,24 @@ int schedule_cpu_switch(unsigned int cpu, struct cpupool *c)
void *ppriv, *ppriv_old, *vpriv, *vpriv_old;
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);
+
+ /*
+ * pCPUs only move from a valid cpupool to free (i.e., out of any pool),
+ * or from free to a valid cpupool. In the former case (which happens when
+ * c is NULL), we want the CPU to have been marked as free already, as
+ * well as to not be valid for the source pool any longer, when we get to
+ * here. In the latter case (which happens when c is a valid cpupool), we
+ * want the CPU to still be marked as free, as well as to not yet be valid
+ * for the destination pool.
+ */
+ ASSERT(c != old_pool && (c != NULL || old_pool != NULL));
+ ASSERT(cpumask_test_cpu(cpu, &cpupool_free_cpus));
+ ASSERT((c == NULL && !cpumask_test_cpu(cpu, old_pool->cpu_valid)) ||
+ (c != NULL && !cpumask_test_cpu(cpu, c->cpu_valid)));
if ( old_ops == new_ops )
- return 0;
+ goto out;
idle = idle_vcpu[cpu];
ppriv = SCHED_OP(new_ops, alloc_pdata, cpu);
@@ -1523,6 +1549,9 @@ int schedule_cpu_switch(unsigned int cpu, struct cpupool *c)
SCHED_OP(old_ops, free_vdata, vpriv_old);
SCHED_OP(old_ops, free_pdata, ppriv_old, cpu);
+ out:
+ per_cpu(cpupool, cpu) = c;
+
return 0;
}
next prev parent reply other threads:[~2015-10-29 23:04 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-10-29 23:04 [PATCH v3 0/6] xen: sched: fix locking of {insert, remove}_vcpu() Dario Faggioli
2015-10-29 23:04 ` [PATCH v3 1/6] xen: sched: fix locking of remove_vcpu() in credit1 Dario Faggioli
2015-11-02 18:04 ` George Dunlap
2015-11-03 17:15 ` Dario Faggioli
2015-10-29 23:04 ` [PATCH v3 2/6] xen: sched: fix locking for insert_vcpu() in credit1 and RTDS Dario Faggioli
2015-10-30 23:00 ` Meng Xu
2015-11-02 8:03 ` Dario Faggioli
2015-11-02 14:45 ` Meng Xu
2015-11-04 14:12 ` Dario Faggioli
2015-11-04 15:01 ` Meng Xu
2015-11-04 15:52 ` Dario Faggioli
2015-11-05 3:55 ` Meng Xu
2015-10-29 23:04 ` Dario Faggioli [this message]
2015-10-29 23:59 ` [PATCH v3 3/6] xen: sched: clarify use cases of schedule_cpu_switch() Dario Faggioli
2015-10-30 4:33 ` Juergen Gross
2015-11-02 18:23 ` George Dunlap
2015-10-29 23:04 ` [PATCH v3 4/6] xen: sched: better handle (not) inserting idle vCPUs in runqueues Dario Faggioli
2015-10-29 23:04 ` [PATCH v3 5/6] xen: sched: get rid of the per domain vCPU list in RTDS Dario Faggioli
2015-11-02 18:57 ` George Dunlap
2015-10-29 23:04 ` [PATCH v3 6/6] xen: sched: get rid of the per domain vCPU list in Credit2 Dario Faggioli
2015-11-02 18:56 ` George Dunlap
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20151029230427.25219.2409.stgit@Solace.station \
--to=dario.faggioli@citrix.com \
--cc=JBeulich@suse.com \
--cc=george.dunlap@eu.citrix.com \
--cc=jgross@suse.com \
--cc=xen-devel@lists.xenproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.