summaryrefslogtreecommitdiff
path: root/lib/igt_gt.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2016-01-08 16:32:29 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2016-01-19 14:03:15 +0000
commita6090c71918ae4c0a54eda133081dbd1e6fe8018 (patch)
tree61d5ec695b6d2dab6840c20fd620d0977afd6172 /lib/igt_gt.c
parent571b876544933c4c6cab16065b1ade76246a7f55 (diff)
igt/gem_mmap_wc: Test cpu mmap vs wc mmap coherency
Similar to the cpu mmap vs gtt mmap coherency test. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'lib/igt_gt.c')
-rw-r--r--lib/igt_gt.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/lib/igt_gt.c b/lib/igt_gt.c
index 688ea5e6..f79728fd 100644
--- a/lib/igt_gt.c
+++ b/lib/igt_gt.c
@@ -343,3 +343,57 @@ void igt_set_stop_rings(enum stop_ring_flags flags)
"i915_ring_stop readback mismatch 0x%x vs 0x%x\n",
flags, current);
}
+
+static unsigned int clflush_size;
+
+int igt_setup_clflush(void)
+{
+ FILE *file;
+ char *line = NULL;
+ size_t size = 0;
+ int first_stanza = 1;
+ int has_clflush = 0;
+
+ if (clflush_size)
+ return 1;
+
+ file = fopen("/proc/cpuinfo", "r");
+ if (file == NULL)
+ return 0;
+
+ while (getline(&line, &size, file) != -1) {
+ if (strncmp(line, "processor", 9) == 0) {
+ if (!first_stanza)
+ break;
+ first_stanza = 0;
+ }
+
+ if (strncmp(line, "flags", 5) == 0) {
+ if (strstr(line, "clflush"))
+ has_clflush = 1;
+ }
+
+ if (strncmp(line, "clflush size", 12) == 0) {
+ char *colon = strchr(line, ':');
+ if (colon)
+ clflush_size = atoi(colon + 1);
+ }
+ }
+ free(line);
+ fclose(file);
+
+ return has_clflush && clflush_size;
+}
+
+void igt_clflush_range(void *addr, int size)
+{
+ char *p, *end;
+
+ end = (char *)addr + size;
+ p = (char *)((uintptr_t)addr & ~((uintptr_t)clflush_size - 1));
+
+ asm volatile("mfence" ::: "memory");
+ for (; p < end; p += clflush_size)
+ asm volatile("clflush %0" : "+m" (*(volatile char *)p));
+ asm volatile("mfence" ::: "memory");
+}