From: Juergen Gross <jgross@suse.com>
To: xen-devel@lists.xenproject.org
Cc: Juergen Gross <jgross@suse.com>,
George Dunlap <george.dunlap@citrix.com>,
Dario Faggioli <dfaggioli@suse.com>
Subject: [PATCH v3 1/8] xen/cpupool: support moving domain between cpupools with different granularity
Date: Wed, 9 Dec 2020 17:09:49 +0100 [thread overview]
Message-ID: <20201209160956.32456-2-jgross@suse.com> (raw)
In-Reply-To: <20201209160956.32456-1-jgross@suse.com>
When moving a domain between cpupools with different scheduling
granularity the sched_units of the domain need to be adjusted.
Do that by allocating new sched_units and throwing away the old ones
in sched_move_domain().
Signed-off-by: Juergen Gross <jgross@suse.com>
---
xen/common/sched/core.c | 121 ++++++++++++++++++++++++++++++----------
1 file changed, 90 insertions(+), 31 deletions(-)
diff --git a/xen/common/sched/core.c b/xen/common/sched/core.c
index a429fc7640..2a61c879b3 100644
--- a/xen/common/sched/core.c
+++ b/xen/common/sched/core.c
@@ -613,17 +613,45 @@ static void sched_move_irqs(const struct sched_unit *unit)
vcpu_move_irqs(v);
}
+/*
+ * Move a domain from one cpupool to another.
+ *
+ * A domain with any vcpu having temporary affinity settings will be denied
+ * to move. Hard and soft affinities will be reset.
+ *
+ * In order to support cpupools with different scheduling granularities all
+ * scheduling units are replaced by new ones.
+ *
+ * The complete move is done in the following steps:
+ * - check prerequisites (no vcpu with temporary affinities)
+ * - allocate all new data structures (scheduler specific domain data, unit
+ * memory, scheduler specific unit data)
+ * - pause domain
+ * - temporarily move all (old) units to the same scheduling resource (this
+ * makes the final resource assignment easier in case the new cpupool has
+ * a larger granularity than the old one, as the scheduling locks for all
+ * vcpus must be held for that operation)
+ * - remove old units from scheduling
+ * - set new cpupool and scheduler domain data pointers in struct domain
+ * - switch all vcpus to new units, still assigned to the old scheduling
+ * resource
+ * - migrate all new units to scheduling resources of the new cpupool
+ * - unpause the domain
+ * - free the old memory (scheduler specific domain data, unit memory,
+ * scheduler specific unit data)
+ */
int sched_move_domain(struct domain *d, struct cpupool *c)
{
struct vcpu *v;
- struct sched_unit *unit;
+ struct sched_unit *unit, *old_unit;
+ struct sched_unit *new_units = NULL, *old_units;
+ struct sched_unit **unit_ptr = &new_units;
unsigned int new_p, unit_idx;
- void **unit_priv;
void *domdata;
- void *unitdata;
- struct scheduler *old_ops;
+ struct scheduler *old_ops = dom_scheduler(d);
void *old_domdata;
unsigned int gran = cpupool_get_granularity(c);
+ unsigned int n_units = DIV_ROUND_UP(d->max_vcpus, gran);
int ret = 0;
for_each_vcpu ( d, v )
@@ -641,53 +669,78 @@ int sched_move_domain(struct domain *d, struct cpupool *c)
goto out;
}
- unit_priv = xzalloc_array(void *, DIV_ROUND_UP(d->max_vcpus, gran));
- if ( unit_priv == NULL )
+ for ( unit_idx = 0; unit_idx < n_units; unit_idx++ )
{
- sched_free_domdata(c->sched, domdata);
- ret = -ENOMEM;
- goto out;
- }
+ unit = sched_alloc_unit_mem();
+ if ( unit )
+ {
+ /* Initialize unit for sched_alloc_udata() to work. */
+ unit->domain = d;
+ unit->unit_id = unit_idx * gran;
+ unit->vcpu_list = d->vcpu[unit->unit_id];
+ unit->priv = sched_alloc_udata(c->sched, unit, domdata);
+ *unit_ptr = unit;
+ }
- unit_idx = 0;
- for_each_sched_unit ( d, unit )
- {
- unit_priv[unit_idx] = sched_alloc_udata(c->sched, unit, domdata);
- if ( unit_priv[unit_idx] == NULL )
+ if ( !unit || !unit->priv )
{
- for ( unit_idx = 0; unit_priv[unit_idx]; unit_idx++ )
- sched_free_udata(c->sched, unit_priv[unit_idx]);
- xfree(unit_priv);
- sched_free_domdata(c->sched, domdata);
+ old_units = new_units;
+ old_domdata = domdata;
ret = -ENOMEM;
- goto out;
+ goto out_free;
}
- unit_idx++;
+
+ unit_ptr = &unit->next_in_list;
}
domain_pause(d);
- old_ops = dom_scheduler(d);
old_domdata = d->sched_priv;
+ new_p = cpumask_first(d->cpupool->cpu_valid);
for_each_sched_unit ( d, unit )
{
+ spinlock_t *lock;
+
+ /*
+ * Temporarily move all units to same processor to make locking
+ * easier when moving the new units to the new processors.
+ */
+ lock = unit_schedule_lock_irq(unit);
+ sched_set_res(unit, get_sched_res(new_p));
+ spin_unlock_irq(lock);
+
sched_remove_unit(old_ops, unit);
}
+ old_units = d->sched_unit_list;
+
d->cpupool = c;
d->sched_priv = domdata;
+ unit = new_units;
+ for_each_vcpu ( d, v )
+ {
+ old_unit = v->sched_unit;
+ if ( unit->unit_id + gran == v->vcpu_id )
+ unit = unit->next_in_list;
+
+ unit->state_entry_time = old_unit->state_entry_time;
+ unit->runstate_cnt[v->runstate.state]++;
+ /* Temporarily use old resource assignment */
+ unit->res = get_sched_res(new_p);
+
+ v->sched_unit = unit;
+ }
+
+ d->sched_unit_list = new_units;
+
new_p = cpumask_first(c->cpu_valid);
- unit_idx = 0;
for_each_sched_unit ( d, unit )
{
spinlock_t *lock;
unsigned int unit_p = new_p;
- unitdata = unit->priv;
- unit->priv = unit_priv[unit_idx];
-
for_each_sched_unit_vcpu ( unit, v )
{
migrate_timer(&v->periodic_timer, new_p);
@@ -713,8 +766,6 @@ int sched_move_domain(struct domain *d, struct cpupool *c)
sched_insert_unit(c->sched, unit);
- sched_free_udata(old_ops, unitdata);
-
unit_idx++;
}
@@ -722,11 +773,19 @@ int sched_move_domain(struct domain *d, struct cpupool *c)
domain_unpause(d);
- sched_free_domdata(old_ops, old_domdata);
+ out_free:
+ for ( unit = old_units; unit; )
+ {
+ if ( unit->priv )
+ sched_free_udata(c->sched, unit->priv);
+ old_unit = unit;
+ unit = unit->next_in_list;
+ xfree(old_unit);
+ }
- xfree(unit_priv);
+ sched_free_domdata(old_ops, old_domdata);
-out:
+ out:
rcu_read_unlock(&sched_res_rculock);
return ret;
--
2.26.2
next prev parent reply other threads:[~2020-12-09 16:10 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-12-09 16:09 [PATCH v3 0/8] xen: support per-cpupool scheduling granularity Juergen Gross
2020-12-09 16:09 ` Juergen Gross [this message]
2020-12-16 17:52 ` [PATCH v3 1/8] xen/cpupool: support moving domain between cpupools with different granularity Dario Faggioli
2020-12-17 7:49 ` Jan Beulich
2020-12-17 7:54 ` Jürgen Groß
2020-12-09 16:09 ` [PATCH v3 2/8] xen/hypfs: switch write function handles to const Juergen Gross
2020-12-16 16:08 ` Jan Beulich
2020-12-16 16:17 ` Jürgen Groß
2020-12-16 16:35 ` Jan Beulich
2020-12-09 16:09 ` [PATCH v3 3/8] xen/hypfs: add new enter() and exit() per node callbacks Juergen Gross
2020-12-16 16:16 ` Jan Beulich
2020-12-16 16:24 ` Jürgen Groß
2020-12-16 16:36 ` Jan Beulich
2020-12-16 17:12 ` Jürgen Groß
2020-12-09 16:09 ` [PATCH v3 4/8] xen/hypfs: support dynamic hypfs nodes Juergen Gross
2020-12-17 11:01 ` Jan Beulich
2020-12-17 11:24 ` Jürgen Groß
2020-12-09 16:09 ` [PATCH v3 5/8] xen/hypfs: add support for id-based dynamic directories Juergen Gross
2020-12-17 11:28 ` Jan Beulich
2020-12-17 11:32 ` Jürgen Groß
2020-12-17 12:14 ` Jan Beulich
2020-12-18 8:57 ` Jürgen Groß
2020-12-18 9:09 ` Jan Beulich
2020-12-18 12:41 ` Jürgen Groß
2020-12-21 8:26 ` Jan Beulich
2021-01-18 7:25 ` Jürgen Groß
2021-01-18 7:59 ` Jan Beulich
2020-12-09 16:09 ` [PATCH v3 6/8] xen/cpupool: add cpupool directories Juergen Gross
2020-12-17 15:54 ` Jan Beulich
2020-12-17 16:10 ` Dario Faggioli
2020-12-09 16:09 ` [PATCH v3 7/8] xen/cpupool: add scheduling granularity entry to cpupool entries Juergen Gross
2020-12-17 15:57 ` Jan Beulich
2020-12-09 16:09 ` [PATCH v3 8/8] xen/cpupool: make per-cpupool sched-gran hypfs node writable Juergen Gross
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=20201209160956.32456-2-jgross@suse.com \
--to=jgross@suse.com \
--cc=dfaggioli@suse.com \
--cc=george.dunlap@citrix.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).