summaryrefslogtreecommitdiff
path: root/gettime.c
diff options
context:
space:
mode:
authorJens Axboe <axboe@kernel.dk>2013-02-24 21:29:35 +0100
committerJens Axboe <axboe@kernel.dk>2013-02-24 21:29:35 +0100
commite259879ea353f5695a8be662b2748c4f4d0918d9 (patch)
tree92801c768a824fd4b00ef3396a95d6fa9b05171c /gettime.c
parent7be39be8deca720afcab621c8512032a064173ba (diff)
downloadfio-e259879ea353f5695a8be662b2748c4f4d0918d9.tar.gz
fio-e259879ea353f5695a8be662b2748c4f4d0918d9.tar.bz2
gettime: add some sanity checks to platform clock
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'gettime.c')
-rw-r--r--gettime.c24
1 files changed, 21 insertions, 3 deletions
diff --git a/gettime.c b/gettime.c
index 5b85a23b..d56045c5 100644
--- a/gettime.c
+++ b/gettime.c
@@ -262,7 +262,7 @@ static unsigned long get_cycles_per_usec(void)
#define NR_TIME_ITERS 50
-static void calibrate_cpu_clock(void)
+static int calibrate_cpu_clock(void)
{
double delta, mean, S;
uint64_t avg, cycles[NR_TIME_ITERS];
@@ -279,6 +279,13 @@ static void calibrate_cpu_clock(void)
}
}
+ /*
+ * The most common platform clock breakage is returning zero
+ * indefinitely. Check for that and return failure.
+ */
+ if (!cycles[0] && !cycles[NR_TIME_ITERS - 1])
+ return 1;
+
S = sqrt(S / (NR_TIME_ITERS - 1.0));
samples = avg = 0;
@@ -305,10 +312,12 @@ static void calibrate_cpu_clock(void)
cycles_per_usec = avg;
inv_cycles_per_usec = 16777216UL / cycles_per_usec;
dprint(FD_TIME, "inv_cycles_per_usec=%lu\n", inv_cycles_per_usec);
+ return 0;
}
#else
-static void calibrate_cpu_clock(void)
+static int calibrate_cpu_clock(void)
{
+ return 1;
}
#endif
@@ -343,7 +352,9 @@ void fio_clock_init(void)
#endif
fio_clock_source_inited = fio_clock_source;
- calibrate_cpu_clock();
+
+ if (calibrate_cpu_clock())
+ tsc_reliable = 0;
/*
* If the arch sets tsc_reliable != 0, then it must be good enough
@@ -481,6 +492,13 @@ static void *clock_thread_fn(void *data)
}
log_info("cs: cpu%3d: %lu clocks seen\n", t->cpu, t->entries[CLOCK_ENTRIES - 1].tsc - t->entries[0].tsc);
+ /*
+ * The most common platform clock breakage is returning zero
+ * indefinitely. Check for that and return failure.
+ */
+ if (!t->entries[CLOCK_ENTRIES - 1].tsc && !t->entries[0].tsc)
+ return (void *) 1;
+
return NULL;
}