[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 2/2] cpu steal accounting for kernel (i386)
Estimate and account for the CPU steal time. That is, the time during which we wanted to run, but the hypervisor scheduled in another process instead. This can be used to help administrators in capacity planning, by clearly being able to distinguish whether the system is too slow or this guest is simply not getting enough CPU time. This is the i386 version, I'll send the implementation for x86_64 soon. 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-20 18:31:26.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> @@ -624,7 +626,43 @@ 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, }; + cputime64_t total; /* In jiffies, not nanoseconds. */ + s64 cputicks, deltaticks, steal; + + if (HYPERVISOR_vcpu_op(VCPUOP_cpu_info, cpu, &vcpu) == 0) { + total = kstat_cpu(cpu).cpustat.user + + kstat_cpu(cpu).cpustat.nice + + kstat_cpu(cpu).cpustat.system + + kstat_cpu(cpu).cpustat.softirq + + kstat_cpu(cpu).cpustat.irq; + + /* do_div modifies the variable in place. YUCK */ + deltaticks = delta_cpu; + cputicks = vcpu.cpu_time; + do_div(cputicks, NS_PER_TICK); + do_div(deltaticks, NS_PER_TICK); + + steal = total + deltaticks - cputicks; + if (unlikely(steal < 0)) + steal = 0; + else if (unlikely(steal > deltaticks)) + steal = deltaticks; + + if (steal > 0) { + 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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |