direct-io.hg

changeset 9235:de5d2b9a9cfb

When both stolen and blocked are rounded down, it is possible for the
final increment of the cpu local processed_system_time to move the cpu
local system time ahead a bit further than expected - but still proper
wrt. wall clock time.

This gives problems on a next timer interrupt, when stolen and blocked
both get rounded up and end up incrementing the per cpu
processed_system_time too far.

These simple checks make sure that the cpu local processed_system_time
never gets advanced too far. Not advancing the variable now should be
fine, since we'll increment it at the next timer tick...

This patch has made the "time went backwards" error messages go away
completely.

Signed-off-by: Rik van Riel <riel@redhat.com>
Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Tue Mar 14 16:00:16 2006 +0100 (2006-03-14)
parents a77cf8fdc307
children f4cef1aa2521
files linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c
line diff
     1.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c	Tue Mar 14 15:45:00 2006 +0100
     1.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c	Tue Mar 14 16:00:16 2006 +0100
     1.3 @@ -645,7 +645,7 @@ irqreturn_t timer_interrupt(int irq, voi
     1.4  	     unlikely(delta_cpu < -(s64)permitted_clock_jitter))
     1.5  	    && printk_ratelimit()) {
     1.6  		printk("Timer ISR/%d: Time went backwards: "
     1.7 -		       "delta=%lld cpu_delta=%lld shadow=%lld "
     1.8 +		       "delta=%lld delta_cpu=%lld shadow=%lld "
     1.9  		       "off=%lld processed=%lld cpu_processed=%lld\n",
    1.10  		       cpu, delta, delta_cpu, shadow->system_timestamp,
    1.11  		       (s64)get_nsec_offset(shadow),
    1.12 @@ -675,8 +675,10 @@ irqreturn_t timer_interrupt(int irq, voi
    1.13  	 * HACK: Passing NULL to account_steal_time()
    1.14  	 * ensures that the ticks are accounted as stolen.
    1.15  	 */
    1.16 -	if (stolen > 0) {
    1.17 +	if ((stolen > 0) && (delta_cpu > 0)) {
    1.18  		delta_cpu -= stolen;
    1.19 +		if (unlikely(delta_cpu < 0))
    1.20 +			stolen += delta_cpu; /* clamp local-time progress */
    1.21  		do_div(stolen, NS_PER_TICK);
    1.22  		per_cpu(processed_stolen_time, cpu) += stolen * NS_PER_TICK;
    1.23  		per_cpu(processed_system_time, cpu) += stolen * NS_PER_TICK;
    1.24 @@ -688,8 +690,10 @@ irqreturn_t timer_interrupt(int irq, voi
    1.25  	 * HACK: Passing idle_task to account_steal_time()
    1.26  	 * ensures that the ticks are accounted as idle/wait.
    1.27  	 */
    1.28 -	if (blocked > 0) {
    1.29 +	if ((blocked > 0) && (delta_cpu > 0)) {
    1.30  		delta_cpu -= blocked;
    1.31 +		if (unlikely(delta_cpu < 0))
    1.32 +			blocked += delta_cpu; /* clamp local-time progress */
    1.33  		do_div(blocked, NS_PER_TICK);
    1.34  		per_cpu(processed_blocked_time, cpu) += blocked * NS_PER_TICK;
    1.35  		per_cpu(processed_system_time, cpu)  += blocked * NS_PER_TICK;