[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen stable-4.13] sched: fix get_cpu_idle_time() with core scheduling



commit 86f0b73bc97842519e6d205046f804664de4b2b0
Author:     Juergen Gross <jgross@xxxxxxxx>
AuthorDate: Thu Mar 5 11:06:19 2020 +0100
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Thu Mar 5 11:06:19 2020 +0100

    sched: fix get_cpu_idle_time() with core scheduling
    
    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@xxxxxxxx>
    Reviewed-by: Dario Faggioli <dfaggioli@xxxxxxxx>
    master commit: 132cbe8f35632fb2fea0625ee8fdda53a19a1645
    master date: 2020-02-19 16:08:11 +0100
---
 xen/common/schedule.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/xen/common/schedule.c b/xen/common/schedule.c
index 54a07ff9e8..27fde772be 100644
--- a/xen/common/schedule.c
+++ b/xen/common/schedule.c
@@ -305,17 +305,26 @@ void vcpu_runstate_get(struct vcpu *v, struct 
vcpu_runstate_info *runstate)
 {
     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);
 }
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.13

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/xen-changelog

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.