diff options
-rw-r--r-- | lib/igt_gt.c | 54 | ||||
-rw-r--r-- | lib/igt_gt.h | 3 | ||||
-rw-r--r-- | tests/gem_mmap_gtt.c | 54 | ||||
-rw-r--r-- | tests/gem_mmap_wc.c | 29 |
4 files changed, 88 insertions, 52 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"); +} diff --git a/lib/igt_gt.h b/lib/igt_gt.h index b70bbd15..4f8eff50 100644 --- a/lib/igt_gt.h +++ b/lib/igt_gt.h @@ -74,4 +74,7 @@ enum stop_ring_flags igt_to_stop_ring_flag(int ring); void igt_set_stop_rings(enum stop_ring_flags flags); enum stop_ring_flags igt_get_stop_rings(void); +int igt_setup_clflush(void); +void igt_clflush_range(void *addr, int size); + #endif /* IGT_GT_H */ diff --git a/tests/gem_mmap_gtt.c b/tests/gem_mmap_gtt.c index 7f3ca68d..292216ce 100644 --- a/tests/gem_mmap_gtt.c +++ b/tests/gem_mmap_gtt.c @@ -253,56 +253,6 @@ test_write_gtt(int fd) munmap(src, OBJECT_SIZE); } -static unsigned int clflush_size; -static int setup_clflush(void) -{ - FILE *file; - char *line = NULL; - size_t size = 0; - int first_stanza = 1; - int has_clflush = 0; - - 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; -} - -static void clflush(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"); -} - static void test_coherency(int fd) { @@ -310,7 +260,7 @@ test_coherency(int fd) uint32_t *gtt, *cpu; int i; - igt_require(setup_clflush()); + igt_require(igt_setup_clflush()); handle = gem_create(fd, OBJECT_SIZE); @@ -321,7 +271,7 @@ test_coherency(int fd) for (i = 0; i < OBJECT_SIZE / 64; i++) { int x = 16*i + (i%16); gtt[x] = i; - clflush(&cpu[x], sizeof(cpu[x])); + igt_clflush_range(&cpu[x], sizeof(cpu[x])); igt_assert_eq(cpu[x], i); } diff --git a/tests/gem_mmap_wc.c b/tests/gem_mmap_wc.c index 91588a40..8ecb9cca 100644 --- a/tests/gem_mmap_wc.c +++ b/tests/gem_mmap_wc.c @@ -218,6 +218,33 @@ test_write(int fd) } static void +test_coherency(int fd) +{ + uint32_t handle; + uint32_t *wc, *cpu; + int i; + + igt_require(igt_setup_clflush()); + + handle = gem_create(fd, OBJECT_SIZE); + + wc = gem_mmap__wc(fd, handle, 0, OBJECT_SIZE, PROT_READ | PROT_WRITE); + cpu = gem_mmap__cpu(fd, handle, 0, OBJECT_SIZE, PROT_READ | PROT_WRITE); + gem_set_domain(fd, handle, I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT); + + for (i = 0; i < OBJECT_SIZE / 64; i++) { + int x = 16*i + (i%16); + wc[x] = i; + igt_clflush_range(&cpu[x], sizeof(cpu[x])); + igt_assert_eq(cpu[x], i); + } + + munmap(cpu, OBJECT_SIZE); + munmap(wc, OBJECT_SIZE); + gem_close(fd, handle); +} + +static void test_write_gtt(int fd) { uint32_t dst; @@ -446,6 +473,8 @@ igt_main test_read(fd); igt_subtest("write") test_write(fd); + igt_subtest("coherency") + test_coherency(fd); igt_subtest("write-gtt") test_write_gtt(fd); igt_subtest("read-write") |