aboutsummaryrefslogtreecommitdiffstats
path: root/xen/common/sched_credit.c
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@suse.com>2013-02-28 11:06:42 +0100
committerJan Beulich <jbeulich@suse.com>2013-02-28 11:06:42 +0100
commitcf0c29d1a99f17fe9e501e4e09d9d1e3eced6f98 (patch)
tree009d9e9a0d0bfd28f3e4747ebfea30fab16478f1 /xen/common/sched_credit.c
parentba9ef879973f9bee4b72c8f1d3ef816bc58e5fdc (diff)
downloadxen-cf0c29d1a99f17fe9e501e4e09d9d1e3eced6f98.tar.gz
xen-cf0c29d1a99f17fe9e501e4e09d9d1e3eced6f98.tar.bz2
xen-cf0c29d1a99f17fe9e501e4e09d9d1e3eced6f98.zip
credit1: track residual from divisions done during accounting
This should help with under-accounting of vCPU-s running for extremly short periods of time, but becoming runnable again at a high frequency. Signed-off-by: Jan Beulich <jbeulich@suse.com> Acked-by: George Dunlap <george.dunlap@eu.citrix.com>
Diffstat (limited to 'xen/common/sched_credit.c')
-rw-r--r--xen/common/sched_credit.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/xen/common/sched_credit.c b/xen/common/sched_credit.c
index df2d0765cd..7fbc0059ad 100644
--- a/xen/common/sched_credit.c
+++ b/xen/common/sched_credit.c
@@ -19,6 +19,7 @@
#include <xen/sched-if.h>
#include <xen/softirq.h>
#include <asm/atomic.h>
+#include <asm/div64.h>
#include <xen/errno.h>
#include <xen/keyhandler.h>
#include <xen/trace.h>
@@ -136,6 +137,7 @@ struct csched_vcpu {
struct csched_dom *sdom;
struct vcpu *vcpu;
atomic_t credit;
+ unsigned int residual;
s_time_t start_time; /* When we were scheduled (used for credit) */
uint16_t flags;
int16_t pri;
@@ -242,6 +244,7 @@ __runq_remove(struct csched_vcpu *svc)
static void burn_credits(struct csched_vcpu *svc, s_time_t now)
{
s_time_t delta;
+ uint64_t val;
unsigned int credits;
/* Assert svc is current */
@@ -250,7 +253,10 @@ static void burn_credits(struct csched_vcpu *svc, s_time_t now)
if ( (delta = now - svc->start_time) <= 0 )
return;
- credits = (delta*CSCHED_CREDITS_PER_MSEC + MILLISECS(1)/2) / MILLISECS(1);
+ val = delta * CSCHED_CREDITS_PER_MSEC + svc->residual;
+ svc->residual = do_div(val, MILLISECS(1));
+ credits = val;
+ ASSERT(credits == val); /* make sure we haven't truncated val */
atomic_sub(credits, &svc->credit);
svc->start_time += (credits * MILLISECS(1)) / CSCHED_CREDITS_PER_MSEC;
}