diff mbox series

[RFC,36/49] xen/sched: rework and rename vcpu_force_reschedule()

Message ID 20190329150934.17694-37-jgross@suse.com (mailing list archive)
State Superseded
Headers show
Series xen: add core scheduling support | expand

Commit Message

Jürgen Groß March 29, 2019, 3:09 p.m. UTC
vcpu_force_reschedule() is only used for modifying the periodic timer
of a vcpu. Forcing a vcpu to give up the physical cpu for that purpose
is kind of brutal.

So instead of doing the reschedule dance just operate on the timer
directly.

In case we are modifying the timer of the currently running vcpu we
can just do that. In case it is for a foreign vcpu we should pause it
for that purpose like we do for all other vcpu state modifications.

Rename the function to vcpu_set_periodic_timer() as this now reflects
the functionality.

Signed-off-by: Juergen Gross <jgross@suse.com>
---
 xen/arch/x86/pv/shim.c  |  4 +---
 xen/common/domain.c     |  6 ++----
 xen/common/schedule.c   | 23 +++++++++++++----------
 xen/include/xen/sched.h |  2 +-
 4 files changed, 17 insertions(+), 18 deletions(-)
diff mbox series

Patch

diff --git a/xen/arch/x86/pv/shim.c b/xen/arch/x86/pv/shim.c
index 324ca27f93..5edbcd9ac5 100644
--- a/xen/arch/x86/pv/shim.c
+++ b/xen/arch/x86/pv/shim.c
@@ -410,7 +410,7 @@  int pv_shim_shutdown(uint8_t reason)
         unmap_vcpu_info(v);
 
         /* Reset the periodic timer to the default value. */
-        v->periodic_period = MILLISECS(10);
+        vcpu_set_periodic_timer(v, MILLISECS(10));
         /* Stop the singleshot timer. */
         stop_timer(&v->singleshot_timer);
 
@@ -419,8 +419,6 @@  int pv_shim_shutdown(uint8_t reason)
 
         if ( v != current )
             vcpu_unpause_by_systemcontroller(v);
-        else
-            vcpu_force_reschedule(v);
     }
 
     return 0;
diff --git a/xen/common/domain.c b/xen/common/domain.c
index 2773a21129..b448d20d40 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -1442,15 +1442,13 @@  long do_vcpu_op(int cmd, unsigned int vcpuid, XEN_GUEST_HANDLE_PARAM(void) arg)
         if ( set.period_ns > STIME_DELTA_MAX )
             return -EINVAL;
 
-        v->periodic_period = set.period_ns;
-        vcpu_force_reschedule(v);
+        vcpu_set_periodic_timer(v, set.period_ns);
 
         break;
     }
 
     case VCPUOP_stop_periodic_timer:
-        v->periodic_period = 0;
-        vcpu_force_reschedule(v);
+        vcpu_set_periodic_timer(v, 0);
         break;
 
     case VCPUOP_set_singleshot_timer:
diff --git a/xen/common/schedule.c b/xen/common/schedule.c
index 0a94505b89..7c7735bf33 100644
--- a/xen/common/schedule.c
+++ b/xen/common/schedule.c
@@ -833,21 +833,24 @@  static void vcpu_migrate_finish(struct vcpu *v)
 }
 
 /*
- * Force a VCPU through a deschedule/reschedule path.
- * For example, using this when setting the periodic timer period means that
- * most periodic-timer state need only be touched from within the scheduler
- * which can thus be done without need for synchronisation.
+ * Set the periodic timer of a vcpu.
  */
-void vcpu_force_reschedule(struct vcpu *v)
+void vcpu_set_periodic_timer(struct vcpu *v, s_time_t value)
 {
-    spinlock_t *lock = item_schedule_lock_irq(v->sched_item);
+    s_time_t now = NOW();
 
-    if ( vcpu_running(v) )
-        vcpu_migrate_start(v);
+    if ( v != current )
+        vcpu_pause(v);
+    else
+        stop_timer(&v->periodic_timer);
 
-    item_schedule_unlock_irq(lock, v->sched_item);
+    v->periodic_period = value;
+    v->periodic_last_event = now;
 
-    vcpu_migrate_finish(v);
+    if ( v != current )
+        vcpu_unpause(v);
+    else if ( value != 0 )
+        set_timer(&v->periodic_timer, now + value);
 }
 
 void restore_vcpu_affinity(struct domain *d)
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index f7eb138d86..873a903977 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -857,7 +857,7 @@  struct scheduler *scheduler_get_default(void);
 struct scheduler *scheduler_alloc(unsigned int sched_id, int *perr);
 void scheduler_free(struct scheduler *sched);
 int schedule_cpu_switch(unsigned int cpu, struct cpupool *c);
-void vcpu_force_reschedule(struct vcpu *v);
+void vcpu_set_periodic_timer(struct vcpu *v, s_time_t value);
 int cpu_disable_scheduler(unsigned int cpu);
 /* We need it in dom0_setup_vcpu */
 void sched_set_affinity(struct vcpu *v, const cpumask_t *hard,