dm: change timers to MONOTONIC mode
Some DM's virtual timer devices use CLOCK_REALTIME as either clock counter source or period timer source. Including: - virtual RTC - virtual PIT - virtual HPET According to Linux Manual, CLOCK_REALTIME is the 'wall clock' which is affected by discontinuous jumps in the system time. The issue is that service VM system time could be changed, either by root user manually or by NTP automatically calibration. When that happens, DM's virtual timer devices which relays on CLOCK_REALTIME will experience discontinuous time jump, and become inaccurate. It would affect both time stamp read value and period timer. Especially when service VM system time is moved backwards, WaaG's system software will lost response and be stalled for quite a long time. To solve this issue, we need to switch CLOCK_REALTIME to CLOCK_MONOTONIC. As it represents: 'A nonsettable monotonically increasing clock that measures time from some unspecified point in the past that does not change after system startup' Tracked-On: #8547 Signed-off-by: Wu Zhou <wu.zhou@intel.com> Reviewed-by: Jian Jun Chen <jian.jun.chen@intel.com>
This commit is contained in:
parent
29b3d03ac7
commit
1407dd3738
|
@ -202,7 +202,7 @@ vhpet_counter(struct vhpet *vhpet, struct timespec *nowptr)
|
|||
val = vhpet->countbase;
|
||||
|
||||
if (vhpet_counter_enabled(vhpet)) {
|
||||
if (clock_gettime(CLOCK_REALTIME, &now))
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &now))
|
||||
pr_dbg("clock_gettime returned: %s", strerror(errno));
|
||||
|
||||
/* delta = now - countbase_ts */
|
||||
|
@ -225,7 +225,7 @@ vhpet_counter(struct vhpet *vhpet, struct timespec *nowptr)
|
|||
*/
|
||||
if (nowptr) {
|
||||
pr_warn("vhpet unexpected nowptr");
|
||||
if (clock_gettime(CLOCK_REALTIME, nowptr))
|
||||
if (clock_gettime(CLOCK_MONOTONIC, nowptr))
|
||||
pr_dbg("clock_gettime returned: %s", strerror(errno));
|
||||
}
|
||||
}
|
||||
|
@ -366,7 +366,7 @@ vhpet_timer_handler(void *a, uint64_t nexp)
|
|||
|
||||
vhpet_timer_interrupt(vhpet, n);
|
||||
|
||||
if (clock_gettime(CLOCK_REALTIME, &now))
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &now))
|
||||
pr_dbg("clock_gettime returned: %s", strerror(errno));
|
||||
|
||||
if (acrn_timer_gettime(vhpet_tmr(vhpet, n), &tmrts))
|
||||
|
@ -548,7 +548,7 @@ vhpet_start_counting(struct vhpet *vhpet)
|
|||
{
|
||||
int i;
|
||||
|
||||
if (clock_gettime(CLOCK_REALTIME, &vhpet->countbase_ts))
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &vhpet->countbase_ts))
|
||||
pr_dbg("clock_gettime returned: %s", strerror(errno));
|
||||
|
||||
/* Restart the timers based on the main counter base value */
|
||||
|
@ -639,7 +639,7 @@ vhpet_timer_update_config(struct vhpet *vhpet, int n, uint64_t data,
|
|||
* - Timer remains in periodic mode
|
||||
*/
|
||||
if (!vhpet_timer_enabled(vhpet, n)) {
|
||||
if (clock_gettime(CLOCK_REALTIME, &now))
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &now))
|
||||
pr_dbg("clock_gettime returned: %s", strerror(errno));
|
||||
vhpet_stop_timer(vhpet, n, &now, true);
|
||||
} else if (!(oldval & (HPET_TCNF_TYPE | HPET_TCNF_INT_ENB)) ||
|
||||
|
@ -998,7 +998,7 @@ vhpet_init(struct vmctx *ctx)
|
|||
arg->timer_num = i;
|
||||
|
||||
tmr = &vhpet->timer[i].tmrlst[j].t;
|
||||
tmr->clockid = CLOCK_REALTIME;
|
||||
tmr->clockid = CLOCK_MONOTONIC;
|
||||
error = acrn_timer_init(tmr, vhpet_timer_handler, arg);
|
||||
|
||||
if (error) {
|
||||
|
|
|
@ -107,7 +107,7 @@ ticks_elapsed_since(const struct timespec *since)
|
|||
{
|
||||
struct timespec ts;
|
||||
|
||||
if (clock_gettime(CLOCK_REALTIME, &ts))
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &ts))
|
||||
pr_dbg("clock_gettime returned: %s", strerror(errno));
|
||||
|
||||
if (timespeccmp(&ts, since, <=))
|
||||
|
@ -192,7 +192,7 @@ pit_load_ce(struct channel *c)
|
|||
c->nullcnt = false;
|
||||
c->crbyte = 0;
|
||||
|
||||
if (clock_gettime(CLOCK_REALTIME, &c->start_ts))
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &c->start_ts))
|
||||
pr_dbg("clock_gettime returned: %s", strerror(errno));
|
||||
|
||||
if (c->initial == 0 || c->initial > 0x10000) {
|
||||
|
@ -330,7 +330,7 @@ pit_timer_start_cntr0(struct vpit *vpit)
|
|||
sigevt.sigev_notify = SIGEV_THREAD;
|
||||
sigevt.sigev_notify_function = vpit_timer_handler;
|
||||
|
||||
if (timer_create(CLOCK_REALTIME, &sigevt, &c->timer_id))
|
||||
if (timer_create(CLOCK_MONOTONIC, &sigevt, &c->timer_id))
|
||||
pr_dbg("timer_create returned: %s", strerror(errno));
|
||||
|
||||
vpit_timer_arg[c->timer_idx].active = true;
|
||||
|
@ -360,7 +360,7 @@ pit_update_counter(struct vpit *vpit, struct channel *c, bool latch,
|
|||
|
||||
c->initial = PIT_HZ_TO_TICKS(100);
|
||||
delta_ticks = 0;
|
||||
if (clock_gettime(CLOCK_REALTIME, &c->start_ts))
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &c->start_ts))
|
||||
pr_dbg("clock_gettime returned: %s", strerror(errno));
|
||||
} else
|
||||
delta_ticks = ticks_elapsed_since(&c->start_ts);
|
||||
|
|
|
@ -1148,11 +1148,11 @@ vrtc_init(struct vmctx *ctx)
|
|||
pthread_mutex_unlock(&vrtc->mtx);
|
||||
|
||||
/* init periodic interrupt timer */
|
||||
vrtc->periodic_timer.clockid = CLOCK_REALTIME;
|
||||
vrtc->periodic_timer.clockid = CLOCK_MONOTONIC;
|
||||
acrn_timer_init(&vrtc->periodic_timer, vrtc_periodic_timer, vrtc);
|
||||
|
||||
/* init update interrupt timer(1s)*/
|
||||
vrtc->update_timer.clockid = CLOCK_REALTIME;
|
||||
vrtc->update_timer.clockid = CLOCK_MONOTONIC;
|
||||
acrn_timer_init(&vrtc->update_timer, vrtc_update_timer, vrtc);
|
||||
vrtc_start_timer(&vrtc->update_timer, 1, 0);
|
||||
|
||||
|
|
Loading…
Reference in New Issue