Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 197835
b: refs/heads/master
c: 489fb49
h: refs/heads/master
i:
  197833: c51a77d
  197831: 9263fe7
v: v3
  • Loading branch information
Glauber Costa authored and Avi Kivity committed May 19, 2010
1 parent 8637885 commit 9cacdce
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 424c32f1aa3112632a657d45698c8e7666668f78
refs/heads/master: 489fb490dbf8dab0249ad82b56688ae3842a79e8
24 changes: 24 additions & 0 deletions trunk/arch/x86/kernel/pvclock.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,11 +118,14 @@ unsigned long pvclock_tsc_khz(struct pvclock_vcpu_time_info *src)
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);
Expand All @@ -132,6 +135,27 @@ cycle_t pvclock_clocksource_read(struct pvclock_vcpu_time_info *src)
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;
}

Expand Down

0 comments on commit 9cacdce

Please sign in to comment.