Messages in this thread Patch in this message | | | Date | Wed, 18 Mar 2009 11:47:04 +0900 | From | Yasunori Goto <> | Subject | [Patch] Fix the possibility of insane return value of hpet_calibrate() against SMI. (take 2) |
| |
> > > >>> 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); + + return ret; +} + int hpet_alloc(struct hpet_data *hdp) { u64 cap, mcfg; -- Yasunori Goto
| |