All of lore.kernel.org
 help / color / mirror / Atom feed
* [Xen-devel] [PATCH v2 0/4] xen: sched: support vcpu hotplug/hotunplug in the 'null scheduler'
@ 2019-07-26  6:25 Dario Faggioli
  2019-07-26  6:25 ` [Xen-devel] [PATCH v2 1/4] xen: sched: refector code around vcpu_deassign() in null scheduler Dario Faggioli
                   ` (3 more replies)
  0 siblings, 4 replies; 10+ messages in thread
From: Dario Faggioli @ 2019-07-26  6:25 UTC (permalink / raw)
  To: xen-devel; +Cc: George Dunlap, Stefano Stabellini, Roger Pau Monne

Hello,

Here it is v2 of my series, about fixing vcpu off- and on-lining in the
null scheduler, recently reviewed by George.

v1 posting is here:
https://lists.xenproject.org/archives/html/xen-devel/2018-08/msg02182.html
Message-Id: <153515586506.7407.8908626058440527641.stgit@Palanthas.fritz.box>

Basically, it turned out, while discussing this patch:
https://lists.xenproject.org/archives/html/xen-devel/2018-01/msg00249.html

that the 'null scheduler' does not really support vcpu
hotplug/hotunplug. In fact, under some circumnstances, it is possible
that the vcpus which are actually offline, get assigned to a pcpu, while
one or more online vcpus, may be left in the wait list, and stay there
forever.

One of these circumnstances was, for instance, when the 'null scheduler'
was used within the PV-SHIM, but the problem is more general, and this
series fixes it.

I think I've addressed Goerge's comments. The most notable change is the
merge of what in v1 were patch 2 and patch 3. The resulting patch (i.e.,
patch 2 of this series) is the only one missing an Ack to go in.

The series is also available in git:
git://xenbits.xen.org/people/dariof/xen.git  rel/sched/null-fix-vcpu-hotplug-v2

Thanks and Regards,
Dario
---
Dario Faggioli (4):
      xen: sched: refector code around vcpu_deassign() in null scheduler
      xen: sched: deal with vCPUs being or becoming online or offline
      xen: sched: reassign vCPUs to pCPUs, when they come back online
      xen: sched: refactor the ASSERTs around vcpu_deassing()

 xen/common/sched_null.c |  210 ++++++++++++++++++++++++++++++++++-------------
 1 file changed, 152 insertions(+), 58 deletions(-)
--
Dario Faggioli, Ph.D
http://about.me/dario.faggioli
Virtualization Software Engineer
SUSE Labs, SUSE https://www.suse.com/
-------------------------------------------------------------------
<<This happens because _I_ choose it to happen!>> (Raistlin Majere)

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Xen-devel] [PATCH v2 1/4] xen: sched: refector code around vcpu_deassign() in null scheduler
  2019-07-26  6:25 [Xen-devel] [PATCH v2 0/4] xen: sched: support vcpu hotplug/hotunplug in the 'null scheduler' Dario Faggioli
@ 2019-07-26  6:25 ` Dario Faggioli
  2019-08-05 15:58   ` Jan Beulich
  2019-07-26  6:25 ` [Xen-devel] [PATCH v2 2/4] xen: sched: deal with vCPUs being or becoming online or offline Dario Faggioli
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 10+ messages in thread
From: Dario Faggioli @ 2019-07-26  6:25 UTC (permalink / raw)
  To: xen-devel; +Cc: George Dunlap

vcpu_deassign() is called only once (in _vcpu_remove()).

Let's consolidate the two functions into one.

No functional change intended.

Signed-off-by: Dario Faggioli <dfaggioli@suse.com>
Acked-by: George Dunlap <george.dunlap@citrix.com>
---
 xen/common/sched_null.c |   76 ++++++++++++++++++++++-------------------------
 1 file changed, 35 insertions(+), 41 deletions(-)

diff --git a/xen/common/sched_null.c b/xen/common/sched_null.c
index c02c1b9c1f..c47c1b5aae 100644
--- a/xen/common/sched_null.c
+++ b/xen/common/sched_null.c
@@ -358,9 +358,14 @@ static void vcpu_assign(struct null_private *prv, struct vcpu *v,
     }
 }
 
-static void vcpu_deassign(struct null_private *prv, struct vcpu *v,
-                          unsigned int cpu)
+static void vcpu_deassign(struct null_private *prv, struct vcpu *v)
 {
+    unsigned int bs;
+    unsigned int cpu = v->processor;
+    struct null_vcpu *wvc;
+
+    ASSERT(list_empty(&null_vcpu(v)->waitq_elem));
+
     per_cpu(npc, cpu).vcpu = NULL;
     cpumask_set_cpu(cpu, &prv->cpus_free);
 
@@ -377,6 +382,32 @@ static void vcpu_deassign(struct null_private *prv, struct vcpu *v,
         d.cpu = cpu;
         __trace_var(TRC_SNULL_VCPU_DEASSIGN, 1, sizeof(d), &d);
     }
+
+    spin_lock(&prv->waitq_lock);
+
+    /*
+     * If v is assigned to a pCPU, let's see if there is someone waiting,
+     * suitable to be assigned to it (prioritizing vcpus that have
+     * soft-affinity with cpu).
+     */
+    for_each_affinity_balance_step( bs )
+    {
+        list_for_each_entry( wvc, &prv->waitq, waitq_elem )
+        {
+            if ( bs == BALANCE_SOFT_AFFINITY && !has_soft_affinity(wvc->vcpu) )
+                continue;
+
+            if ( vcpu_check_affinity(wvc->vcpu, cpu, bs) )
+            {
+                list_del_init(&wvc->waitq_elem);
+                vcpu_assign(prv, wvc->vcpu, cpu);
+                cpu_raise_softirq(cpu, SCHEDULE_SOFTIRQ);
+                spin_unlock(&prv->waitq_lock);
+                return;
+            }
+        }
+    }
+    spin_unlock(&prv->waitq_lock);
 }
 
 /* Change the scheduler of cpu to us (null). */
@@ -459,43 +490,6 @@ static void null_vcpu_insert(const struct scheduler *ops, struct vcpu *v)
     SCHED_STAT_CRANK(vcpu_insert);
 }
 
-static void _vcpu_remove(struct null_private *prv, struct vcpu *v)
-{
-    unsigned int bs;
-    unsigned int cpu = v->processor;
-    struct null_vcpu *wvc;
-
-    ASSERT(list_empty(&null_vcpu(v)->waitq_elem));
-
-    vcpu_deassign(prv, v, cpu);
-
-    spin_lock(&prv->waitq_lock);
-
-    /*
-     * If v is assigned to a pCPU, let's see if there is someone waiting,
-     * suitable to be assigned to it (prioritizing vcpus that have
-     * soft-affinity with cpu).
-     */
-    for_each_affinity_balance_step( bs )
-    {
-        list_for_each_entry( wvc, &prv->waitq, waitq_elem )
-        {
-            if ( bs == BALANCE_SOFT_AFFINITY && !has_soft_affinity(wvc->vcpu) )
-                continue;
-
-            if ( vcpu_check_affinity(wvc->vcpu, cpu, bs) )
-            {
-                list_del_init(&wvc->waitq_elem);
-                vcpu_assign(prv, wvc->vcpu, cpu);
-                cpu_raise_softirq(cpu, SCHEDULE_SOFTIRQ);
-                spin_unlock(&prv->waitq_lock);
-                return;
-            }
-        }
-    }
-    spin_unlock(&prv->waitq_lock);
-}
-
 static void null_vcpu_remove(const struct scheduler *ops, struct vcpu *v)
 {
     struct null_private *prv = null_priv(ops);
@@ -519,7 +513,7 @@ static void null_vcpu_remove(const struct scheduler *ops, struct vcpu *v)
     ASSERT(per_cpu(npc, v->processor).vcpu == v);
     ASSERT(!cpumask_test_cpu(v->processor, &prv->cpus_free));
 
-    _vcpu_remove(prv, v);
+    vcpu_deassign(prv, v);
 
  out:
     vcpu_schedule_unlock_irq(lock, v);
@@ -605,7 +599,7 @@ static void null_vcpu_migrate(const struct scheduler *ops, struct vcpu *v,
      */
     if ( likely(list_empty(&nvc->waitq_elem)) )
     {
-        _vcpu_remove(prv, v);
+        vcpu_deassign(prv, v);
         SCHED_STAT_CRANK(migrate_running);
     }
     else


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Xen-devel] [PATCH v2 2/4] xen: sched: deal with vCPUs being or becoming online or offline
  2019-07-26  6:25 [Xen-devel] [PATCH v2 0/4] xen: sched: support vcpu hotplug/hotunplug in the 'null scheduler' Dario Faggioli
  2019-07-26  6:25 ` [Xen-devel] [PATCH v2 1/4] xen: sched: refector code around vcpu_deassign() in null scheduler Dario Faggioli
@ 2019-07-26  6:25 ` Dario Faggioli
  2019-08-05 10:48   ` George Dunlap
  2019-07-26  6:26 ` [Xen-devel] [PATCH v2 3/4] xen: sched: reassign vCPUs to pCPUs, when they come back online Dario Faggioli
  2019-07-26  6:26 ` [Xen-devel] [PATCH v2 4/4] xen: sched: refactor the ASSERTs around vcpu_deassing() Dario Faggioli
  3 siblings, 1 reply; 10+ messages in thread
From: Dario Faggioli @ 2019-07-26  6:25 UTC (permalink / raw)
  To: xen-devel; +Cc: George Dunlap, Stefano Stabellini, Roger Pau Monne

If a vCPU is, or is going, offline we want it to be neither
assigned to a pCPU, nor in the wait list, so:
- if an offline vcpu is inserted (or migrated) it must not
  go on a pCPU, nor in the wait list;
- if an offline vcpu is removed, we are sure that it is
  neither on a pCPU nor in the wait list already, so we
  should just bail, avoiding doing any further action;
- if a vCPU goes offline we need to remove it either from
  its pCPU or from the wait list.

Signed-off-by: Dario Faggioli <dfaggioli@suse.com>
---
Cc: George Dunlap <george.dunlap@eu.citrix.com>
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Roger Pau Monne <roger.pau@citrix.com>
---
Changes from v1:
* improved wording in changelog and comments
* this patch is the result of the merge of patches 2 and 3 from v1
---
 xen/common/sched_null.c |   80 +++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 66 insertions(+), 14 deletions(-)

diff --git a/xen/common/sched_null.c b/xen/common/sched_null.c
index c47c1b5aae..10e96f21dd 100644
--- a/xen/common/sched_null.c
+++ b/xen/common/sched_null.c
@@ -339,6 +339,8 @@ static unsigned int pick_cpu(struct null_private *prv, struct vcpu *v)
 static void vcpu_assign(struct null_private *prv, struct vcpu *v,
                         unsigned int cpu)
 {
+    ASSERT(is_vcpu_online(v));
+
     per_cpu(npc, cpu).vcpu = v;
     v->processor = cpu;
     cpumask_clear_cpu(cpu, &prv->cpus_free);
@@ -358,7 +360,8 @@ static void vcpu_assign(struct null_private *prv, struct vcpu *v,
     }
 }
 
-static void vcpu_deassign(struct null_private *prv, struct vcpu *v)
+/* Returns true if a cpu was tickled */
+static bool vcpu_deassign(struct null_private *prv, struct vcpu *v)
 {
     unsigned int bs;
     unsigned int cpu = v->processor;
@@ -403,11 +406,13 @@ static void vcpu_deassign(struct null_private *prv, struct vcpu *v)
                 vcpu_assign(prv, wvc->vcpu, cpu);
                 cpu_raise_softirq(cpu, SCHEDULE_SOFTIRQ);
                 spin_unlock(&prv->waitq_lock);
-                return;
+                return true;
             }
         }
     }
     spin_unlock(&prv->waitq_lock);
+
+    return false;
 }
 
 /* Change the scheduler of cpu to us (null). */
@@ -445,8 +450,14 @@ static void null_vcpu_insert(const struct scheduler *ops, struct vcpu *v)
     ASSERT(!is_idle_vcpu(v));
 
     lock = vcpu_schedule_lock_irq(v);
- retry:
 
+    if ( unlikely(!is_vcpu_online(v)) )
+    {
+        vcpu_schedule_unlock_irq(lock, v);
+        return;
+    }
+
+ retry:
     cpu = v->processor = pick_cpu(prv, v);
 
     spin_unlock(lock);
@@ -500,6 +511,14 @@ static void null_vcpu_remove(const struct scheduler *ops, struct vcpu *v)
 
     lock = vcpu_schedule_lock_irq(v);
 
+    /* If offline, the vcpu shouldn't be assigned, nor in the waitqueue */
+    if ( unlikely(!is_vcpu_online(v)) )
+    {
+        ASSERT(per_cpu(npc, v->processor).vcpu != v);
+        ASSERT(list_empty(&nvc->waitq_elem));
+        goto out;
+    }
+
     /* If v is in waitqueue, just get it out of there and bail */
     if ( unlikely(!list_empty(&nvc->waitq_elem)) )
     {
@@ -549,11 +568,33 @@ static void null_vcpu_wake(const struct scheduler *ops, struct vcpu *v)
 
 static void null_vcpu_sleep(const struct scheduler *ops, struct vcpu *v)
 {
+    struct null_private *prv = null_priv(ops);
+    unsigned int cpu = v->processor;
+    bool tickled = false;
+
     ASSERT(!is_idle_vcpu(v));
 
+    /* 
+     * Check if the vcpu is in the process of being offlined. if yes,
+     * we need to remove it from either its pCPU or the waitqueue.
+     */
+    if ( unlikely(!is_vcpu_online(v)) )
+    {
+        struct null_vcpu *nvc = null_vcpu(v);
+
+        if ( unlikely(!list_empty(&nvc->waitq_elem)) )
+        {
+            spin_lock(&prv->waitq_lock);
+            list_del_init(&nvc->waitq_elem);
+            spin_unlock(&prv->waitq_lock);
+        }
+        else if ( per_cpu(npc, cpu).vcpu == v )
+            tickled = vcpu_deassign(prv, v);
+    }
+
     /* If v is not assigned to a pCPU, or is not running, no need to bother */
-    if ( curr_on_cpu(v->processor) == v )
-        cpu_raise_softirq(v->processor, SCHEDULE_SOFTIRQ);
+    if ( likely(!tickled && curr_on_cpu(cpu) == v) )
+        cpu_raise_softirq(cpu, SCHEDULE_SOFTIRQ);
 
     SCHED_STAT_CRANK(vcpu_sleep);
 }
@@ -589,24 +630,34 @@ static void null_vcpu_migrate(const struct scheduler *ops, struct vcpu *v,
     }
 
     /*
-     * v is either assigned to a pCPU, or in the waitqueue.
-     *
-     * In the former case, the pCPU to which it was assigned would
-     * become free, and we, therefore, should check whether there is
-     * anyone in the waitqueue that can be assigned to it.
-     *
-     * In the latter, there is just nothing to do.
+     * If v is assigned to a pCPU, then such pCPU becomes free, and we
+     * should look in the waitqueue if anyone else can be assigned to it.
      */
-    if ( likely(list_empty(&nvc->waitq_elem)) )
+    if ( likely(per_cpu(npc, v->processor).vcpu == v) )
     {
         vcpu_deassign(prv, v);
         SCHED_STAT_CRANK(migrate_running);
     }
-    else
+    else if ( !list_empty(&nvc->waitq_elem) )
         SCHED_STAT_CRANK(migrate_on_runq);
 
     SCHED_STAT_CRANK(migrated);
 
+    /*
+     * If a vcpu is (going) offline, we want it to be neither assigned
+     * to a pCPU, nor in the waitqueue.
+     *
+     * If it was on a cpu, we've removed it from there above. If it is
+     * in the waitqueue, we remove it from there now. And then we bail.
+     */
+    if ( unlikely(!is_vcpu_online(v)) )
+    {
+        spin_lock(&prv->waitq_lock);
+        list_del_init(&nvc->waitq_elem);
+        spin_unlock(&prv->waitq_lock);
+        goto out;
+    }
+
     /*
      * Let's now consider new_cpu, which is where v is being sent. It can be
      * either free, or have a vCPU already assigned to it.
@@ -646,6 +697,7 @@ static void null_vcpu_migrate(const struct scheduler *ops, struct vcpu *v,
      * at least. In case of suspend, any temporary inconsistency caused
      * by this, will be fixed-up during resume.
      */
+ out:
     v->processor = new_cpu;
 }
 


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Xen-devel] [PATCH v2 3/4] xen: sched: reassign vCPUs to pCPUs, when they come back online
  2019-07-26  6:25 [Xen-devel] [PATCH v2 0/4] xen: sched: support vcpu hotplug/hotunplug in the 'null scheduler' Dario Faggioli
  2019-07-26  6:25 ` [Xen-devel] [PATCH v2 1/4] xen: sched: refector code around vcpu_deassign() in null scheduler Dario Faggioli
  2019-07-26  6:25 ` [Xen-devel] [PATCH v2 2/4] xen: sched: deal with vCPUs being or becoming online or offline Dario Faggioli
@ 2019-07-26  6:26 ` Dario Faggioli
  2019-07-26  6:26 ` [Xen-devel] [PATCH v2 4/4] xen: sched: refactor the ASSERTs around vcpu_deassing() Dario Faggioli
  3 siblings, 0 replies; 10+ messages in thread
From: Dario Faggioli @ 2019-07-26  6:26 UTC (permalink / raw)
  To: xen-devel
  Cc: Roger Pau Monne, Stefano Stabellini, George Dunlap, Dario Faggioli

When a vcpu that was offline, comes back online, we do want it to either
be assigned to a pCPU, or go into the wait list.

Detecting that a vcpu is coming back online is a bit tricky. Basically,
if the vcpu is waking up, and is neither assigned to a pCPU, nor in the
wait list, it must be coming back from offline.

When this happens, we put it in the waitqueue, and we "tickle" an idle
pCPU (if any), to go pick it up.

Looking at the patch, it seems that the vcpu wakeup code is getting
complex, and hence that it could potentially introduce latencies.
However, all this new logic is triggered only by the case of a vcpu
coming online, so, basically, the overhead during normal operations is
just an additional 'if()'.

Signed-off-by: Dario Faggioli <dario.faggioli@suse.com>
Reviewed-by: George Dunlap <george.dunlap@citrix.com>
---
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Roger Pau Monne <roger.pau@citrix.com>
---
 xen/common/sched_null.c |   53 +++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 51 insertions(+), 2 deletions(-)

diff --git a/xen/common/sched_null.c b/xen/common/sched_null.c
index 10e96f21dd..1bbcaf92b9 100644
--- a/xen/common/sched_null.c
+++ b/xen/common/sched_null.c
@@ -542,15 +542,19 @@ static void null_vcpu_remove(const struct scheduler *ops, struct vcpu *v)
 
 static void null_vcpu_wake(const struct scheduler *ops, struct vcpu *v)
 {
+    struct null_private *prv = null_priv(ops);
+    struct null_vcpu *nvc = null_vcpu(v);
+    unsigned int cpu = v->processor;
+
     ASSERT(!is_idle_vcpu(v));
 
-    if ( unlikely(curr_on_cpu(v->processor) == v) )
+    if ( unlikely(curr_on_cpu(cpu) == v) )
     {
         SCHED_STAT_CRANK(vcpu_wake_running);
         return;
     }
 
-    if ( unlikely(!list_empty(&null_vcpu(v)->waitq_elem)) )
+    if ( unlikely(!list_empty(&nvc->waitq_elem)) )
     {
         /* Not exactly "on runq", but close enough for reusing the counter */
         SCHED_STAT_CRANK(vcpu_wake_onrunq);
@@ -562,6 +566,48 @@ static void null_vcpu_wake(const struct scheduler *ops, struct vcpu *v)
     else
         SCHED_STAT_CRANK(vcpu_wake_not_runnable);
 
+    /*
+     * If a vcpu is neither on a pCPU nor in the waitqueue, it means it was
+     * offline, and that it is now coming back being online.
+     */
+    if ( unlikely(per_cpu(npc, cpu).vcpu != v && list_empty(&nvc->waitq_elem)) )
+    {
+        spin_lock(&prv->waitq_lock);
+        list_add_tail(&nvc->waitq_elem, &prv->waitq);
+        spin_unlock(&prv->waitq_lock);
+
+        cpumask_and(cpumask_scratch_cpu(cpu), v->cpu_hard_affinity,
+                    cpupool_domain_cpumask(v->domain));
+
+        if ( !cpumask_intersects(&prv->cpus_free, cpumask_scratch_cpu(cpu)) )
+        {
+            dprintk(XENLOG_G_WARNING, "WARNING: d%dv%d not assigned to any CPU!\n",
+                    v->domain->domain_id, v->vcpu_id);
+            return;
+        }
+
+        /*
+         * Now we would want to assign the vcpu to cpu, but we can't, because
+         * we don't have the lock. So, let's do the following:
+         * - try to remove cpu from the list of free cpus, to avoid races with
+         *   other onlining, inserting or migrating operations;
+         * - tickle the cpu, which will pickup work from the waitqueue, and
+         *   assign it to itself;
+         * - if we're racing already, and if there still are free cpus, try
+         *   again.
+         */
+        while ( cpumask_intersects(&prv->cpus_free, cpumask_scratch_cpu(cpu)) )
+        {
+            unsigned int new_cpu = pick_cpu(prv, v);
+
+            if ( test_and_clear_bit(new_cpu, &prv->cpus_free) )
+            {
+                cpu_raise_softirq(new_cpu, SCHEDULE_SOFTIRQ);
+                return;
+            }
+        }
+    }
+
     /* Note that we get here only for vCPUs assigned to a pCPU */
     cpu_raise_softirq(v->processor, SCHEDULE_SOFTIRQ);
 }
@@ -808,6 +854,9 @@ static struct task_slice null_schedule(const struct scheduler *ops,
         }
  unlock:
         spin_unlock(&prv->waitq_lock);
+
+        if ( ret.task == NULL && !cpumask_test_cpu(cpu, &prv->cpus_free) )
+            cpumask_set_cpu(cpu, &prv->cpus_free);
     }
 
     if ( unlikely(ret.task == NULL || !vcpu_runnable(ret.task)) )


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Xen-devel] [PATCH v2 4/4] xen: sched: refactor the ASSERTs around vcpu_deassing()
  2019-07-26  6:25 [Xen-devel] [PATCH v2 0/4] xen: sched: support vcpu hotplug/hotunplug in the 'null scheduler' Dario Faggioli
                   ` (2 preceding siblings ...)
  2019-07-26  6:26 ` [Xen-devel] [PATCH v2 3/4] xen: sched: reassign vCPUs to pCPUs, when they come back online Dario Faggioli
@ 2019-07-26  6:26 ` Dario Faggioli
  3 siblings, 0 replies; 10+ messages in thread
From: Dario Faggioli @ 2019-07-26  6:26 UTC (permalink / raw)
  To: xen-devel; +Cc: George Dunlap

It is all the time that we call vcpu_deassing() that the vcpu _must_ be
assigned to a pCPU, and hence that such pCPU can't be free.

Therefore, move the ASSERT-s which check for these properties in that
function, where they belong better.

Signed-off-by: Dario Faggioli <dfaggioli@suse.com>
Reviewed-by: George Dunlap <george.dunlap@citix.com>
---
 xen/common/sched_null.c |    5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/xen/common/sched_null.c b/xen/common/sched_null.c
index 1bbcaf92b9..c72335e5fa 100644
--- a/xen/common/sched_null.c
+++ b/xen/common/sched_null.c
@@ -368,6 +368,8 @@ static bool vcpu_deassign(struct null_private *prv, struct vcpu *v)
     struct null_vcpu *wvc;
 
     ASSERT(list_empty(&null_vcpu(v)->waitq_elem));
+    ASSERT(per_cpu(npc, v->processor).vcpu == v);
+    ASSERT(!cpumask_test_cpu(v->processor, &prv->cpus_free));
 
     per_cpu(npc, cpu).vcpu = NULL;
     cpumask_set_cpu(cpu, &prv->cpus_free);
@@ -529,9 +531,6 @@ static void null_vcpu_remove(const struct scheduler *ops, struct vcpu *v)
         goto out;
     }
 
-    ASSERT(per_cpu(npc, v->processor).vcpu == v);
-    ASSERT(!cpumask_test_cpu(v->processor, &prv->cpus_free));
-
     vcpu_deassign(prv, v);
 
  out:


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [Xen-devel] [PATCH v2 2/4] xen: sched: deal with vCPUs being or becoming online or offline
  2019-07-26  6:25 ` [Xen-devel] [PATCH v2 2/4] xen: sched: deal with vCPUs being or becoming online or offline Dario Faggioli
@ 2019-08-05 10:48   ` George Dunlap
  0 siblings, 0 replies; 10+ messages in thread
From: George Dunlap @ 2019-08-05 10:48 UTC (permalink / raw)
  To: Dario Faggioli, xen-devel
  Cc: George Dunlap, Stefano Stabellini, Roger Pau Monne

On 7/26/19 7:25 AM, Dario Faggioli wrote:
> If a vCPU is, or is going, offline we want it to be neither
> assigned to a pCPU, nor in the wait list, so:
> - if an offline vcpu is inserted (or migrated) it must not
>   go on a pCPU, nor in the wait list;
> - if an offline vcpu is removed, we are sure that it is
>   neither on a pCPU nor in the wait list already, so we
>   should just bail, avoiding doing any further action;
> - if a vCPU goes offline we need to remove it either from
>   its pCPU or from the wait list.
> 
> Signed-off-by: Dario Faggioli <dfaggioli@suse.com>

Reviewed-by: George Dunlap <george.dunlap@citrix.com>

> ---
> Cc: George Dunlap <george.dunlap@eu.citrix.com>
> Cc: Stefano Stabellini <sstabellini@kernel.org>
> Cc: Roger Pau Monne <roger.pau@citrix.com>
> ---
> Changes from v1:
> * improved wording in changelog and comments
> * this patch is the result of the merge of patches 2 and 3 from v1
> ---
>  xen/common/sched_null.c |   80 +++++++++++++++++++++++++++++++++++++++--------
>  1 file changed, 66 insertions(+), 14 deletions(-)
> 
> diff --git a/xen/common/sched_null.c b/xen/common/sched_null.c
> index c47c1b5aae..10e96f21dd 100644
> --- a/xen/common/sched_null.c
> +++ b/xen/common/sched_null.c
> @@ -339,6 +339,8 @@ static unsigned int pick_cpu(struct null_private *prv, struct vcpu *v)
>  static void vcpu_assign(struct null_private *prv, struct vcpu *v,
>                          unsigned int cpu)
>  {
> +    ASSERT(is_vcpu_online(v));
> +
>      per_cpu(npc, cpu).vcpu = v;
>      v->processor = cpu;
>      cpumask_clear_cpu(cpu, &prv->cpus_free);
> @@ -358,7 +360,8 @@ static void vcpu_assign(struct null_private *prv, struct vcpu *v,
>      }
>  }
>  
> -static void vcpu_deassign(struct null_private *prv, struct vcpu *v)
> +/* Returns true if a cpu was tickled */
> +static bool vcpu_deassign(struct null_private *prv, struct vcpu *v)
>  {
>      unsigned int bs;
>      unsigned int cpu = v->processor;
> @@ -403,11 +406,13 @@ static void vcpu_deassign(struct null_private *prv, struct vcpu *v)
>                  vcpu_assign(prv, wvc->vcpu, cpu);
>                  cpu_raise_softirq(cpu, SCHEDULE_SOFTIRQ);
>                  spin_unlock(&prv->waitq_lock);
> -                return;
> +                return true;
>              }
>          }
>      }
>      spin_unlock(&prv->waitq_lock);
> +
> +    return false;
>  }
>  
>  /* Change the scheduler of cpu to us (null). */
> @@ -445,8 +450,14 @@ static void null_vcpu_insert(const struct scheduler *ops, struct vcpu *v)
>      ASSERT(!is_idle_vcpu(v));
>  
>      lock = vcpu_schedule_lock_irq(v);
> - retry:
>  
> +    if ( unlikely(!is_vcpu_online(v)) )
> +    {
> +        vcpu_schedule_unlock_irq(lock, v);
> +        return;
> +    }
> +
> + retry:
>      cpu = v->processor = pick_cpu(prv, v);
>  
>      spin_unlock(lock);
> @@ -500,6 +511,14 @@ static void null_vcpu_remove(const struct scheduler *ops, struct vcpu *v)
>  
>      lock = vcpu_schedule_lock_irq(v);
>  
> +    /* If offline, the vcpu shouldn't be assigned, nor in the waitqueue */
> +    if ( unlikely(!is_vcpu_online(v)) )
> +    {
> +        ASSERT(per_cpu(npc, v->processor).vcpu != v);
> +        ASSERT(list_empty(&nvc->waitq_elem));
> +        goto out;
> +    }
> +
>      /* If v is in waitqueue, just get it out of there and bail */
>      if ( unlikely(!list_empty(&nvc->waitq_elem)) )
>      {
> @@ -549,11 +568,33 @@ static void null_vcpu_wake(const struct scheduler *ops, struct vcpu *v)
>  
>  static void null_vcpu_sleep(const struct scheduler *ops, struct vcpu *v)
>  {
> +    struct null_private *prv = null_priv(ops);
> +    unsigned int cpu = v->processor;
> +    bool tickled = false;
> +
>      ASSERT(!is_idle_vcpu(v));
>  
> +    /* 
> +     * Check if the vcpu is in the process of being offlined. if yes,
> +     * we need to remove it from either its pCPU or the waitqueue.
> +     */
> +    if ( unlikely(!is_vcpu_online(v)) )
> +    {
> +        struct null_vcpu *nvc = null_vcpu(v);
> +
> +        if ( unlikely(!list_empty(&nvc->waitq_elem)) )
> +        {
> +            spin_lock(&prv->waitq_lock);
> +            list_del_init(&nvc->waitq_elem);
> +            spin_unlock(&prv->waitq_lock);
> +        }
> +        else if ( per_cpu(npc, cpu).vcpu == v )
> +            tickled = vcpu_deassign(prv, v);
> +    }
> +
>      /* If v is not assigned to a pCPU, or is not running, no need to bother */
> -    if ( curr_on_cpu(v->processor) == v )
> -        cpu_raise_softirq(v->processor, SCHEDULE_SOFTIRQ);
> +    if ( likely(!tickled && curr_on_cpu(cpu) == v) )
> +        cpu_raise_softirq(cpu, SCHEDULE_SOFTIRQ);
>  
>      SCHED_STAT_CRANK(vcpu_sleep);
>  }
> @@ -589,24 +630,34 @@ static void null_vcpu_migrate(const struct scheduler *ops, struct vcpu *v,
>      }
>  
>      /*
> -     * v is either assigned to a pCPU, or in the waitqueue.
> -     *
> -     * In the former case, the pCPU to which it was assigned would
> -     * become free, and we, therefore, should check whether there is
> -     * anyone in the waitqueue that can be assigned to it.
> -     *
> -     * In the latter, there is just nothing to do.
> +     * If v is assigned to a pCPU, then such pCPU becomes free, and we
> +     * should look in the waitqueue if anyone else can be assigned to it.
>       */
> -    if ( likely(list_empty(&nvc->waitq_elem)) )
> +    if ( likely(per_cpu(npc, v->processor).vcpu == v) )
>      {
>          vcpu_deassign(prv, v);
>          SCHED_STAT_CRANK(migrate_running);
>      }
> -    else
> +    else if ( !list_empty(&nvc->waitq_elem) )
>          SCHED_STAT_CRANK(migrate_on_runq);
>  
>      SCHED_STAT_CRANK(migrated);
>  
> +    /*
> +     * If a vcpu is (going) offline, we want it to be neither assigned
> +     * to a pCPU, nor in the waitqueue.
> +     *
> +     * If it was on a cpu, we've removed it from there above. If it is
> +     * in the waitqueue, we remove it from there now. And then we bail.
> +     */
> +    if ( unlikely(!is_vcpu_online(v)) )
> +    {
> +        spin_lock(&prv->waitq_lock);
> +        list_del_init(&nvc->waitq_elem);
> +        spin_unlock(&prv->waitq_lock);
> +        goto out;
> +    }
> +
>      /*
>       * Let's now consider new_cpu, which is where v is being sent. It can be
>       * either free, or have a vCPU already assigned to it.
> @@ -646,6 +697,7 @@ static void null_vcpu_migrate(const struct scheduler *ops, struct vcpu *v,
>       * at least. In case of suspend, any temporary inconsistency caused
>       * by this, will be fixed-up during resume.
>       */
> + out:
>      v->processor = new_cpu;
>  }
>  
> 


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Xen-devel] [PATCH v2 1/4] xen: sched: refector code around vcpu_deassign() in null scheduler
  2019-07-26  6:25 ` [Xen-devel] [PATCH v2 1/4] xen: sched: refector code around vcpu_deassign() in null scheduler Dario Faggioli
@ 2019-08-05 15:58   ` Jan Beulich
  2019-08-05 16:04     ` George Dunlap
  0 siblings, 1 reply; 10+ messages in thread
From: Jan Beulich @ 2019-08-05 15:58 UTC (permalink / raw)
  To: George Dunlap; +Cc: xen-devel, Dario Faggioli

On 26.07.2019 08:25, Dario Faggioli wrote:
> vcpu_deassign() is called only once (in _vcpu_remove()).
> 
> Let's consolidate the two functions into one.
> 
> No functional change intended.
> 
> Signed-off-by: Dario Faggioli <dfaggioli@suse.com>
> Acked-by: George Dunlap <george.dunlap@citrix.com>

I'm puzzled by commit a397471278, in two ways:

1) The commit is empty, presumably because I did apply the patch a few
days ago already.

2) The committer is recorded as "Patchew Importer <importer@patchew.org>".
Do we really want to hide the fact who has been committing a patch?
While it's mostly mechanical, there's still the human decision of "this
is ready to go in" involved, which I don't think a bot can reliably take
in all cases.

Jan
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Xen-devel] [PATCH v2 1/4] xen: sched: refector code around vcpu_deassign() in null scheduler
  2019-08-05 15:58   ` Jan Beulich
@ 2019-08-05 16:04     ` George Dunlap
  2019-08-05 17:30       ` Dario Faggioli
  0 siblings, 1 reply; 10+ messages in thread
From: George Dunlap @ 2019-08-05 16:04 UTC (permalink / raw)
  To: Jan Beulich; +Cc: xen-devel, Dario Faggioli

On 8/5/19 4:58 PM, Jan Beulich wrote:
> On 26.07.2019 08:25, Dario Faggioli wrote:
>> vcpu_deassign() is called only once (in _vcpu_remove()).
>>
>> Let's consolidate the two functions into one.
>>
>> No functional change intended.
>>
>> Signed-off-by: Dario Faggioli <dfaggioli@suse.com>
>> Acked-by: George Dunlap <george.dunlap@citrix.com>
> 
> I'm puzzled by commit a397471278, in two ways:
> 
> 1) The commit is empty, presumably because I did apply the patch a few
> days ago already.
> 
> 2) The committer is recorded as "Patchew Importer <importer@patchew.org>".
> Do we really want to hide the fact who has been committing a patch?
> While it's mostly mechanical, there's still the human decision of "this
> is ready to go in" involved, which I don't think a bot can reliably take
> in all cases.

Both of these are mistakes, and due to the fact that I `git fetch`ed
patchew's commit rather than doing `git am` of the mbox provided by
patchew.  (And I used patchew's commit because somehow 4/4 didn't reach
my inbox.)

Re #1, I re-reviewed v2 from the commit itself; but then rebased before
pushing, and didn't notice that the commit ended up  being empty.

Re #2, I guess that means I shouldn't really be pushing from patchew's
commit anyway.

Either way, sorry about the mistake; I'll try to remember to avoid using
patchew's commit in the future.

 -George

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Xen-devel] [PATCH v2 1/4] xen: sched: refector code around vcpu_deassign() in null scheduler
  2019-08-05 16:04     ` George Dunlap
@ 2019-08-05 17:30       ` Dario Faggioli
  2019-08-06  7:45         ` George Dunlap
  0 siblings, 1 reply; 10+ messages in thread
From: Dario Faggioli @ 2019-08-05 17:30 UTC (permalink / raw)
  To: George Dunlap, Jan Beulich; +Cc: xen-devel


[-- Attachment #1.1: Type: text/plain, Size: 1316 bytes --]

On Mon, 2019-08-05 at 17:04 +0100, George Dunlap wrote:
> On 8/5/19 4:58 PM, Jan Beulich wrote:
> > On 26.07.2019 08:25, Dario Faggioli wrote:
> > > 
> > 1) The commit is empty, presumably because I did apply the patch a
> > few
> > days ago already.
> > 
> > 2) The committer is recorded as "Patchew Importer <
> > importer@patchew.org>".
> > Do we really want to hide the fact who has been committing a patch?
> > While it's mostly mechanical, there's still the human decision of
> > "this
> > is ready to go in" involved, which I don't think a bot can reliably
> > take
> > in all cases.
> 
> Both of these are mistakes, and due to the fact that I `git fetch`ed
> patchew's commit rather than doing `git am` of the mbox provided by
> patchew.  (And I used patchew's commit because somehow 4/4 didn't
> reach
> my inbox.)
>
And this last part is apparently my fault, as your email address is
actually wrong, in the Cc line of that patch.

So I guess I had a part in this as well... Sorry about that! :-)

Regards
-- 
Dario Faggioli, Ph.D
http://about.me/dario.faggioli
Virtualization Software Engineer
SUSE Labs, SUSE https://www.suse.com/
-------------------------------------------------------------------
<<This happens because _I_ choose it to happen!>> (Raistlin Majere)


[-- Attachment #1.2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 157 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Xen-devel] [PATCH v2 1/4] xen: sched: refector code around vcpu_deassign() in null scheduler
  2019-08-05 17:30       ` Dario Faggioli
@ 2019-08-06  7:45         ` George Dunlap
  0 siblings, 0 replies; 10+ messages in thread
From: George Dunlap @ 2019-08-06  7:45 UTC (permalink / raw)
  To: Dario Faggioli; +Cc: xen-devel, Jan Beulich



> On Aug 5, 2019, at 6:30 PM, Dario Faggioli <dfaggioli@suse.com> wrote:
> 
> On Mon, 2019-08-05 at 17:04 +0100, George Dunlap wrote:
>> On 8/5/19 4:58 PM, Jan Beulich wrote:
>>> On 26.07.2019 08:25, Dario Faggioli wrote:
>>>> 
>>> 1) The commit is empty, presumably because I did apply the patch a
>>> few
>>> days ago already.
>>> 
>>> 2) The committer is recorded as "Patchew Importer <
>>> importer@patchew.org>".
>>> Do we really want to hide the fact who has been committing a patch?
>>> While it's mostly mechanical, there's still the human decision of
>>> "this
>>> is ready to go in" involved, which I don't think a bot can reliably
>>> take
>>> in all cases.
>> 
>> Both of these are mistakes, and due to the fact that I `git fetch`ed
>> patchew's commit rather than doing `git am` of the mbox provided by
>> patchew.  (And I used patchew's commit because somehow 4/4 didn't
>> reach
>> my inbox.)
>> 
> And this last part is apparently my fault, as your email address is
> actually wrong, in the Cc line of that patch.

That would explain it. :-)  But that’s by no means your “fault”: It’s very common for me to only be CC’d on a subset of patches in a series (e.g., because I’m the maintainer for some patches but not others), so “receiving a only a subset of patches” is something my workflow should handle effectively but didn’t.

 -George

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2019-08-06  7:45 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-07-26  6:25 [Xen-devel] [PATCH v2 0/4] xen: sched: support vcpu hotplug/hotunplug in the 'null scheduler' Dario Faggioli
2019-07-26  6:25 ` [Xen-devel] [PATCH v2 1/4] xen: sched: refector code around vcpu_deassign() in null scheduler Dario Faggioli
2019-08-05 15:58   ` Jan Beulich
2019-08-05 16:04     ` George Dunlap
2019-08-05 17:30       ` Dario Faggioli
2019-08-06  7:45         ` George Dunlap
2019-07-26  6:25 ` [Xen-devel] [PATCH v2 2/4] xen: sched: deal with vCPUs being or becoming online or offline Dario Faggioli
2019-08-05 10:48   ` George Dunlap
2019-07-26  6:26 ` [Xen-devel] [PATCH v2 3/4] xen: sched: reassign vCPUs to pCPUs, when they come back online Dario Faggioli
2019-07-26  6:26 ` [Xen-devel] [PATCH v2 4/4] xen: sched: refactor the ASSERTs around vcpu_deassing() Dario Faggioli

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.