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

[xen master] sched: fix scheduler_disable() with core scheduling



commit 82dd1a956d9b68f52e830d1dddfdfb4ab4d5a638
Author:     Sergey Dyasli <sergey.dyasli@xxxxxxxxxx>
AuthorDate: Fri Apr 17 09:28:16 2020 +0200
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Fri Apr 17 09:28:16 2020 +0200

    sched: fix scheduler_disable() with core scheduling
    
    In core-scheduling mode, Xen might crash when entering ACPI S5 state.
    This happens in sched_slave() during is_idle_unit(next) check because
    next->vcpu_list is stale and points to an already freed memory.
    
    This situation happens shortly after scheduler_disable() is called if
    some CPU is still inside sched_slave() softirq. Current logic simply
    returns prev->next_task from sched_wait_rendezvous_in() which causes
    the described crash because next_task->vcpu_list has become invalid.
    
    Fix the crash by returning NULL from sched_wait_rendezvous_in() in
    the case when scheduler_disable() has been called.
    
    Signed-off-by: Sergey Dyasli <sergey.dyasli@xxxxxxxxxx>
    Reviewed-by: Juergen Gross <jgross@xxxxxxxx>
    Reviewed-by: Dario Faggioli <dfaggioli@xxxxxxxx>
---
 xen/common/sched/core.c | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/xen/common/sched/core.c b/xen/common/sched/core.c
index c4ed070470..d94b95285f 100644
--- a/xen/common/sched/core.c
+++ b/xen/common/sched/core.c
@@ -2484,19 +2484,15 @@ static struct sched_unit 
*sched_wait_rendezvous_in(struct sched_unit *prev,
 
         *lock = pcpu_schedule_lock_irq(cpu);
 
-        if ( unlikely(!scheduler_active) )
-        {
-            ASSERT(is_idle_unit(prev));
-            atomic_set(&prev->next_task->rendezvous_out_cnt, 0);
-            prev->rendezvous_in_cnt = 0;
-        }
-
         /*
          * Check for scheduling resource switched. This happens when we are
          * moved away from our cpupool and cpus are subject of the idle
          * scheduler now.
+         *
+         * This is also a bail out case when scheduler_disable() has been
+         * called.
          */
-        if ( unlikely(sr != get_sched_res(cpu)) )
+        if ( unlikely(sr != get_sched_res(cpu) || !scheduler_active) )
         {
             ASSERT(is_idle_unit(prev));
             atomic_set(&prev->next_task->rendezvous_out_cnt, 0);
--
generated by git-patchbot for /home/xen/git/xen.git#master



 


Rackspace

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