summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorJens Axboe <axboe@kernel.dk>2012-12-09 20:29:00 +0100
committerJens Axboe <axboe@kernel.dk>2012-12-09 20:29:00 +0100
commitfa80feae51331fb170e784459fa1359d7ec3a963 (patch)
treeaa23a345eb99081d44b1afb92bf60c7d4d6eec10 /arch
parent5a90bb5f50f641a65f879ae09dbd65440e0ab2a6 (diff)
downloadfio-fa80feae51331fb170e784459fa1359d7ec3a963.tar.gz
fio-fa80feae51331fb170e784459fa1359d7ec3a963.tar.bz2
Add check for invariant TSC on x86 and use TSC is default clock if reliable
TSC is by far the fastest clock we can use. Check the CPUID bits for whether it is both constant rate AND synced across cores. If it is, we can use it as our default clock source. Fio will default to this clock source on x86 if no other clock source is specifically given with clocksource= in the job file. Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'arch')
-rw-r--r--arch/arch-x86-common.h43
-rw-r--r--arch/arch-x86.h2
-rw-r--r--arch/arch-x86_64.h2
3 files changed, 47 insertions, 0 deletions
diff --git a/arch/arch-x86-common.h b/arch/arch-x86-common.h
new file mode 100644
index 00000000..1e623544
--- /dev/null
+++ b/arch/arch-x86-common.h
@@ -0,0 +1,43 @@
+#ifndef FIO_ARCH_X86_COMMON
+#define FIO_ARCH_X86_COMMON
+
+static inline void do_cpuid(unsigned int *eax, unsigned int *ebx,
+ unsigned int *ecx, unsigned int *edx)
+{
+ unsigned int id = *eax;
+
+ asm("movl %4, %%eax;"
+ "cpuid;"
+ "movl %%eax, %0;"
+ "movl %%ebx, %1;"
+ "movl %%ecx, %2;"
+ "movl %%edx, %3;"
+ : "=r" (*eax), "=r" (*ebx), "=r" (*ecx), "=r" (*edx)
+ : "r" (id)
+ : "eax", "ebx", "ecx", "edx");
+}
+
+#define ARCH_HAVE_INIT
+extern int tsc_reliable;
+static inline int arch_init(char *envp[])
+{
+ unsigned int eax, ebx, ecx, edx;
+
+ /*
+ * Check for TSC
+ */
+ eax = 1;
+ do_cpuid(&eax, &ebx, &ecx, &edx);
+ if (!(edx & (1U << 4)))
+ return 0;
+
+ /*
+ * Check for constant rate and synced (across cores) TSC
+ */
+ eax = 0x80000007;
+ do_cpuid(&eax, &ebx, &ecx, &edx);
+ tsc_reliable = edx & (1U << 8);
+ return 0;
+}
+
+#endif
diff --git a/arch/arch-x86.h b/arch/arch-x86.h
index 1ededd84..48030060 100644
--- a/arch/arch-x86.h
+++ b/arch/arch-x86.h
@@ -1,6 +1,8 @@
#ifndef ARCH_X86_H
#define ARCH_X86_H
+#include "arch-x86-common.h"
+
#define FIO_ARCH (arch_i386)
#ifndef __NR_ioprio_set
diff --git a/arch/arch-x86_64.h b/arch/arch-x86_64.h
index 29e681f2..d8b0933b 100644
--- a/arch/arch-x86_64.h
+++ b/arch/arch-x86_64.h
@@ -1,6 +1,8 @@
#ifndef ARCH_X86_64_h
#define ARCH_X86_64_h
+#include "arch-x86-common.h"
+
#define FIO_ARCH (arch_x86_64)
#ifndef __NR_ioprio_set