* A better fix for the Xen clock problem.
svn path=/nixpkgs/trunk/; revision=24488
This commit is contained in:
parent
2cc3847cd4
commit
85a0cd1385
@ -214,9 +214,10 @@ in
|
|||||||
patch = ./guruplug-mach-type.patch;
|
patch = ./guruplug-mach-type.patch;
|
||||||
};
|
};
|
||||||
|
|
||||||
revert_pvclock_sync =
|
xen_pvclock_resume =
|
||||||
{ name = "revert-pvclock-sync";
|
{ # Fix the clock after a DomU restore following a Dom0 reboot or migration.
|
||||||
patch = ./revert-pvclock-sync.patch;
|
name = "xen-pvclock-resume";
|
||||||
|
patch = ./xen-pvclock-resume.patch;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,46 +0,0 @@
|
|||||||
diff -ru -x '*~' linux-2.6.32.24-orig/arch/x86/kernel/pvclock.c linux-2.6.32.24/arch/x86/kernel/pvclock.c
|
|
||||||
--- linux-2.6.32.24-orig/arch/x86/kernel/pvclock.c 2010-10-01 22:51:56.000000000 +0200
|
|
||||||
+++ linux-2.6.32.24/arch/x86/kernel/pvclock.c 2010-10-25 14:02:14.000000000 +0200
|
|
||||||
@@ -109,14 +109,11 @@
|
|
||||||
return pv_tsc_khz;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static atomic64_t last_value = ATOMIC64_INIT(0);
|
|
||||||
-
|
|
||||||
cycle_t pvclock_clocksource_read(struct pvclock_vcpu_time_info *src)
|
|
||||||
{
|
|
||||||
struct pvclock_shadow_time shadow;
|
|
||||||
unsigned version;
|
|
||||||
cycle_t ret, offset;
|
|
||||||
- u64 last;
|
|
||||||
|
|
||||||
do {
|
|
||||||
version = pvclock_get_time_values(&shadow, src);
|
|
||||||
@@ -126,27 +123,6 @@
|
|
||||||
barrier();
|
|
||||||
} while (version != src->version);
|
|
||||||
|
|
||||||
- /*
|
|
||||||
- * Assumption here is that last_value, a global accumulator, always goes
|
|
||||||
- * forward. If we are less than that, we should not be much smaller.
|
|
||||||
- * We assume there is an error marging we're inside, and then the correction
|
|
||||||
- * does not sacrifice accuracy.
|
|
||||||
- *
|
|
||||||
- * For reads: global may have changed between test and return,
|
|
||||||
- * but this means someone else updated poked the clock at a later time.
|
|
||||||
- * We just need to make sure we are not seeing a backwards event.
|
|
||||||
- *
|
|
||||||
- * For updates: last_value = ret is not enough, since two vcpus could be
|
|
||||||
- * updating at the same time, and one of them could be slightly behind,
|
|
||||||
- * making the assumption that last_value always go forward fail to hold.
|
|
||||||
- */
|
|
||||||
- last = atomic64_read(&last_value);
|
|
||||||
- do {
|
|
||||||
- if (ret < last)
|
|
||||||
- return last;
|
|
||||||
- last = atomic64_cmpxchg(&last_value, last, ret);
|
|
||||||
- } while (unlikely(last != ret));
|
|
||||||
-
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
51
pkgs/os-specific/linux/kernel/xen-pvclock-resume.patch
Normal file
51
pkgs/os-specific/linux/kernel/xen-pvclock-resume.patch
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
From: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
|
||||||
|
Date: Mon, 25 Oct 2010 16:53:46 -0700
|
||||||
|
Subject: [PATCH] x86/pvclock: zero last_value on resume
|
||||||
|
|
||||||
|
If the guest domain has been suspend/resumed or migrated, then the
|
||||||
|
system clock backing the pvclock clocksource may revert to a smaller
|
||||||
|
value (ie, can be non-monotonic across the migration/save-restore).
|
||||||
|
Make sure we zero last_value in that case so that the domain
|
||||||
|
continues to see clock updates.
|
||||||
|
|
||||||
|
Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
|
||||||
|
|
||||||
|
diff --git a/arch/x86/include/asm/pvclock.h b/arch/x86/include/asm/pvclock.h
|
||||||
|
index cd02f32..6226870 100644
|
||||||
|
--- a/arch/x86/include/asm/pvclock.h
|
||||||
|
+++ b/arch/x86/include/asm/pvclock.h
|
||||||
|
@@ -11,5 +11,6 @@ unsigned long pvclock_tsc_khz(struct pvclock_vcpu_time_info *src);
|
||||||
|
void pvclock_read_wallclock(struct pvclock_wall_clock *wall,
|
||||||
|
struct pvclock_vcpu_time_info *vcpu,
|
||||||
|
struct timespec *ts);
|
||||||
|
+void pvclock_resume(void);
|
||||||
|
|
||||||
|
#endif /* _ASM_X86_PVCLOCK_H */
|
||||||
|
diff --git a/arch/x86/kernel/pvclock.c b/arch/x86/kernel/pvclock.c
|
||||||
|
index 239427c..a4f07c1 100644
|
||||||
|
--- a/arch/x86/kernel/pvclock.c
|
||||||
|
+++ b/arch/x86/kernel/pvclock.c
|
||||||
|
@@ -120,6 +120,11 @@ unsigned long pvclock_tsc_khz(struct pvclock_vcpu_time_info *src)
|
||||||
|
|
||||||
|
static atomic64_t last_value = ATOMIC64_INIT(0);
|
||||||
|
|
||||||
|
+void pvclock_resume(void)
|
||||||
|
+{
|
||||||
|
+ atomic64_set(&last_value, 0);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
cycle_t pvclock_clocksource_read(struct pvclock_vcpu_time_info *src)
|
||||||
|
{
|
||||||
|
struct pvclock_shadow_time shadow;
|
||||||
|
diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c
|
||||||
|
index b2bb5aa..5da5e53 100644
|
||||||
|
--- a/arch/x86/xen/time.c
|
||||||
|
+++ b/arch/x86/xen/time.c
|
||||||
|
@@ -426,6 +426,8 @@ void xen_timer_resume(void)
|
||||||
|
{
|
||||||
|
int cpu;
|
||||||
|
|
||||||
|
+ pvclock_resume();
|
||||||
|
+
|
||||||
|
if (xen_clockevent != &xen_vcpuop_clockevent)
|
||||||
|
return;
|
@ -4582,7 +4582,7 @@ let
|
|||||||
kernelPatches.cifs_timeout
|
kernelPatches.cifs_timeout
|
||||||
kernelPatches.no_xsave
|
kernelPatches.no_xsave
|
||||||
kernelPatches.dell_rfkill
|
kernelPatches.dell_rfkill
|
||||||
kernelPatches.revert_pvclock_sync
|
kernelPatches.xen_pvclock_resume
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user