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

[xen master] sched: introduce specialization of "running only" vcpu_runstate_get()



commit 519bf1f8f3bb78ae1d826f22d593a486cd302266
Author:     Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Wed Jun 17 12:39:36 2026 +0200
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Wed Jun 17 12:39:36 2026 +0200

    sched: introduce specialization of "running only" vcpu_runstate_get()
    
    About half the callers of vcpu_runstate_get() are solely after the
    "running" time of a vCPU. Introduce a specialization with a smaller
    read critical section and thus reduced risk of a need for retries.
    
    Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
    Acked-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
    Reviewed-by: Juergen Gross <jgross@xxxxxxxx>
    Release-Acked-by: Oleksii Kurochko <oleksii.kurochko@xxxxxxxxx>
---
 xen/common/domctl.c     | 11 +++--------
 xen/common/sched/core.c | 30 +++++++++++++++++++++++++-----
 xen/include/xen/sched.h |  1 +
 3 files changed, 29 insertions(+), 13 deletions(-)

diff --git a/xen/common/domctl.c b/xen/common/domctl.c
index 32ef5b2e38..e98fddf515 100644
--- a/xen/common/domctl.c
+++ b/xen/common/domctl.c
@@ -56,7 +56,6 @@ void getdomaininfo(struct domain *d, struct 
xen_domctl_getdomaininfo *info)
     struct vcpu *v;
     u64 cpu_time = 0;
     int flags = XEN_DOMINF_blocked;
-    struct vcpu_runstate_info runstate;
 
     memset(info, 0, sizeof(*info));
 
@@ -69,8 +68,7 @@ void getdomaininfo(struct domain *d, struct 
xen_domctl_getdomaininfo *info)
      */
     for_each_vcpu ( d, v )
     {
-        vcpu_runstate_get(v, &runstate);
-        cpu_time += runstate.time[RUNSTATE_running];
+        cpu_time += vcpu_runstate_get_running(v);
         info->max_vcpu_id = v->vcpu_id;
         if ( !(v->pause_flags & VPF_down) )
         {
@@ -796,8 +794,7 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) 
u_domctl)
 
     case XEN_DOMCTL_getvcpuinfo:
     {
-        struct vcpu   *v;
-        struct vcpu_runstate_info runstate;
+        const struct vcpu *v;
 
         ret = -EINVAL;
         if ( op->u.getvcpuinfo.vcpu >= d->max_vcpus )
@@ -807,12 +804,10 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) 
u_domctl)
         if ( (v = d->vcpu[op->u.getvcpuinfo.vcpu]) == NULL )
             break;
 
-        vcpu_runstate_get(v, &runstate);
-
         op->u.getvcpuinfo.online   = !(v->pause_flags & VPF_down);
         op->u.getvcpuinfo.blocked  = !!(v->pause_flags & VPF_blocked);
         op->u.getvcpuinfo.running  = v->is_running;
-        op->u.getvcpuinfo.cpu_time = runstate.time[RUNSTATE_running];
+        op->u.getvcpuinfo.cpu_time = vcpu_runstate_get_running(v);
         op->u.getvcpuinfo.cpu      = v->processor;
         ret = 0;
         copyback = 1;
diff --git a/xen/common/sched/core.c b/xen/common/sched/core.c
index cf7c4e7a8a..c59c1dc872 100644
--- a/xen/common/sched/core.c
+++ b/xen/common/sched/core.c
@@ -325,15 +325,35 @@ void vcpu_runstate_get(const struct vcpu *v,
     }
 }
 
-uint64_t get_cpu_idle_time(unsigned int cpu)
+uint64_t vcpu_runstate_get_running(const struct vcpu *v)
 {
-    struct vcpu_runstate_info state = { 0 };
-    const struct vcpu *v = idle_vcpu[cpu];
+    struct seqcount seq = SEQCNT_ZERO();
+    const struct seqcount *s = v == current ? &seq : &v->runstate_seq;
+    unsigned int count;
+    uint64_t running;
+    s_time_t delta;
+
+    do {
+        count = read_seqcount_begin(s);
+
+        running = v->runstate.time[RUNSTATE_running];
+        delta = v->runstate.state == RUNSTATE_running
+                ? NOW() - v->runstate.state_entry_time
+                : 0;
+    } while ( read_seqcount_retry(s, count) );
+
+    if ( delta > 0 )
+        running += delta;
 
+    return running;
+}
+
+uint64_t get_cpu_idle_time(unsigned int cpu)
+{
     if ( cpu_online(cpu) && get_sched_res(cpu) )
-        vcpu_runstate_get(v, &state);
+        return vcpu_runstate_get_running(idle_vcpu[cpu]);
 
-    return state.time[RUNSTATE_running];
+    return 0;
 }
 
 /*
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index 11ffebbea4..91f6db7a32 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -1121,6 +1121,7 @@ int vcpu_affinity_domctl(struct domain *d, uint32_t cmd,
 
 void vcpu_runstate_get(const struct vcpu *v,
                        struct vcpu_runstate_info *runstate);
+uint64_t vcpu_runstate_get_running(const struct vcpu *v);
 uint64_t get_cpu_idle_time(unsigned int cpu);
 void sched_guest_idle(void (*idle) (void), unsigned int cpu);
 void scheduler_enable(void);
--
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®.