* [PATCH 2/5] igt/gem_tiled_wc: Exercise wc mmaps with swizzling
2014-11-17 11:37 [PATCH 1/5] igt/gem_mmap_wc: Exercise mmap(wc) interface Chris Wilson
@ 2014-11-17 11:37 ` Chris Wilson
2014-11-17 11:37 ` [PATCH 3/5] igt/gem_gtt_speed: compare against WC mmaps Chris Wilson
` (4 subsequent siblings)
5 siblings, 0 replies; 11+ messages in thread
From: Chris Wilson @ 2014-11-17 11:37 UTC (permalink / raw)
To: intel-gfx; +Cc: Akash Goel
This exercises both the wc mmappings and the extended get_tiling ioctl.
Userspace cannot handle bit17 swizzling through wc mmaps (because bit17
requires swizzling based on the actual physical address of the page -
which is unknown to userspace) and so we need an extended get_tiling
ioctl to report the actual as well as the logical swizzling on an
object. We then check that the contents of the object are tiled and
swizzled correctly when viewed through a wc mmap.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
tests/.gitignore | 1 +
tests/Makefile.sources | 1 +
tests/gem_tiled_wc.c | 237 +++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 239 insertions(+)
create mode 100644 tests/gem_tiled_wc.c
diff --git a/tests/.gitignore b/tests/.gitignore
index 07d3b5a..c5ee6fd 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -101,6 +101,7 @@ gem_tiled_pread
gem_tiled_pread_pwrite
gem_tiled_swapping
gem_tiled_wb
+gem_tiled_wc
gem_tiling_max_stride
gem_unfence_active_buffers
gem_unref_active_buffers
diff --git a/tests/Makefile.sources b/tests/Makefile.sources
index 97aab02..04fbe81 100644
--- a/tests/Makefile.sources
+++ b/tests/Makefile.sources
@@ -134,6 +134,7 @@ TESTS_progs = \
gem_tiled_pread_pwrite \
gem_tiled_swapping \
gem_tiled_wb \
+ gem_tiled_wc \
gem_tiling_max_stride \
gem_unfence_active_buffers \
gem_unref_active_buffers \
diff --git a/tests/gem_tiled_wc.c b/tests/gem_tiled_wc.c
new file mode 100644
index 0000000..633299e
--- /dev/null
+++ b/tests/gem_tiled_wc.c
@@ -0,0 +1,237 @@
+/*
+ * Copyright © 2009 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+/** @file gem_tiled_wc.c
+ *
+ * This is a test of write-combining mmap's behavior on tiled objects
+ * with respect to the reported swizzling value.
+ *
+ * The goal is to exercise the complications that arise when using a linear
+ * view of a tiled object that is subject to hardware swizzling. This is
+ * useful to check that we are presenting the correct view of the object
+ * to userspace, and that userspace has to respect the swizzle.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+#include "drm.h"
+#include "ioctl_wrappers.h"
+#include "drmtest.h"
+#include "intel_io.h"
+#include "intel_chipset.h"
+
+#define WIDTH 512
+#define HEIGHT 512
+#define SIZE (WIDTH*HEIGHT*sizeof(uint32_t))
+
+#define PAGE_SIZE 4096
+
+static int tile_width;
+static int tile_height;
+static int tile_size;
+
+static uint32_t
+create_bo(int fd)
+{
+ uint32_t handle;
+ uint32_t *data;
+ int i;
+
+ handle = gem_create(fd, SIZE);
+ gem_set_tiling(fd, handle, I915_TILING_X, WIDTH * sizeof(uint32_t));
+
+ /* Fill the BO with dwords starting at start_val */
+ data = gem_mmap__wc(fd, handle, 0, SIZE, PROT_READ | PROT_WRITE);
+ for (i = 0; i < WIDTH*HEIGHT; i++)
+ data[i] = i;
+ munmap(data, SIZE);
+
+ return handle;
+}
+
+static int
+swizzle_bit(int bit, int offset)
+{
+ return (offset & (1 << bit)) >> (bit - 6);
+}
+
+/* Translate from a swizzled offset in the tiled buffer to the corresponding
+ * value from the original linear buffer.
+ */
+static uint32_t
+calculate_expected(int offset)
+{
+ int tile_off = offset & (tile_size - 1);
+ int tile_base = offset & -tile_size;
+ int tile_index = tile_base / tile_size;
+ int tiles_per_row = 4*WIDTH / tile_width;
+
+ /* base x,y values from the tile (page) index. */
+ int base_y = tile_index / tiles_per_row * tile_height;
+ int base_x = tile_index % tiles_per_row * (tile_width/4);
+
+ /* x, y offsets within the tile */
+ int tile_y = tile_off / tile_width;
+ int tile_x = (tile_off % tile_width) / 4;
+
+ igt_debug("%3d, %3d, %3d,%3d\n", base_x, base_y, tile_x, tile_y);
+ return (base_y + tile_y) * WIDTH + base_x + tile_x;
+}
+
+static void
+get_tiling(int fd, uint32_t handle, uint32_t *tiling, uint32_t *swizzle)
+{
+ struct drm_i915_gem_get_tiling2 {
+ uint32_t handle;
+ uint32_t tiling_mode;
+ uint32_t swizzle_mode;
+ uint32_t phys_swizzle_mode;
+ } arg;
+#define DRM_IOCTL_I915_GEM_GET_TILING2 DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_TILING, struct drm_i915_gem_get_tiling2)
+
+ memset(&arg, 0, sizeof(arg));
+ arg.handle = handle;
+
+ do_or_die(drmIoctl(fd, DRM_IOCTL_I915_GEM_GET_TILING2, &arg));
+ igt_require(arg.phys_swizzle_mode == arg.swizzle_mode);
+
+ *tiling = arg.tiling_mode;
+ *swizzle = arg.swizzle_mode;
+}
+
+igt_simple_main
+{
+ int fd;
+ int i, iter = 100;
+ uint32_t tiling, swizzle;
+ uint32_t handle;
+
+ fd = drm_open_any();
+ igt_require_mmap_wc(fd);
+
+ handle = create_bo(fd);
+ get_tiling(fd, handle, &tiling, &swizzle);
+
+ if (IS_GEN2(intel_get_drm_devid(fd))) {
+ tile_height = 16;
+ tile_width = 128;
+ tile_size = 2048;
+ } else {
+ tile_height = 8;
+ tile_width = 512;
+ tile_size = PAGE_SIZE;
+ }
+
+ /* Read a bunch of random subsets of the data and check that they come
+ * out right.
+ */
+ for (i = 0; i < iter; i++) {
+ int size = WIDTH * HEIGHT * 4;
+ int offset = (random() % size) & ~3;
+ int len = (random() % size) & ~3;
+ int first_page, last_page;
+ uint32_t *linear;
+ int j;
+
+ if (len == 0)
+ len = 4;
+
+ if (offset + len > size)
+ len = size - offset;
+
+ if (i == 0) {
+ offset = 0;
+ len = size;
+ }
+
+ first_page = offset & ~(PAGE_SIZE-1);
+ last_page = (offset + len + PAGE_SIZE) & ~(PAGE_SIZE-1);
+ offset -= first_page;
+
+ linear = gem_mmap__wc(fd, handle, first_page, last_page - first_page, PROT_READ);
+ igt_assert(linear);
+
+ /* Translate from offsets in the read buffer to the swizzled
+ * address that it corresponds to. This is the opposite of
+ * what Mesa does (calculate offset to be read given the linear
+ * offset it's looking for).
+ */
+ for (j = offset; j < offset + len; j += 4) {
+ uint32_t expected_val, found_val;
+ int swizzled_offset;
+ const char *swizzle_str;
+
+ switch (swizzle) {
+ case I915_BIT_6_SWIZZLE_NONE:
+ swizzled_offset = j;
+ swizzle_str = "none";
+ break;
+ case I915_BIT_6_SWIZZLE_9:
+ swizzled_offset = j ^
+ swizzle_bit(9, j);
+ swizzle_str = "bit9";
+ break;
+ case I915_BIT_6_SWIZZLE_9_10:
+ swizzled_offset = j ^
+ swizzle_bit(9, j) ^
+ swizzle_bit(10, j);
+ swizzle_str = "bit9^10";
+ break;
+ case I915_BIT_6_SWIZZLE_9_11:
+ swizzled_offset = j ^
+ swizzle_bit(9, j) ^
+ swizzle_bit(11, j);
+ swizzle_str = "bit9^11";
+ break;
+ case I915_BIT_6_SWIZZLE_9_10_11:
+ swizzled_offset = j ^
+ swizzle_bit(9, j) ^
+ swizzle_bit(10, j) ^
+ swizzle_bit(11, j);
+ swizzle_str = "bit9^10^11";
+ break;
+ default:
+ igt_skip("unknown swizzling");
+ break;
+ }
+ expected_val = calculate_expected(swizzled_offset);
+ found_val = linear[j / 4];
+ igt_assert_f(expected_val == found_val,
+ "Bad read [%d]: %d instead of %d at 0x%08x "
+ "for read from 0x%08x to 0x%08x, swizzle=%s\n",
+ i, found_val, expected_val, j,
+ offset, offset + len,
+ swizzle_str);
+ munmap(linear, last_page - first_page);
+ }
+ }
+
+ close(fd);
+}
--
1.9.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH 3/5] igt/gem_gtt_speed: compare against WC mmaps
2014-11-17 11:37 [PATCH 1/5] igt/gem_mmap_wc: Exercise mmap(wc) interface Chris Wilson
2014-11-17 11:37 ` [PATCH 2/5] igt/gem_tiled_wc: Exercise wc mmaps with swizzling Chris Wilson
@ 2014-11-17 11:37 ` Chris Wilson
2014-11-17 11:37 ` [PATCH 4/5] igt/gem_fence_upload: Add comparison against wc mmaps Chris Wilson
` (3 subsequent siblings)
5 siblings, 0 replies; 11+ messages in thread
From: Chris Wilson @ 2014-11-17 11:37 UTC (permalink / raw)
To: intel-gfx; +Cc: Akash Goel
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
tests/gem_gtt_speed.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 62 insertions(+), 1 deletion(-)
diff --git a/tests/gem_gtt_speed.c b/tests/gem_gtt_speed.c
index c68b8e4..d5e745e 100644
--- a/tests/gem_gtt_speed.c
+++ b/tests/gem_gtt_speed.c
@@ -206,6 +206,27 @@ int main(int argc, char **argv)
igt_info("Time to read %dk through a GTT map: %7.3fµs\n",
size/1024, elapsed(&start, &end, loop));
+ if (gem_mmap__has_wc(fd)) {
+ gettimeofday(&start, NULL);
+ for (loop = 0; loop < 1000; loop++) {
+ uint32_t *base = gem_mmap__wc(fd, handle, 0, size, PROT_READ | PROT_WRITE);
+ volatile uint32_t *ptr = base;
+ int x = 0;
+
+ for (i = 0; i < size/sizeof(*ptr); i++)
+ x += ptr[i];
+
+ /* force overtly clever gcc to actually compute x */
+ ptr[0] = x;
+
+ munmap(base, size);
+ }
+ gettimeofday(&end, NULL);
+ igt_info("Time to read %dk through a WC map: %7.3fµs\n",
+ size/1024, elapsed(&start, &end, loop));
+ }
+
+
/* mmap write */
gettimeofday(&start, NULL);
for (loop = 0; loop < 1000; loop++) {
@@ -221,6 +242,23 @@ int main(int argc, char **argv)
igt_info("Time to write %dk through a GTT map: %7.3fµs\n",
size/1024, elapsed(&start, &end, loop));
+ if (gem_mmap__has_wc(fd)) {
+ /* mmap write */
+ gettimeofday(&start, NULL);
+ for (loop = 0; loop < 1000; loop++) {
+ uint32_t *base = gem_mmap__wc(fd, handle, 0, size, PROT_READ | PROT_WRITE);
+ volatile uint32_t *ptr = base;
+
+ for (i = 0; i < size/sizeof(*ptr); i++)
+ ptr[i] = i;
+
+ munmap(base, size);
+ }
+ gettimeofday(&end, NULL);
+ igt_info("Time to write %dk through a WC map: %7.3fµs\n",
+ size/1024, elapsed(&start, &end, loop));
+ }
+
/* mmap clear */
gettimeofday(&start, NULL);
for (loop = 0; loop < 1000; loop++) {
@@ -232,6 +270,19 @@ int main(int argc, char **argv)
igt_info("Time to clear %dk through a GTT map: %7.3fµs\n",
size/1024, elapsed(&start, &end, loop));
+ if (gem_mmap__has_wc(fd)) {
+ /* mmap clear */
+ gettimeofday(&start, NULL);
+ for (loop = 0; loop < 1000; loop++) {
+ uint32_t *base = gem_mmap__wc(fd, handle, 0, size, PROT_READ | PROT_WRITE);
+ memset(base, 0, size);
+ munmap(base, size);
+ }
+ gettimeofday(&end, NULL);
+ igt_info("Time to clear %dk through a WC map: %7.3fµs\n",
+ size/1024, elapsed(&start, &end, loop));
+ }
+
gettimeofday(&start, NULL);{
uint32_t *base = gem_mmap(fd, handle, size, PROT_READ | PROT_WRITE);
for (loop = 0; loop < 1000; loop++)
@@ -241,6 +292,17 @@ int main(int argc, char **argv)
igt_info("Time to clear %dk through a cached GTT map: %7.3fµs\n",
size/1024, elapsed(&start, &end, loop));
+ if (gem_mmap__has_wc(fd)) {
+ gettimeofday(&start, NULL);{
+ uint32_t *base = gem_mmap__wc(fd, handle, 0, size, PROT_READ | PROT_WRITE);
+ for (loop = 0; loop < 1000; loop++)
+ memset(base, 0, size);
+ munmap(base, size);
+ } gettimeofday(&end, NULL);
+ igt_info("Time to clear %dk through a cached WC map: %7.3fµs\n",
+ size/1024, elapsed(&start, &end, loop));
+ }
+
/* mmap read */
gettimeofday(&start, NULL);
for (loop = 0; loop < 1000; loop++) {
@@ -323,7 +385,6 @@ int main(int argc, char **argv)
size *= 4;
}
-
}
gem_close(fd, handle);
--
1.9.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH 4/5] igt/gem_fence_upload: Add comparison against wc mmaps
2014-11-17 11:37 [PATCH 1/5] igt/gem_mmap_wc: Exercise mmap(wc) interface Chris Wilson
2014-11-17 11:37 ` [PATCH 2/5] igt/gem_tiled_wc: Exercise wc mmaps with swizzling Chris Wilson
2014-11-17 11:37 ` [PATCH 3/5] igt/gem_gtt_speed: compare against WC mmaps Chris Wilson
@ 2014-11-17 11:37 ` Chris Wilson
2014-11-17 11:37 ` [PATCH 5/5] igt/gem_concurrent_blit: Exercise wc mappings Chris Wilson
` (2 subsequent siblings)
5 siblings, 0 replies; 11+ messages in thread
From: Chris Wilson @ 2014-11-17 11:37 UTC (permalink / raw)
To: intel-gfx; +Cc: Akash Goel
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
tests/gem_fence_upload.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 73 insertions(+)
diff --git a/tests/gem_fence_upload.c b/tests/gem_fence_upload.c
index 88da5dc..81f797b 100644
--- a/tests/gem_fence_upload.c
+++ b/tests/gem_fence_upload.c
@@ -267,6 +267,21 @@ static void *no_contention(void *closure)
return NULL;
}
+static void *wc_mmap(void *closure)
+{
+ struct thread_contention *t = closure;
+ int n;
+
+ for (n = 0; n < t->loops; n++) {
+ uint32_t *ptr = gem_mmap__wc(t->fd, t->handle, 0, OBJECT_SIZE, PROT_READ | PROT_WRITE);
+ igt_assert(ptr);
+ memset(ptr + (rand() % 256) * 4096 / 4, 0, 4096);
+ munmap(ptr, OBJECT_SIZE);
+ }
+
+ return NULL;
+}
+
static void thread_contention(void)
{
const int loops = 4096;
@@ -322,6 +337,62 @@ static void thread_contention(void)
igt_assert(tiled[1] > 0.75 * tiled[0]);
}
+static void wc_contention(void)
+{
+ const int loops = 4096;
+ int n, count;
+ int fd, num_fences;
+ double linear[2], tiled[2];
+
+ fd = drm_open_any();
+ igt_require_mmap_wc(fd);
+
+ num_fences = gem_available_fences(fd);
+ igt_require(num_fences > 0);
+
+ for (count = 1; count < 4*num_fences; count *= 2) {
+ struct timeval start, end;
+ struct thread_contention threads[count];
+
+ for (n = 0; n < count; n++) {
+ threads[n].handle = gem_create(fd, OBJECT_SIZE);
+ threads[n].loops = loops;
+ threads[n].fd = fd;
+ }
+
+ gettimeofday(&start, NULL);
+ for (n = 0; n < count; n++)
+ pthread_create(&threads[n].thread, NULL, wc_mmap, &threads[n]);
+ for (n = 0; n < count; n++)
+ pthread_join(threads[n].thread, NULL);
+ gettimeofday(&end, NULL);
+
+ linear[count != 2] = count * loops / elapsed(&start, &end) / (OBJECT_SIZE / 4096);
+ igt_info("Contended upload rate for %d linear threads/wc: %7.3fMiB/s\n", count, linear[count != 2]);
+
+ for (n = 0; n < count; n++)
+ gem_set_tiling(fd, threads[n].handle, I915_TILING_X, 1024);
+
+ gettimeofday(&start, NULL);
+ for (n = 0; n < count; n++)
+ pthread_create(&threads[n].thread, NULL, wc_mmap, &threads[n]);
+ for (n = 0; n < count; n++)
+ pthread_join(threads[n].thread, NULL);
+ gettimeofday(&end, NULL);
+
+ tiled[count != 2] = count * loops / elapsed(&start, &end) / (OBJECT_SIZE / 4096);
+ igt_info("Contended upload rate for %d tiled threads/wc: %7.3fMiB/s\n", count, tiled[count != 2]);
+
+ for (n = 0; n < count; n++) {
+ gem_close(fd, threads[n].handle);
+ }
+ }
+
+ errno = 0;
+ igt_assert(linear[1] > 0.75 * linear[0]);
+ igt_assert(tiled[1] > 0.75 * tiled[0]);
+}
+
igt_main
{
igt_skip_on_simulation();
@@ -330,6 +401,8 @@ igt_main
performance();
igt_subtest("thread-contention")
thread_contention();
+ igt_subtest("wc-contention")
+ wc_contention();
igt_subtest("thread-performance-read")
thread_performance(READ);
igt_subtest("thread-performance-write")
--
1.9.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH 5/5] igt/gem_concurrent_blit: Exercise wc mappings
2014-11-17 11:37 [PATCH 1/5] igt/gem_mmap_wc: Exercise mmap(wc) interface Chris Wilson
` (2 preceding siblings ...)
2014-11-17 11:37 ` [PATCH 4/5] igt/gem_fence_upload: Add comparison against wc mmaps Chris Wilson
@ 2014-11-17 11:37 ` Chris Wilson
2014-11-17 11:40 ` [PATCH 1/5] igt/gem_mmap_wc: Exercise mmap(wc) interface Chris Wilson
2014-11-17 18:36 ` Daniel Vetter
5 siblings, 0 replies; 11+ messages in thread
From: Chris Wilson @ 2014-11-17 11:37 UTC (permalink / raw)
To: intel-gfx; +Cc: Akash Goel
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
tests/gem_concurrent_blit.c | 233 +++++++++++++++++++++++++++++++++++++-------
1 file changed, 198 insertions(+), 35 deletions(-)
diff --git a/tests/gem_concurrent_blit.c b/tests/gem_concurrent_blit.c
index 7d8d628..4c4cd9f 100644
--- a/tests/gem_concurrent_blit.c
+++ b/tests/gem_concurrent_blit.c
@@ -59,6 +59,12 @@ int fd, devid, gen;
struct intel_batchbuffer *batch;
static void
+nop_release_bo(drm_intel_bo *bo)
+{
+ drm_intel_bo_unreference(bo);
+}
+
+static void
prw_set_bo(drm_intel_bo *bo, uint32_t val, int width, int height)
{
int size = width * height, i;
@@ -159,6 +165,27 @@ gttX_create_bo(drm_intel_bufmgr *bufmgr, int width, int height)
}
static drm_intel_bo *
+wc_create_bo(drm_intel_bufmgr *bufmgr, int width, int height)
+{
+ drm_intel_bo *bo;
+
+ igt_require_mmap_wc(fd);
+
+ bo = unmapped_create_bo(bufmgr, width, height);
+ bo->virtual = gem_mmap__wc(fd, bo->handle, 0, bo->size, PROT_READ | PROT_WRITE);
+ return bo;
+}
+
+static void
+wc_release_bo(drm_intel_bo *bo)
+{
+ munmap(bo->virtual, bo->size);
+ bo->virtual = NULL;
+
+ nop_release_bo(bo);
+}
+
+static drm_intel_bo *
gpu_create_bo(drm_intel_bufmgr *bufmgr, int width, int height)
{
return unmapped_create_bo(bufmgr, width, height);
@@ -271,26 +298,62 @@ gpu_cmp_bo(drm_intel_bo *bo, uint32_t val, int width, int height, drm_intel_bo *
cpu_cmp_bo(tmp, val, width, height, NULL);
}
-struct access_mode {
+const struct access_mode {
+ const char *name;
void (*set_bo)(drm_intel_bo *bo, uint32_t val, int w, int h);
void (*cmp_bo)(drm_intel_bo *bo, uint32_t val, int w, int h, drm_intel_bo *tmp);
drm_intel_bo *(*create_bo)(drm_intel_bufmgr *bufmgr, int width, int height);
- const char *name;
-};
-
-struct access_mode access_modes[] = {
- { .set_bo = prw_set_bo, .cmp_bo = prw_cmp_bo,
- .create_bo = unmapped_create_bo, .name = "prw" },
- { .set_bo = cpu_set_bo, .cmp_bo = cpu_cmp_bo,
- .create_bo = unmapped_create_bo, .name = "cpu" },
- { .set_bo = gtt_set_bo, .cmp_bo = gtt_cmp_bo,
- .create_bo = gtt_create_bo, .name = "gtt" },
- { .set_bo = gtt_set_bo, .cmp_bo = gtt_cmp_bo,
- .create_bo = gttX_create_bo, .name = "gttX" },
- { .set_bo = gpu_set_bo, .cmp_bo = gpu_cmp_bo,
- .create_bo = gpu_create_bo, .name = "gpu" },
- { .set_bo = gpu_set_bo, .cmp_bo = gpu_cmp_bo,
- .create_bo = gpuX_create_bo, .name = "gpuX" },
+ void (*release_bo)(drm_intel_bo *bo);
+} access_modes[] = {
+ {
+ .name = "prw",
+ .set_bo = prw_set_bo,
+ .cmp_bo = prw_cmp_bo,
+ .create_bo = unmapped_create_bo,
+ .release_bo = nop_release_bo,
+ },
+ {
+ .name = "cpu",
+ .set_bo = cpu_set_bo,
+ .cmp_bo = cpu_cmp_bo,
+ .create_bo = unmapped_create_bo,
+ .release_bo = nop_release_bo,
+ },
+ {
+ .name = "gtt",
+ .set_bo = gtt_set_bo,
+ .cmp_bo = gtt_cmp_bo,
+ .create_bo = gtt_create_bo,
+ .release_bo = nop_release_bo,
+ },
+ {
+ .name = "gttX",
+ .set_bo = gtt_set_bo,
+ .cmp_bo = gtt_cmp_bo,
+ .create_bo = gttX_create_bo,
+ .release_bo = nop_release_bo,
+ },
+ {
+ .name = "wc",
+ .set_bo = gtt_set_bo,
+ .cmp_bo = gtt_cmp_bo,
+ .create_bo = wc_create_bo,
+ .release_bo = wc_release_bo,
+ },
+ {
+ .name = "gpu",
+ .set_bo = gpu_set_bo,
+ .cmp_bo = gpu_cmp_bo,
+ .create_bo = gpu_create_bo,
+ .release_bo = nop_release_bo,
+ },
+ {
+ .name = "gpuX",
+ .set_bo = gpu_set_bo,
+ .cmp_bo = gpu_cmp_bo,
+ .create_bo = gpuX_create_bo,
+ .release_bo = nop_release_bo,
+ },
};
#define MAX_NUM_BUFFERS 1024
@@ -332,7 +395,63 @@ static void blt_copy_bo(drm_intel_bo *dst, drm_intel_bo *src)
width, height, 32);
}
-static void do_overwrite_source(struct access_mode *mode,
+static void cpu_copy_bo(drm_intel_bo *dst, drm_intel_bo *src)
+{
+ const int size = width * height * sizeof(uint32_t);
+ void *d, *s;
+
+ gem_set_domain(fd, src->handle, I915_GEM_DOMAIN_CPU, 0);
+ gem_set_domain(fd, dst->handle, I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
+ s = gem_mmap__cpu(fd, src->handle, 0, size, PROT_READ);
+ igt_assert(s != NULL);
+ d = gem_mmap__cpu(fd, dst->handle, 0, size, PROT_WRITE);
+ igt_assert(d != NULL);
+
+ memcpy(d, s, size);
+
+ munmap(d, size);
+ munmap(s, size);
+}
+
+static void gtt_copy_bo(drm_intel_bo *dst, drm_intel_bo *src)
+{
+ const int size = width * height * sizeof(uint32_t);
+ void *d, *s;
+
+ gem_set_domain(fd, src->handle, I915_GEM_DOMAIN_GTT, 0);
+ gem_set_domain(fd, dst->handle, I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
+
+ s = gem_mmap__gtt(fd, src->handle, size, PROT_READ);
+ igt_assert(s != NULL);
+ d = gem_mmap__gtt(fd, dst->handle, size, PROT_WRITE);
+ igt_assert(d != NULL);
+
+ memcpy(d, s, size);
+
+ munmap(d, size);
+ munmap(s, size);
+}
+
+static void wc_copy_bo(drm_intel_bo *dst, drm_intel_bo *src)
+{
+ const int size = width * height * sizeof(uint32_t);
+ void *d, *s;
+
+ gem_set_domain(fd, src->handle, I915_GEM_DOMAIN_GTT, 0);
+ gem_set_domain(fd, dst->handle, I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
+
+ s = gem_mmap__wc(fd, src->handle, 0, size, PROT_READ);
+ igt_assert(s != NULL);
+ d = gem_mmap__wc(fd, dst->handle, 0, size, PROT_WRITE);
+ igt_assert(d != NULL);
+
+ memcpy(d, s, size);
+
+ munmap(d, size);
+ munmap(s, size);
+}
+
+static void do_overwrite_source(const struct access_mode *mode,
drm_intel_bo **src, drm_intel_bo **dst,
drm_intel_bo *dummy,
do_copy do_copy_func)
@@ -352,7 +471,7 @@ static void do_overwrite_source(struct access_mode *mode,
mode->cmp_bo(dst[i], i, width, height, dummy);
}
-static void do_early_read(struct access_mode *mode,
+static void do_early_read(const struct access_mode *mode,
drm_intel_bo **src, drm_intel_bo **dst,
drm_intel_bo *dummy,
do_copy do_copy_func)
@@ -368,7 +487,7 @@ static void do_early_read(struct access_mode *mode,
mode->cmp_bo(dst[i], 0xdeadbeef, width, height, dummy);
}
-static void do_gpu_read_after_write(struct access_mode *mode,
+static void do_gpu_read_after_write(const struct access_mode *mode,
drm_intel_bo **src, drm_intel_bo **dst,
drm_intel_bo *dummy,
do_copy do_copy_func)
@@ -386,18 +505,18 @@ static void do_gpu_read_after_write(struct access_mode *mode,
mode->cmp_bo(dst[i], 0xabcdabcd, width, height, dummy);
}
-typedef void (*do_test)(struct access_mode *mode,
+typedef void (*do_test)(const struct access_mode *mode,
drm_intel_bo **src, drm_intel_bo **dst,
drm_intel_bo *dummy,
do_copy do_copy_func);
-typedef void (*run_wrap)(struct access_mode *mode,
+typedef void (*run_wrap)(const struct access_mode *mode,
drm_intel_bo **src, drm_intel_bo **dst,
drm_intel_bo *dummy,
do_test do_test_func,
do_copy do_copy_func);
-static void run_single(struct access_mode *mode,
+static void run_single(const struct access_mode *mode,
drm_intel_bo **src, drm_intel_bo **dst,
drm_intel_bo *dummy,
do_test do_test_func,
@@ -406,7 +525,7 @@ static void run_single(struct access_mode *mode,
do_test_func(mode, src, dst, dummy, do_copy_func);
}
-static void run_interruptible(struct access_mode *mode,
+static void run_interruptible(const struct access_mode *mode,
drm_intel_bo **src, drm_intel_bo **dst,
drm_intel_bo *dummy,
do_test do_test_func,
@@ -418,37 +537,44 @@ static void run_interruptible(struct access_mode *mode,
do_test_func(mode, src, dst, dummy, do_copy_func);
}
-static void run_forked(struct access_mode *mode,
+static void run_forked(const struct access_mode *mode,
drm_intel_bo **src, drm_intel_bo **dst,
drm_intel_bo *dummy,
do_test do_test_func,
do_copy do_copy_func)
{
const int old_num_buffers = num_buffers;
- drm_intel_bufmgr *bufmgr;
num_buffers /= 16;
num_buffers += 2;
igt_fork(child, 16) {
+ drm_intel_bufmgr *bufmgr;
+
/* recreate process local variables */
bufmgr = drm_intel_bufmgr_gem_init(fd, 4096);
drm_intel_bufmgr_gem_enable_reuse(bufmgr);
+
batch = intel_batchbuffer_alloc(bufmgr, devid);
+
for (int i = 0; i < num_buffers; i++) {
src[i] = mode->create_bo(bufmgr, width, height);
dst[i] = mode->create_bo(bufmgr, width, height);
}
dummy = mode->create_bo(bufmgr, width, height);
+
for (int loop = 0; loop < 10; loop++)
do_test_func(mode, src, dst, dummy, do_copy_func);
+
/* as we borrow the fd, we need to reap our bo */
for (int i = 0; i < num_buffers; i++) {
- drm_intel_bo_unreference(src[i]);
- drm_intel_bo_unreference(dst[i]);
+ mode->release_bo(src[i]);
+ mode->release_bo(dst[i]);
}
- drm_intel_bo_unreference(dummy);
+ mode->release_bo(dummy);
+
intel_batchbuffer_free(batch);
+
drm_intel_bufmgr_destroy(bufmgr);
}
@@ -457,6 +583,40 @@ static void run_forked(struct access_mode *mode,
num_buffers = old_num_buffers;
}
+static void bit17_require(void)
+{
+ struct drm_i915_gem_get_tiling2 {
+ uint32_t handle;
+ uint32_t tiling_mode;
+ uint32_t swizzle_mode;
+ uint32_t phys_swizzle_mode;
+ } arg;
+#define DRM_IOCTL_I915_GEM_GET_TILING2 DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_TILING, struct drm_i915_gem_get_tiling2)
+
+ memset(&arg, 0, sizeof(arg));
+ arg.handle = gem_create(fd, 4096);
+ gem_set_tiling(fd, arg.handle, I915_TILING_X, 512);
+
+ do_or_die(drmIoctl(fd, DRM_IOCTL_I915_GEM_GET_TILING2, &arg));
+ gem_close(fd, arg.handle);
+ igt_require(arg.phys_swizzle_mode == arg.swizzle_mode);
+}
+
+static void cpu_require(void)
+{
+ bit17_require();
+}
+
+static void gtt_require(void)
+{
+}
+
+static void wc_require(void)
+{
+ bit17_require();
+ igt_require_mmap_wc(fd);
+}
+
static void bcs_require(void)
{
}
@@ -467,16 +627,19 @@ static void rcs_require(void)
}
static void
-run_basic_modes(struct access_mode *mode,
+run_basic_modes(const struct access_mode *mode,
drm_intel_bo **src, drm_intel_bo **dst,
drm_intel_bo *dummy, const char *suffix,
run_wrap run_wrap_func)
{
- struct {
+ const struct {
const char *prefix;
do_copy copy;
void (*require)(void);
} pipelines[] = {
+ { "cpu", cpu_copy_bo, cpu_require },
+ { "gtt", gtt_copy_bo, gtt_require },
+ { "wc", wc_copy_bo, wc_require },
{ "bcs", blt_copy_bo, bcs_require },
{ "rcs", render_copy_bo, rcs_require },
{ NULL, NULL }
@@ -507,7 +670,7 @@ run_basic_modes(struct access_mode *mode,
}
static void
-run_modes(struct access_mode *mode)
+run_modes(const struct access_mode *mode)
{
drm_intel_bo *src[MAX_NUM_BUFFERS], *dst[MAX_NUM_BUFFERS], *dummy = NULL;
drm_intel_bufmgr *bufmgr;
@@ -532,10 +695,10 @@ run_modes(struct access_mode *mode)
igt_fixture {
for (int i = 0; i < num_buffers; i++) {
- drm_intel_bo_unreference(src[i]);
- drm_intel_bo_unreference(dst[i]);
+ mode->release_bo(src[i]);
+ mode->release_bo(dst[i]);
}
- drm_intel_bo_unreference(dummy);
+ mode->release_bo(dummy);
intel_batchbuffer_free(batch);
drm_intel_bufmgr_destroy(bufmgr);
}
--
1.9.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 11+ messages in thread* Re: [PATCH 1/5] igt/gem_mmap_wc: Exercise mmap(wc) interface
2014-11-17 11:37 [PATCH 1/5] igt/gem_mmap_wc: Exercise mmap(wc) interface Chris Wilson
` (3 preceding siblings ...)
2014-11-17 11:37 ` [PATCH 5/5] igt/gem_concurrent_blit: Exercise wc mappings Chris Wilson
@ 2014-11-17 11:40 ` Chris Wilson
2014-11-17 18:36 ` Daniel Vetter
5 siblings, 0 replies; 11+ messages in thread
From: Chris Wilson @ 2014-11-17 11:40 UTC (permalink / raw)
To: intel-gfx; +Cc: Akash Goel
On Mon, Nov 17, 2014 at 11:37:19AM +0000, Chris Wilson wrote:
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> ---
> lib/ioctl_wrappers.c | 81 +++++++++++
> lib/ioctl_wrappers.h | 5 +
> tests/.gitignore | 1 +
> tests/Makefile.am | 2 +
> tests/Makefile.sources | 1 +
> tests/gem_mmap_wc.c | 370 +++++++++++++++++++++++++++++++++++++++++++++++++
> 6 files changed, 460 insertions(+)
> create mode 100644 tests/gem_mmap_wc.c
>
> diff --git a/lib/ioctl_wrappers.c b/lib/ioctl_wrappers.c
> index f423237..8316f0d 100644
> --- a/lib/ioctl_wrappers.c
> +++ b/lib/ioctl_wrappers.c
> @@ -463,10 +463,91 @@ void *gem_mmap__gtt(int fd, uint32_t handle, int size, int prot)
> ptr = mmap64(0, size, prot, MAP_SHARED, fd, mmap_arg.offset);
> if (ptr == MAP_FAILED)
> ptr = NULL;
> + else
> + errno = 0;
>
> return ptr;
> }
>
> +struct local_i915_gem_mmap_v2 {
> + uint32_t handle;
> + uint32_t pad;
> + uint64_t offset;
> + uint64_t size;
> + uint64_t addr_ptr;
> + uint64_t flags;
> +#define I915_MMAP_WC 0x1
> +};
> +#define LOCAL_IOCTL_I915_GEM_MMAP_v2 DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MMAP, struct local_i915_gem_mmap_v2)
> +
> +bool gem_mmap__has_wc(int fd)
> +{
> + static int has_wc = -1;
> +
> + if (has_wc == -1) {
> + struct drm_i915_getparam gp;
> + int val = -1;
> +
> + has_wc = 0;
> +
> + memset(&gp, 0, sizeof(gp));
> + gp.param = 29; /* MMAP_VERSION */
Now 30.
-Chris
--
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: [PATCH 1/5] igt/gem_mmap_wc: Exercise mmap(wc) interface
2014-11-17 11:37 [PATCH 1/5] igt/gem_mmap_wc: Exercise mmap(wc) interface Chris Wilson
` (4 preceding siblings ...)
2014-11-17 11:40 ` [PATCH 1/5] igt/gem_mmap_wc: Exercise mmap(wc) interface Chris Wilson
@ 2014-11-17 18:36 ` Daniel Vetter
2014-11-25 8:58 ` [PATCH] igt/gem_mmap_wc: Add the invalid flags subtest akash.goel
5 siblings, 1 reply; 11+ messages in thread
From: Daniel Vetter @ 2014-11-17 18:36 UTC (permalink / raw)
To: Chris Wilson; +Cc: intel-gfx, Akash Goel
On Mon, Nov 17, 2014 at 11:37:19AM +0000, Chris Wilson wrote:
> +/**
> + * gem_mmap__wc:
> + * @fd: open i915 drm file descriptor
> + * @handle: gem buffer object handle
> + * @offset: offset in the gem buffer of te mmap arena
> + * @size: size of the mmap arena
> + * @prot: memory protection bits as used by mmap()
> + *
> + * This functions wraps up procedure to establish a memory mapping through
> + * direct cpu access, bypassing the gpu and cpu caches completely.
Nit: Since this is the same for gtt wc mappings shouldn't we mention that
this bypasses "all cpu caches and also the gpu system agent (used by gtt
mmaps)"? Otherwise awesome and it looks like Akash has not time to supply
the ioctl(invalid) == -EINVAL tests and take a look at this too and then
I'll pull it all in.
-Daniel
> + *
> + * Returns: A pointer to the created memory mapping.
> + */
> +void *gem_mmap__wc(int fd, uint32_t handle, int offset, int size, int prot)
> +{
> + struct local_i915_gem_mmap_v2 arg;
> +
> + if (!gem_mmap__has_wc(fd)) {
> + errno = ENOSYS;
> + return NULL;
> + }
> +
> + memset(&arg, 0, sizeof(arg));
> + arg.handle = handle;
> + arg.offset = offset;
> + arg.size = size;
> + arg.flags = I915_MMAP_WC;
> + if (drmIoctl(fd, LOCAL_IOCTL_I915_GEM_MMAP_v2, &arg))
> + return NULL;
> +
> + errno = 0;
> + return (void *)(uintptr_t)arg.addr_ptr;
> +}
> +
> /**
> * gem_mmap__cpu:
> * @fd: open i915 drm file descriptor
> diff --git a/lib/ioctl_wrappers.h b/lib/ioctl_wrappers.h
> index d13408c..9e7edad 100644
> --- a/lib/ioctl_wrappers.h
> +++ b/lib/ioctl_wrappers.h
> @@ -62,6 +62,11 @@ void gem_execbuf(int fd, struct drm_i915_gem_execbuffer2 *execbuf);
>
> void *gem_mmap__gtt(int fd, uint32_t handle, int size, int prot);
> void *gem_mmap__cpu(int fd, uint32_t handle, int offset, int size, int prot);
> +
> +bool gem_mmap__has_wc(int fd);
> +void *gem_mmap__wc(int fd, uint32_t handle, int offset, int size, int prot);
> +#define igt_require_mmap_wc(x) igt_require(gem_mmap__has_wc(x))
> +
> /**
> * gem_mmap:
> *
> diff --git a/tests/.gitignore b/tests/.gitignore
> index 6e6ab58..07d3b5a 100644
> --- a/tests/.gitignore
> +++ b/tests/.gitignore
> @@ -58,6 +58,7 @@ gem_madvise
> gem_media_fill
> gem_mmap
> gem_mmap_gtt
> +gem_mmap_wc
> gem_mmap_offset_exhaustion
> gem_multi_bsd_sync_loop
> gem_non_secure_batch
> diff --git a/tests/Makefile.am b/tests/Makefile.am
> index 3762737..78cbe04 100644
> --- a/tests/Makefile.am
> +++ b/tests/Makefile.am
> @@ -58,6 +58,8 @@ gem_flink_race_CFLAGS = $(AM_CFLAGS) $(THREAD_CFLAGS)
> gem_flink_race_LDADD = $(LDADD) -lpthread
> gem_mmap_gtt_CFLAGS = $(AM_CFLAGS) $(THREAD_CFLAGS)
> gem_mmap_gtt_LDADD = $(LDADD) -lpthread
> +gem_mmap_wc_CFLAGS = $(AM_CFLAGS) $(THREAD_CFLAGS)
> +gem_mmap_wc_LDADD = $(LDADD) -lpthread
> gem_threaded_access_tiled_CFLAGS = $(AM_CFLAGS) $(THREAD_CFLAGS)
> gem_threaded_access_tiled_LDADD = $(LDADD) -lpthread
> gem_tiled_swapping_CFLAGS = $(AM_CFLAGS) $(THREAD_CFLAGS)
> diff --git a/tests/Makefile.sources b/tests/Makefile.sources
> index 2677bf7..97aab02 100644
> --- a/tests/Makefile.sources
> +++ b/tests/Makefile.sources
> @@ -42,6 +42,7 @@ TESTS_progs_M = \
> gem_madvise \
> gem_mmap \
> gem_mmap_gtt \
> + gem_mmap_wc \
> gem_partial_pwrite_pread \
> gem_persistent_relocs \
> gem_pipe_control_store_loop \
> diff --git a/tests/gem_mmap_wc.c b/tests/gem_mmap_wc.c
> new file mode 100644
> index 0000000..87140ff
> --- /dev/null
> +++ b/tests/gem_mmap_wc.c
> @@ -0,0 +1,370 @@
> +/*
> + * Copyright © 2011 Intel Corporation
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the next
> + * paragraph) shall be included in all copies or substantial portions of the
> + * Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
> + * IN THE SOFTWARE.
> + *
> + * Authors:
> + * Chris Wilson <chris@chris-wilson.co.uk>
> + *
> + */
> +
> +#define _GNU_SOURCE
> +#include <unistd.h>
> +#include <stdlib.h>
> +#include <stdio.h>
> +#include <string.h>
> +#include <fcntl.h>
> +#include <inttypes.h>
> +#include <pthread.h>
> +#include <errno.h>
> +#include <sys/stat.h>
> +#include <sys/ioctl.h>
> +#include "drm.h"
> +#include "ioctl_wrappers.h"
> +#include "drmtest.h"
> +#include "igt_debugfs.h"
> +
> +static int OBJECT_SIZE = 16*1024*1024;
> +
> +static void set_domain(int fd, uint32_t handle)
> +{
> + gem_set_domain(fd, handle, I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
> +}
> +
> +static void *
> +mmap_bo(int fd, uint32_t handle)
> +{
> + void *ptr;
> +
> + ptr = gem_mmap__wc(fd, handle, 0, OBJECT_SIZE, PROT_READ | PROT_WRITE);
> + igt_assert(ptr && ptr != MAP_FAILED);
> +
> + return ptr;
> +}
> +
> +static void *
> +create_pointer(int fd)
> +{
> + uint32_t handle;
> + void *ptr;
> +
> + handle = gem_create(fd, OBJECT_SIZE);
> +
> + ptr = mmap_bo(fd, handle);
> + set_domain(fd, handle);
> +
> + gem_close(fd, handle);
> +
> + return ptr;
> +}
> +
> +static void
> +test_copy(int fd)
> +{
> + void *src, *dst;
> +
> + igt_require_mmap_wc(fd);
> +
> + /* copy from a fresh src to fresh dst to force pagefault on both */
> + src = create_pointer(fd);
> + dst = create_pointer(fd);
> +
> + memcpy(dst, src, OBJECT_SIZE);
> + memcpy(src, dst, OBJECT_SIZE);
> +
> + munmap(dst, OBJECT_SIZE);
> + munmap(src, OBJECT_SIZE);
> +}
> +
> +enum test_read_write {
> + READ_BEFORE_WRITE,
> + READ_AFTER_WRITE,
> +};
> +
> +static void
> +test_read_write(int fd, enum test_read_write order)
> +{
> + uint32_t handle;
> + void *ptr;
> + volatile uint32_t val = 0;
> +
> + handle = gem_create(fd, OBJECT_SIZE);
> + set_domain(fd, handle);
> +
> + ptr = mmap_bo(fd, handle);
> + igt_assert(ptr != MAP_FAILED);
> +
> + if (order == READ_BEFORE_WRITE) {
> + val = *(uint32_t *)ptr;
> + *(uint32_t *)ptr = val;
> + } else {
> + *(uint32_t *)ptr = val;
> + val = *(uint32_t *)ptr;
> + }
> +
> + gem_close(fd, handle);
> + munmap(ptr, OBJECT_SIZE);
> +}
> +
> +static void
> +test_read_write2(int fd, enum test_read_write order)
> +{
> + uint32_t handle;
> + void *r, *w;
> + volatile uint32_t val = 0;
> +
> + igt_require_mmap_wc(fd);
> +
> + handle = gem_create(fd, OBJECT_SIZE);
> + set_domain(fd, handle);
> +
> + r = gem_mmap__wc(fd, handle, 0, OBJECT_SIZE, PROT_READ);
> + igt_assert(r != MAP_FAILED);
> +
> + w = gem_mmap__wc(fd, handle, 0, OBJECT_SIZE, PROT_READ | PROT_WRITE);
> + igt_assert(w != MAP_FAILED);
> +
> + if (order == READ_BEFORE_WRITE) {
> + val = *(uint32_t *)r;
> + *(uint32_t *)w = val;
> + } else {
> + *(uint32_t *)w = val;
> + val = *(uint32_t *)r;
> + }
> +
> + gem_close(fd, handle);
> + munmap(r, OBJECT_SIZE);
> + munmap(w, OBJECT_SIZE);
> +}
> +
> +static void
> +test_write(int fd)
> +{
> + void *src;
> + uint32_t dst;
> +
> + igt_require_mmap_wc(fd);
> +
> + /* copy from a fresh src to fresh dst to force pagefault on both */
> + src = create_pointer(fd);
> + dst = gem_create(fd, OBJECT_SIZE);
> +
> + gem_write(fd, dst, 0, src, OBJECT_SIZE);
> +
> + gem_close(fd, dst);
> + munmap(src, OBJECT_SIZE);
> +}
> +
> +static void
> +test_write_gtt(int fd)
> +{
> + uint32_t dst;
> + char *dst_gtt;
> + void *src;
> +
> + igt_require_mmap_wc(fd);
> +
> + dst = gem_create(fd, OBJECT_SIZE);
> + set_domain(fd, dst);
> +
> + /* prefault object into gtt */
> + dst_gtt = mmap_bo(fd, dst);
> + memset(dst_gtt, 0, OBJECT_SIZE);
> + munmap(dst_gtt, OBJECT_SIZE);
> +
> + src = create_pointer(fd);
> +
> + gem_write(fd, dst, 0, src, OBJECT_SIZE);
> +
> + gem_close(fd, dst);
> + munmap(src, OBJECT_SIZE);
> +}
> +
> +static void
> +test_read(int fd)
> +{
> + void *dst;
> + uint32_t src;
> +
> + igt_require_mmap_wc(fd);
> +
> + /* copy from a fresh src to fresh dst to force pagefault on both */
> + dst = create_pointer(fd);
> + src = gem_create(fd, OBJECT_SIZE);
> +
> + gem_read(fd, src, 0, dst, OBJECT_SIZE);
> +
> + gem_close(fd, src);
> + munmap(dst, OBJECT_SIZE);
> +}
> +
> +static void
> +test_write_cpu_read_wc(int fd)
> +{
> + uint32_t handle;
> + uint32_t *src, *dst;
> +
> + igt_require_mmap_wc(fd);
> +
> + handle = gem_create(fd, OBJECT_SIZE);
> +
> + dst = gem_mmap__wc(fd, handle, 0, OBJECT_SIZE, PROT_READ);
> + igt_assert(dst != (uint32_t *)MAP_FAILED);
> +
> + src = gem_mmap__cpu(fd, handle, 0, OBJECT_SIZE, PROT_WRITE);
> + igt_assert(src != (uint32_t *)MAP_FAILED);
> +
> + gem_close(fd, handle);
> +
> + memset(src, 0xaa, OBJECT_SIZE);
> + set_domain(fd, handle);
> + igt_assert(memcmp(dst, src, OBJECT_SIZE) == 0);
> +
> + munmap(src, OBJECT_SIZE);
> + munmap(dst, OBJECT_SIZE);
> +}
> +
> +static void
> +test_write_gtt_read_wc(int fd)
> +{
> + uint32_t handle;
> + uint32_t *src, *dst;
> +
> + igt_require_mmap_wc(fd);
> +
> + handle = gem_create(fd, OBJECT_SIZE);
> + set_domain(fd, handle);
> +
> + dst = gem_mmap__wc(fd, handle, 0, OBJECT_SIZE, PROT_READ);
> + igt_assert(dst != (uint32_t *)MAP_FAILED);
> +
> + src = gem_mmap__gtt(fd, handle, OBJECT_SIZE, PROT_WRITE);
> + igt_assert(src != (uint32_t *)MAP_FAILED);
> +
> + gem_close(fd, handle);
> +
> + memset(src, 0xaa, OBJECT_SIZE);
> + igt_assert(memcmp(dst, src, OBJECT_SIZE) == 0);
> +
> + munmap(src, OBJECT_SIZE);
> + munmap(dst, OBJECT_SIZE);
> +}
> +
> +struct thread_fault_concurrent {
> + pthread_t thread;
> + int id;
> + uint32_t **ptr;
> +};
> +
> +static void *
> +thread_fault_concurrent(void *closure)
> +{
> + struct thread_fault_concurrent *t = closure;
> + uint32_t val = 0;
> + int n;
> +
> + for (n = 0; n < 32; n++) {
> + if (n & 1)
> + *t->ptr[(n + t->id) % 32] = val;
> + else
> + val = *t->ptr[(n + t->id) % 32];
> + }
> +
> + return NULL;
> +}
> +
> +static void
> +test_fault_concurrent(int fd)
> +{
> + uint32_t *ptr[32];
> + struct thread_fault_concurrent thread[64];
> + int n;
> +
> + igt_require_mmap_wc(fd);
> +
> + for (n = 0; n < 32; n++) {
> + ptr[n] = create_pointer(fd);
> + }
> +
> + for (n = 0; n < 64; n++) {
> + thread[n].ptr = ptr;
> + thread[n].id = n;
> + pthread_create(&thread[n].thread, NULL, thread_fault_concurrent, &thread[n]);
> + }
> +
> + for (n = 0; n < 64; n++)
> + pthread_join(thread[n].thread, NULL);
> +
> + for (n = 0; n < 32; n++) {
> + munmap(ptr[n], OBJECT_SIZE);
> + }
> +}
> +
> +static void
> +run_without_prefault(int fd,
> + void (*func)(int fd))
> +{
> + igt_disable_prefault();
> + func(fd);
> + igt_enable_prefault();
> +}
> +
> +int fd;
> +
> +igt_main
> +{
> + if (igt_run_in_simulation())
> + OBJECT_SIZE = 1 * 1024 * 1024;
> +
> + igt_fixture
> + fd = drm_open_any();
> +
> + igt_subtest("copy")
> + test_copy(fd);
> + igt_subtest("read")
> + test_read(fd);
> + igt_subtest("write")
> + test_write(fd);
> + igt_subtest("write-gtt")
> + test_write_gtt(fd);
> + igt_subtest("read-write")
> + test_read_write(fd, READ_BEFORE_WRITE);
> + igt_subtest("write-read")
> + test_read_write(fd, READ_AFTER_WRITE);
> + igt_subtest("read-write-distinct")
> + test_read_write2(fd, READ_BEFORE_WRITE);
> + igt_subtest("write-read-distinct")
> + test_read_write2(fd, READ_AFTER_WRITE);
> + igt_subtest("fault-concurrent")
> + test_fault_concurrent(fd);
> + igt_subtest("read-no-prefault")
> + run_without_prefault(fd, test_read);
> + igt_subtest("write-no-prefault")
> + run_without_prefault(fd, test_write);
> + igt_subtest("write-gtt-no-prefault")
> + run_without_prefault(fd, test_write_gtt);
> + igt_subtest("write-cpu-read-wc")
> + test_write_cpu_read_wc(fd);
> + igt_subtest("write-gtt-read-wc")
> + test_write_gtt_read_wc(fd);
> +
> + igt_fixture
> + close(fd);
> +}
> --
> 1.9.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 11+ messages in thread* [PATCH] igt/gem_mmap_wc: Add the invalid flags subtest
2014-11-17 18:36 ` Daniel Vetter
@ 2014-11-25 8:58 ` akash.goel
2014-11-25 11:30 ` Daniel Vetter
0 siblings, 1 reply; 11+ messages in thread
From: akash.goel @ 2014-11-25 8:58 UTC (permalink / raw)
To: intel-gfx; +Cc: Akash Goel
From: Akash Goel <akash.goel@intel.com>
A new subtest added to validate the new version of gem_mmap ioctl,
for creating the wc mappings, on yet to be supported flags.
Older kernel is also checked against the flags field, which should
be treated as a don't care by it.
Signed-off-by: Akash Goel <akash.goel@intel.com>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
tests/gem_mmap_wc.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 66 insertions(+)
diff --git a/tests/gem_mmap_wc.c b/tests/gem_mmap_wc.c
index 6f91a89..f923553 100644
--- a/tests/gem_mmap_wc.c
+++ b/tests/gem_mmap_wc.c
@@ -41,6 +41,17 @@
#include "drmtest.h"
#include "igt_debugfs.h"
+struct local_i915_gem_mmap_v2 {
+ uint32_t handle;
+ uint32_t pad;
+ uint64_t offset;
+ uint64_t size;
+ uint64_t addr_ptr;
+ uint64_t flags;
+#define I915_MMAP_WC 0x1
+};
+#define LOCAL_IOCTL_I915_GEM_MMAP_v2 DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MMAP, struct local_i915_gem_mmap_v2)
+
static int OBJECT_SIZE = 16*1024*1024;
static void set_domain(int fd, uint32_t handle)
@@ -75,6 +86,59 @@ create_pointer(int fd)
}
static void
+test_invalid_flags(int fd)
+{
+ struct drm_i915_getparam gp;
+ struct local_i915_gem_mmap_v2 arg;
+ uint64_t flag = I915_MMAP_WC;
+ int val = -1;
+
+ memset(&arg, 0, sizeof(arg));
+ arg.handle = gem_create(fd, 4096);
+ arg.offset = 0;
+ arg.size = 4096;
+
+ memset(&gp, 0, sizeof(gp));
+ gp.param = 30; /* MMAP_VERSION */
+ gp.value = &val;
+
+ /* Do we have the new mmap_ioctl? */
+ do_ioctl(fd, DRM_IOCTL_I915_GETPARAM, &gp);
+
+ if (val >= 1) {
+ /*
+ * Only MMAP_WC flag is supported in version 1, so any other
+ * flag should be rejected.
+ */
+ flag <<= 1;
+ while (flag) {
+ arg.flags = flag;
+ igt_assert(drmIoctl(fd,
+ LOCAL_IOCTL_I915_GEM_MMAP_v2,
+ &arg) == -1);
+ igt_assert_eq(errno, EINVAL);
+ flag <<= 1;
+ }
+ } else {
+ /*
+ * flags field should be ignored by older kernel
+ * and so irrespective of the flag value passed,
+ * mmap call should succeed
+ */
+ while (flag) {
+ arg.flags = flag;
+ igt_assert(drmIoctl(fd,
+ LOCAL_IOCTL_I915_GEM_MMAP_v2,
+ &arg) == 0);
+ munmap(arg.addr_ptr, 4096);
+ flag <<= 1;
+ }
+ }
+
+ gem_close(fd, arg.handle);
+}
+
+static void
test_copy(int fd)
{
void *src, *dst;
@@ -331,6 +395,8 @@ igt_main
igt_fixture
fd = drm_open_any();
+ igt_subtest("invalid flags")
+ test_invalid_flags(fd);
igt_subtest("copy")
test_copy(fd);
igt_subtest("read")
--
1.9.2
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 11+ messages in thread* Re: [PATCH] igt/gem_mmap_wc: Add the invalid flags subtest
2014-11-25 8:58 ` [PATCH] igt/gem_mmap_wc: Add the invalid flags subtest akash.goel
@ 2014-11-25 11:30 ` Daniel Vetter
2014-12-03 12:58 ` Akash Goel
2014-12-04 4:41 ` [PATCH v2] " akash.goel
0 siblings, 2 replies; 11+ messages in thread
From: Daniel Vetter @ 2014-11-25 11:30 UTC (permalink / raw)
To: akash.goel; +Cc: intel-gfx
On Tue, Nov 25, 2014 at 02:28:52PM +0530, akash.goel@intel.com wrote:
> From: Akash Goel <akash.goel@intel.com>
>
> A new subtest added to validate the new version of gem_mmap ioctl,
> for creating the wc mappings, on yet to be supported flags.
> Older kernel is also checked against the flags field, which should
> be treated as a don't care by it.
>
> Signed-off-by: Akash Goel <akash.goel@intel.com>
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> ---
> tests/gem_mmap_wc.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 66 insertions(+)
>
> diff --git a/tests/gem_mmap_wc.c b/tests/gem_mmap_wc.c
> index 6f91a89..f923553 100644
> --- a/tests/gem_mmap_wc.c
> +++ b/tests/gem_mmap_wc.c
> @@ -41,6 +41,17 @@
> #include "drmtest.h"
> #include "igt_debugfs.h"
>
> +struct local_i915_gem_mmap_v2 {
> + uint32_t handle;
> + uint32_t pad;
> + uint64_t offset;
> + uint64_t size;
> + uint64_t addr_ptr;
> + uint64_t flags;
> +#define I915_MMAP_WC 0x1
> +};
> +#define LOCAL_IOCTL_I915_GEM_MMAP_v2 DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MMAP, struct local_i915_gem_mmap_v2)
> +
> static int OBJECT_SIZE = 16*1024*1024;
>
> static void set_domain(int fd, uint32_t handle)
> @@ -75,6 +86,59 @@ create_pointer(int fd)
> }
>
> static void
> +test_invalid_flags(int fd)
> +{
> + struct drm_i915_getparam gp;
> + struct local_i915_gem_mmap_v2 arg;
> + uint64_t flag = I915_MMAP_WC;
> + int val = -1;
> +
> + memset(&arg, 0, sizeof(arg));
> + arg.handle = gem_create(fd, 4096);
> + arg.offset = 0;
> + arg.size = 4096;
> +
> + memset(&gp, 0, sizeof(gp));
> + gp.param = 30; /* MMAP_VERSION */
> + gp.value = &val;
> +
> + /* Do we have the new mmap_ioctl? */
> + do_ioctl(fd, DRM_IOCTL_I915_GETPARAM, &gp);
> +
> + if (val >= 1) {
> + /*
> + * Only MMAP_WC flag is supported in version 1, so any other
> + * flag should be rejected.
> + */
> + flag <<= 1;
> + while (flag) {
> + arg.flags = flag;
> + igt_assert(drmIoctl(fd,
> + LOCAL_IOCTL_I915_GEM_MMAP_v2,
> + &arg) == -1);
> + igt_assert_eq(errno, EINVAL);
> + flag <<= 1;
> + }
> + } else {
> + /*
> + * flags field should be ignored by older kernel
> + * and so irrespective of the flag value passed,
> + * mmap call should succeed
> + */
> + while (flag) {
> + arg.flags = flag;
> + igt_assert(drmIoctl(fd,
> + LOCAL_IOCTL_I915_GEM_MMAP_v2,
> + &arg) == 0);
> + munmap(arg.addr_ptr, 4096);
> + flag <<= 1;
> + }
> + }
Imo just skip when the new flag stuff isn't available.
> +
> + gem_close(fd, arg.handle);
> +}
> +
> +static void
> test_copy(int fd)
> {
> void *src, *dst;
> @@ -331,6 +395,8 @@ igt_main
> igt_fixture
> fd = drm_open_any();
>
> + igt_subtest("invalid flags")
s/ /-/
Also can you please add invalid-foo tests for all the other ioctl
paramters, too? That's an existing gap in our coverage and general rule is
that the next person to touch it gets to fill it out (it's been a while
though since that was last required, we have fairly good coverage
nowadays).
Thanks, Daniel
> + test_invalid_flags(fd);
> igt_subtest("copy")
> test_copy(fd);
> igt_subtest("read")
> --
> 1.9.2
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: [PATCH] igt/gem_mmap_wc: Add the invalid flags subtest
2014-11-25 11:30 ` Daniel Vetter
@ 2014-12-03 12:58 ` Akash Goel
2014-12-04 4:41 ` [PATCH v2] " akash.goel
1 sibling, 0 replies; 11+ messages in thread
From: Akash Goel @ 2014-12-03 12:58 UTC (permalink / raw)
To: Daniel Vetter; +Cc: intel-gfx
On Tue, 2014-11-25 at 12:30 +0100, Daniel Vetter wrote:
> On Tue, Nov 25, 2014 at 02:28:52PM +0530, akash.goel@intel.com wrote:
> > From: Akash Goel <akash.goel@intel.com>
> >
> > A new subtest added to validate the new version of gem_mmap ioctl,
> > for creating the wc mappings, on yet to be supported flags.
> > Older kernel is also checked against the flags field, which should
> > be treated as a don't care by it.
> >
> > Signed-off-by: Akash Goel <akash.goel@intel.com>
> > Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> > ---
> > tests/gem_mmap_wc.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++
> > 1 file changed, 66 insertions(+)
> >
> > diff --git a/tests/gem_mmap_wc.c b/tests/gem_mmap_wc.c
> > index 6f91a89..f923553 100644
> > --- a/tests/gem_mmap_wc.c
> > +++ b/tests/gem_mmap_wc.c
> > @@ -41,6 +41,17 @@
> > #include "drmtest.h"
> > #include "igt_debugfs.h"
> >
> > +struct local_i915_gem_mmap_v2 {
> > + uint32_t handle;
> > + uint32_t pad;
> > + uint64_t offset;
> > + uint64_t size;
> > + uint64_t addr_ptr;
> > + uint64_t flags;
> > +#define I915_MMAP_WC 0x1
> > +};
> > +#define LOCAL_IOCTL_I915_GEM_MMAP_v2 DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MMAP, struct local_i915_gem_mmap_v2)
> > +
> > static int OBJECT_SIZE = 16*1024*1024;
> >
> > static void set_domain(int fd, uint32_t handle)
> > @@ -75,6 +86,59 @@ create_pointer(int fd)
> > }
> >
> > static void
> > +test_invalid_flags(int fd)
> > +{
> > + struct drm_i915_getparam gp;
> > + struct local_i915_gem_mmap_v2 arg;
> > + uint64_t flag = I915_MMAP_WC;
> > + int val = -1;
> > +
> > + memset(&arg, 0, sizeof(arg));
> > + arg.handle = gem_create(fd, 4096);
> > + arg.offset = 0;
> > + arg.size = 4096;
> > +
> > + memset(&gp, 0, sizeof(gp));
> > + gp.param = 30; /* MMAP_VERSION */
> > + gp.value = &val;
> > +
> > + /* Do we have the new mmap_ioctl? */
> > + do_ioctl(fd, DRM_IOCTL_I915_GETPARAM, &gp);
> > +
> > + if (val >= 1) {
> > + /*
> > + * Only MMAP_WC flag is supported in version 1, so any other
> > + * flag should be rejected.
> > + */
> > + flag <<= 1;
> > + while (flag) {
> > + arg.flags = flag;
> > + igt_assert(drmIoctl(fd,
> > + LOCAL_IOCTL_I915_GEM_MMAP_v2,
> > + &arg) == -1);
> > + igt_assert_eq(errno, EINVAL);
> > + flag <<= 1;
> > + }
> > + } else {
> > + /*
> > + * flags field should be ignored by older kernel
> > + * and so irrespective of the flag value passed,
> > + * mmap call should succeed
> > + */
> > + while (flag) {
> > + arg.flags = flag;
> > + igt_assert(drmIoctl(fd,
> > + LOCAL_IOCTL_I915_GEM_MMAP_v2,
> > + &arg) == 0);
> > + munmap(arg.addr_ptr, 4096);
> > + flag <<= 1;
> > + }
> > + }
>
> Imo just skip when the new flag stuff isn't available.
Ok will remove this checking for the flags on older kernels.
Thought that older kernel shouldn't react to flag values in anyway.
>
> > +
> > + gem_close(fd, arg.handle);
> > +}
> > +
> > +static void
> > test_copy(int fd)
> > {
> > void *src, *dst;
> > @@ -331,6 +395,8 @@ igt_main
> > igt_fixture
> > fd = drm_open_any();
> >
> > + igt_subtest("invalid flags")
>
> s/ /-/
>
> Also can you please add invalid-foo tests for all the other ioctl
> paramters, too? That's an existing gap in our coverage and general rule is
> that the next person to touch it gets to fill it out (it's been a while
> though since that was last required, we have fairly good coverage
> nowadays).
Should a new subtest be added in 'gem_mmap' IGT, for checking on the
other parameters of i915_gem_mmap ioctl.
Best regards
Akash
>
> Thanks, Daniel
>
>
> > + test_invalid_flags(fd);
> > igt_subtest("copy")
> > test_copy(fd);
> > igt_subtest("read")
> > --
> > 1.9.2
> >
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 11+ messages in thread* [PATCH v2] igt/gem_mmap_wc: Add the invalid flags subtest
2014-11-25 11:30 ` Daniel Vetter
2014-12-03 12:58 ` Akash Goel
@ 2014-12-04 4:41 ` akash.goel
1 sibling, 0 replies; 11+ messages in thread
From: akash.goel @ 2014-12-04 4:41 UTC (permalink / raw)
To: intel-gfx; +Cc: Akash Goel
From: Akash Goel <akash.goel@intel.com>
A new subtest added to validate the new version of gem_mmap ioctl,
for creating the wc mappings, on yet to be supported flags.
Older kernel is also checked against the flags field, which should
be treated as a don't care by it.
v2: Removed the flags checking for older kernels (Daniel)
Signed-off-by: Akash Goel <akash.goel@intel.com>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
tests/gem_mmap_wc.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 52 insertions(+)
diff --git a/tests/gem_mmap_wc.c b/tests/gem_mmap_wc.c
index 6f91a89..18ff1f5 100644
--- a/tests/gem_mmap_wc.c
+++ b/tests/gem_mmap_wc.c
@@ -41,6 +41,17 @@
#include "drmtest.h"
#include "igt_debugfs.h"
+struct local_i915_gem_mmap_v2 {
+ uint32_t handle;
+ uint32_t pad;
+ uint64_t offset;
+ uint64_t size;
+ uint64_t addr_ptr;
+ uint64_t flags;
+#define I915_MMAP_WC 0x1
+};
+#define LOCAL_IOCTL_I915_GEM_MMAP_v2 DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MMAP, struct local_i915_gem_mmap_v2)
+
static int OBJECT_SIZE = 16*1024*1024;
static void set_domain(int fd, uint32_t handle)
@@ -75,6 +86,45 @@ create_pointer(int fd)
}
static void
+test_invalid_flags(int fd)
+{
+ struct drm_i915_getparam gp;
+ struct local_i915_gem_mmap_v2 arg;
+ uint64_t flag = I915_MMAP_WC;
+ int val = -1;
+
+ memset(&arg, 0, sizeof(arg));
+ arg.handle = gem_create(fd, 4096);
+ arg.offset = 0;
+ arg.size = 4096;
+
+ memset(&gp, 0, sizeof(gp));
+ gp.param = 30; /* MMAP_VERSION */
+ gp.value = &val;
+
+ /* Do we have the new mmap_ioctl? */
+ do_ioctl(fd, DRM_IOCTL_I915_GETPARAM, &gp);
+
+ if (val >= 1) {
+ /*
+ * Only MMAP_WC flag is supported in version 1, so any other
+ * flag should be rejected.
+ */
+ flag <<= 1;
+ while (flag) {
+ arg.flags = flag;
+ igt_assert(drmIoctl(fd,
+ LOCAL_IOCTL_I915_GEM_MMAP_v2,
+ &arg) == -1);
+ igt_assert_eq(errno, EINVAL);
+ flag <<= 1;
+ }
+ }
+
+ gem_close(fd, arg.handle);
+}
+
+static void
test_copy(int fd)
{
void *src, *dst;
@@ -331,6 +381,8 @@ igt_main
igt_fixture
fd = drm_open_any();
+ igt_subtest("invalid flags")
+ test_invalid_flags(fd);
igt_subtest("copy")
test_copy(fd);
igt_subtest("read")
--
1.9.2
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 11+ messages in thread