diff mbox series

xen/timer: don't migrate timers away from cpus during suspend

Message ID 20220906124135.12998-1-jgross@suse.com (mailing list archive)
State New, archived
Headers show
Series xen/timer: don't migrate timers away from cpus during suspend | expand

Commit Message

Jürgen Groß Sept. 6, 2022, 12:41 p.m. UTC
During a suspend/resume cycle timers on all cpus but cpu 0 will be
migrated to cpu 0, as the other cpus are taken down.

This is problematic in case such a timer is related to a specific vcpu,
as the vcpus are not migrated to another cpu during suspend (migrating
them would break cpupools and core scheduling).

In order to avoid the problems just try to keep the timers on their
cpus. Only migrate them away in case resume failed. Doing so isn't
problematic, as any vcpu on a cpu not coming back to life would be
migrated away, too.

Signed-off-by: Juergen Gross <jgross@suse.com>
Tested-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
---
 xen/common/timer.c | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)
diff mbox series

Patch

diff --git a/xen/common/timer.c b/xen/common/timer.c
index 9b5016d5ed..6b5473e5f1 100644
--- a/xen/common/timer.c
+++ b/xen/common/timer.c
@@ -637,6 +637,13 @@  static void free_percpu_timers(unsigned int cpu)
         ASSERT(ts->heap == dummy_heap);
 }
 
+static void deinit_timers(unsigned int cpu)
+{
+    migrate_timers_from_cpu(cpu);
+    if ( !park_offline_cpus )
+        free_percpu_timers(cpu);
+}
+
 static int cf_check cpu_callback(
     struct notifier_block *nfb, unsigned long action, void *hcpu)
 {
@@ -655,13 +662,14 @@  static int cf_check cpu_callback(
         }
         break;
 
-    case CPU_UP_CANCELED:
     case CPU_DEAD:
-    case CPU_RESUME_FAILED:
-        migrate_timers_from_cpu(cpu);
+        if ( system_state != SYS_STATE_suspend )
+            deinit_timers(cpu);
+        break;
 
-        if ( !park_offline_cpus && system_state != SYS_STATE_suspend )
-            free_percpu_timers(cpu);
+    case CPU_UP_CANCELED:
+    case CPU_RESUME_FAILED:
+        deinit_timers(cpu);
         break;
 
     case CPU_REMOVE: