summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2014-08-16 21:04:41 +0200
committercinap_lenrek <cinap_lenrek@felloff.net>2014-08-16 21:04:41 +0200
commit773b57b676526975059e5ba3858cfde6d8b50ceb (patch)
treee0c4d5e398cb1b2665ba1966dbbeae666f8c9ad0
parentce0b77e2b9bd4669844d0356f8e49d2f4878bac8 (diff)
kernel: fix todfix() race
we have to recheck the condition under tod lock, otherwise another process can come in and updated tod.last and tod.off and once we have the lock, we would make time jump backwards.
-rw-r--r--sys/src/9/port/tod.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/sys/src/9/port/tod.c b/sys/src/9/port/tod.c
index 424e0f290..b88f721af 100644
--- a/sys/src/9/port/tod.c
+++ b/sys/src/9/port/tod.c
@@ -198,11 +198,13 @@ todfix(void)
uvlong x;
ticks = fastticks(nil);
+ diff = ticks - tod.last;
+ if(diff <= tod.hz)
+ return;
+ ilock(&tod);
diff = ticks - tod.last;
if(diff > tod.hz){
- ilock(&tod);
-
/* convert to epoch */
mul64fract(&x, diff, tod.multiplier);
if(x > 30000000000ULL) iprint("todfix %llud\n", x);
@@ -211,9 +213,8 @@ if(x > 30000000000ULL) iprint("todfix %llud\n", x);
/* protect against overflows */
tod.last = ticks;
tod.off = x;
-
- iunlock(&tod);
}
+ iunlock(&tod);
}
long