Messages in this thread | | | Date | Wed, 18 Mar 2009 09:55:47 -0400 | From | Paul Gortmaker <> | Subject | Re: [Patch] Fix the possibility of insane return value of hpet_calibrate() against SMI. (take 2) |
| |
Yasunori Goto wrote: >>>>>> Each calibration of this has 1 milli second. >>>>>> Do you think 5 msec is too long? >>>>>> >>>>>> >>>>> This shouldn't matter when booting. Anyway, I think it's possible to >>>>> increase TICK_CALIBRATE without losing too much accuracy. >>>>> >>>>> >>>> Hmm. If the person who is trying to reduce boot time for fastboot dislikes this impact, >>>> then I'll try Vojtech-san's way. >>>> >>>> >>> That probably makes sense -- if it is extremely rare, and if you get two >>> values that are the same (within some small delta) then you probably >>> are 99.99% confident that you have the right data. >>> >> Ok. I'll make it. >> >> Thanks for your comment. >> > > Here is updated version. > > -------- > > hpet_calibrate() has a possibility of miss-calibration due to SMI. > If SMI interrupts in the while loop of calibration, then return value > will be big. This change calibrates until stabilizing by the return > value with a small value. > > > Signed-off-by: Yasunori Goto <y-goto@jp.fujitsu.com> > > > --- > drivers/char/hpet.c | 21 ++++++++++++++++++++- > 1 file changed, 20 insertions(+), 1 deletion(-) > > Index: hpet_test/drivers/char/hpet.c > =================================================================== > --- hpet_test.orig/drivers/char/hpet.c 2009-03-12 15:47:45.000000000 +0900 > +++ hpet_test/drivers/char/hpet.c 2009-03-18 11:12:42.000000000 +0900 > @@ -713,7 +713,7 @@ > */ > #define TICK_CALIBRATE (1000UL) > > -static unsigned long hpet_calibrate(struct hpets *hpetp) > +static unsigned long __hpet_calibrate(struct hpets *hpetp) > { > struct hpet_timer __iomem *timer = NULL; > unsigned long t, m, count, i, flags, start; > @@ -750,6 +750,25 @@ > return (m - start) / i; > } > > +static unsigned long hpet_calibrate(struct hpets *hpetp) > +{ > + unsigned long ret = ~0UL, tmp; > + > + /* > + * Try to calibrate until return value becomes stable small value. > + * If SMI interruption occurs in calibration loop, the return value > + * will be big. This avoids its impact. > + */ > + do { > + tmp = __hpet_calibrate(hpetp); > + if (ret <= tmp) > + break; > + ret = tmp; > + } while (1); >
For what it is worth, if a situation arose where continued calls to hpet_calibrate() represented a monotonically decreasing function, (perhaps some insane power management?) you could be stuck in this function for an unbounded amount of time. I don't expect that should ever happen, but I figured I'd mention it.
Paul.
> + > + return ret; > +} > + > int hpet_alloc(struct hpet_data *hdp) > { > u64 cap, mcfg; > >
| |