From a8fac230386935dfeaddcad0801c773a9d781d3a Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Thu, 29 Jun 2006 14:22:56 +0100 Subject: [PATCH] [XEN] Work around timeout bug in old Linux kernels where timeout would erroneously be set far out in the future. Signed-off-by: Keir Fraser --- xen/common/schedule.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/xen/common/schedule.c b/xen/common/schedule.c index 8d2f44be35..cb80104016 100644 --- a/xen/common/schedule.c +++ b/xen/common/schedule.c @@ -391,9 +391,30 @@ long do_set_timer_op(s_time_t timeout) struct vcpu *v = current; if ( timeout == 0 ) + { stop_timer(&v->timer); + } else + { + if ( unlikely(timeout < 0) || + unlikely((uint32_t)((timeout - NOW()) >> 50) != 0) ) + { + /* + * Linux workaround: occasionally we will see timeouts a long way + * in the future due to wrapping in Linux's jiffy time handling. + * We check for tiemouts wrapped negative, and for positive + * timeouts more than about 13 days in the future (2^50ns). + * The correct fix is to trigger an interrupt in a short while + * (since Linux in fact has pending work to do in this situation). + */ + DPRINTK("Warning: huge timeout set by domain %d (vcpu %d):" + " %"PRIx64"\n", + v->domain->domain_id, v->vcpu_id, (uint64_t)timeout); + timeout = NOW() + MILLISECS(10); + } + set_timer(&v->timer, timeout); + } return 0; } -- 2.39.5