On Wed, 22 Feb 2006, Keir Fraser wrote:
> I think the calculation of delta stolen time would be clearer as:
> ((system_time - prev_system_time) - (vcpu_time - prev_vcpu_time)) /
> NS_PER_TICK
The "(system_time - prev_system_time)" above is equivalent
to the delta_cpu variable.
I agree on saving the prev_vcpu_time though, it makes the code
quite a bit nicer. I hope you like this patch ;)
Signed-off-by: Rik van Riel <riel@xxxxxxxxxx>
--- linux-2.6.15.i686/arch/i386/kernel/time-xen.c.steal 2006-02-17
16:44:40.000000000 -0500
+++ linux-2.6.15.i686/arch/i386/kernel/time-xen.c 2006-02-24
13:53:08.000000000 -0500
@@ -48,6 +48,7 @@
#include <linux/mca.h>
#include <linux/sysctl.h>
#include <linux/percpu.h>
+#include <linux/kernel_stat.h>
#include <asm/io.h>
#include <asm/smp.h>
@@ -77,6 +78,7 @@
#include <asm/arch_hooks.h>
#include <xen/evtchn.h>
+#include <xen/interface/vcpu.h>
#if defined (__i386__)
#include <asm/i8259.h>
@@ -125,6 +127,9 @@ static u32 shadow_tv_version;
static u64 processed_system_time; /* System time (ns) at last processing. */
static DEFINE_PER_CPU(u64, processed_system_time);
+/* Keep track of how much time our vcpu used, for steal time calculation. */
+static DEFINE_PER_CPU(u64, prev_vcpu_time);
+
/* Must be signed, as it's compared with s64 quantities which can be -ve. */
#define NS_PER_TICK (1000000000LL/HZ)
@@ -624,7 +629,32 @@ irqreturn_t timer_interrupt(int irq, voi
* Local CPU jiffy work. No need to hold xtime_lock, and I'm not sure
* if there is risk of deadlock if we do (since update_process_times
* may do scheduler rebalancing work and thus acquire runqueue locks).
+ *
+ * If we have not run for a while, chances are this vcpu got scheduled
+ * away. Try to estimate how much time was stolen.
*/
+ if (delta_cpu > (s64)(2 * NS_PER_TICK)) {
+ dom0_getvcpuinfo_t vcpu = { 0, };
+ s64 steal;
+ u64 dvcpu;
+
+ if (HYPERVISOR_vcpu_op(VCPUOP_cpu_info, cpu, &vcpu) == 0) {
+ dvcpu = vcpu.cpu_time - per_cpu(prev_vcpu_time, cpu);
+ per_cpu(prev_vcpu_time, cpu) = vcpu.cpu_time;
+ steal = delta_cpu - (s64)dvcpu;
+
+ if (steal > 0) {
+ /* do_div modifies the variable in place. */
+ do_div(steal, NS_PER_TICK);
+
+ delta_cpu -= steal * NS_PER_TICK;
+ per_cpu(processed_system_time, cpu) +=
+ steal * NS_PER_TICK;
+ account_steal_time(current, (cputime_t)steal);
+ }
+ }
+ }
+
while (delta_cpu >= NS_PER_TICK) {
delta_cpu -= NS_PER_TICK;
per_cpu(processed_system_time, cpu) += NS_PER_TICK;
--- linux-2.6.15.i686/include/xen/interface/vcpu.h.steal 2006-02-17
16:14:17.000000000 -0500
+++ linux-2.6.15.i686/include/xen/interface/vcpu.h 2006-02-17
16:14:52.000000000 -0500
@@ -51,6 +51,14 @@
/* Returns 1 if the given VCPU is up. */
#define VCPUOP_is_up 3
+/*
+ * Get information on how much CPU time this VCPU has used, etc...
+ *
+ * @extra_arg == pointer to an empty dom0_getvcpuinfo_t, the "OUT" variables
+ * of which filled in with scheduler info.
+ */
+#define VCPUOP_cpu_info 4
+
#endif /* __XEN_PUBLIC_VCPU_H__ */
/*
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|