Xen-Devel Archive on lore.kernel.org
 help / color / Atom feed
* [Xen-devel] [PATCH] xen/sched: fix get_cpu_idle_time() with core scheduling
@ 2020-02-13 14:35 Juergen Gross
  2020-02-19 12:28 ` Dario Faggioli
  0 siblings, 1 reply; 2+ messages in thread
From: Juergen Gross @ 2020-02-13 14:35 UTC (permalink / raw)
  To: xen-devel; +Cc: Juergen Gross, George Dunlap, Dario Faggioli

get_cpu_idle_time() is calling vcpu_runstate_get() for an idle vcpu.
With core scheduling active this is fragile, as idle vcpus are assigned
to other scheduling units temporarily, and that assignment is changed
in some cases without holding the scheduling lock, and
vcpu_runstate_get() is using v->sched_unit as parameter for
unit_schedule_[un]lock_irq(), resulting in an ASSERT() triggering in
unlock in case v->sched_unit has changed meanwhile.

Fix that by using a local unit variable holding the correct unit.

Signed-off-by: Juergen Gross <jgross@suse.com>
---
I have verified that all other uses of v->sched_unit are not
problematic: they are all for non-idle vcpus, or in scheduling paths
dealing with scheduling themselves and thus being aware of the
potential problem or not vulnerable by it.
---
 xen/common/sched/core.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/xen/common/sched/core.c b/xen/common/sched/core.c
index 2e43f8029f..de5a6b1a57 100644
--- a/xen/common/sched/core.c
+++ b/xen/common/sched/core.c
@@ -308,17 +308,26 @@ void vcpu_runstate_get(const struct vcpu *v,
 {
     spinlock_t *lock;
     s_time_t delta;
+    struct sched_unit *unit;
 
     rcu_read_lock(&sched_res_rculock);
 
-    lock = likely(v == current) ? NULL : unit_schedule_lock_irq(v->sched_unit);
+    /*
+     * Be careful in case of an idle vcpu: the assignment to a unit might
+     * change even with the scheduling lock held, so be sure to use the
+     * correct unit for locking in order to avoid triggering an ASSERT() in
+     * the unlock function.
+     */
+    unit = is_idle_vcpu(v) ? get_sched_res(v->processor)->sched_unit_idle
+                           : v->sched_unit;
+    lock = likely(v == current) ? NULL : unit_schedule_lock_irq(unit);
     memcpy(runstate, &v->runstate, sizeof(*runstate));
     delta = NOW() - runstate->state_entry_time;
     if ( delta > 0 )
         runstate->time[runstate->state] += delta;
 
     if ( unlikely(lock != NULL) )
-        unit_schedule_unlock_irq(lock, v->sched_unit);
+        unit_schedule_unlock_irq(lock, unit);
 
     rcu_read_unlock(&sched_res_rculock);
 }
-- 
2.16.4


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

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

* Re: [Xen-devel] [PATCH] xen/sched: fix get_cpu_idle_time() with core scheduling
  2020-02-13 14:35 [Xen-devel] [PATCH] xen/sched: fix get_cpu_idle_time() with core scheduling Juergen Gross
@ 2020-02-19 12:28 ` Dario Faggioli
  0 siblings, 0 replies; 2+ messages in thread
From: Dario Faggioli @ 2020-02-19 12:28 UTC (permalink / raw)
  To: Juergen Gross, xen-devel; +Cc: George Dunlap

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

On Thu, 2020-02-13 at 15:35 +0100, Juergen Gross wrote:
> get_cpu_idle_time() is calling vcpu_runstate_get() for an idle vcpu.
> With core scheduling active this is fragile, as idle vcpus are
> assigned
> to other scheduling units temporarily, and that assignment is changed
> in some cases without holding the scheduling lock, and
> vcpu_runstate_get() is using v->sched_unit as parameter for
> unit_schedule_[un]lock_irq(), resulting in an ASSERT() triggering in
> unlock in case v->sched_unit has changed meanwhile.
> 
> Fix that by using a local unit variable holding the correct unit.
> 
> Signed-off-by: Juergen Gross <jgross@suse.com>
>
Reviewed-by: Dario Faggioli <dfaggioli@suse.com>

And...

> I have verified that all other uses of v->sched_unit are not
> problematic: they are all for non-idle vcpus, or in scheduling paths
> dealing with scheduling themselves and thus being aware of the
> potential problem or not vulnerable by it.
>
... Thanks for having done this as well. :-)

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] 2+ messages in thread

end of thread, back to index

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-02-13 14:35 [Xen-devel] [PATCH] xen/sched: fix get_cpu_idle_time() with core scheduling Juergen Gross
2020-02-19 12:28 ` Dario Faggioli

Xen-Devel Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/xen-devel/0 xen-devel/git/0.git
	git clone --mirror https://lore.kernel.org/xen-devel/1 xen-devel/git/1.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 xen-devel xen-devel/ https://lore.kernel.org/xen-devel \
		xen-devel@lists.xenproject.org xen-devel@lists.xen.org
	public-inbox-index xen-devel

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.xenproject.lists.xen-devel


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git