All of lore.kernel.org
 help / color / mirror / Atom feed
* [igt-dev] [PATCH i-g-t] lib/ioctl_wrappers: Keep IGT working without pread/pwrite ioctls
@ 2020-09-30  3:40 Ashutosh Dixit
  2020-09-30  4:15 ` [igt-dev] ✓ Fi.CI.BAT: success for lib/ioctl_wrappers: Keep IGT working without pread/pwrite ioctls (rev6) Patchwork
                   ` (3 more replies)
  0 siblings, 4 replies; 17+ messages in thread
From: Ashutosh Dixit @ 2020-09-30  3:40 UTC (permalink / raw)
  To: igt-dev

The general direction at this time is to phase out pread/write ioctls
and not support them in future products. This means IGT must handle
the absence of these ioctls. This patch does this by modifying
gem_read() and gem_write() to do the read/write using the pread/pwrite
ioctls first but when these ioctls are unavailable fall back to doing
the read/write using a combination of mmap and memcpy.

Callers who must absolutely use the pread/pwrite ioctls (such as tests
which test these ioctls or must otherwise only use the pread/pwrite
ioctls) must use gem_require_pread_pwrite() to skip when these ioctls
are not available.

v1: Removed __gem_pread, gem_pread, __gem_pwrite and gem_pwrite
    introduced previously since they are not necessary,
    gem_require_pread_pwrite is sufficient
v2: Fix CI failures in gem_advise and gen9_exec_parse by introducing
    gem_require_pread_pwrite
v3: Skip mmap for 0 length read/write's
v4: Remove redundant igt_assert's
v5: Re-run
v6: s/EOPNOTSUPP/-EOPNOTSUPP/

Reviewed-by: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com>
Signed-off-by: Ashutosh Dixit <ashutosh.dixit@intel.com>
---
 lib/ioctl_wrappers.c                        | 135 +++++++++++++++++++-
 lib/ioctl_wrappers.h                        |   3 +
 tests/i915/gem_madvise.c                    |   2 +
 tests/i915/gem_partial_pwrite_pread.c       |   1 +
 tests/i915/gem_pread.c                      |   1 +
 tests/i915/gem_pread_after_blit.c           |   1 +
 tests/i915/gem_pwrite.c                     |   1 +
 tests/i915/gem_pwrite_snooped.c             |   1 +
 tests/i915/gem_readwrite.c                  |   1 +
 tests/i915/gem_set_tiling_vs_pwrite.c       |   1 +
 tests/i915/gem_tiled_partial_pwrite_pread.c |   1 +
 tests/i915/gem_tiled_pread_basic.c          |   1 +
 tests/i915/gem_tiled_pread_pwrite.c         |   1 +
 tests/i915/gem_userptr_blits.c              |   2 +
 tests/i915/gen9_exec_parse.c                |   4 +-
 15 files changed, 149 insertions(+), 7 deletions(-)

diff --git a/lib/ioctl_wrappers.c b/lib/ioctl_wrappers.c
index edac50f0f..ac77b3eb6 100644
--- a/lib/ioctl_wrappers.c
+++ b/lib/ioctl_wrappers.c
@@ -55,6 +55,7 @@
 #include "igt_debugfs.h"
 #include "igt_sysfs.h"
 #include "config.h"
+#include "i915/gem_mman.h"
 
 #ifdef HAVE_VALGRIND
 #include <valgrind/valgrind.h>
@@ -323,6 +324,70 @@ void gem_close(int fd, uint32_t handle)
 	do_ioctl(fd, DRM_IOCTL_GEM_CLOSE, &close_bo);
 }
 
+static bool is_cache_coherent(int fd, uint32_t handle)
+{
+	return gem_get_caching(fd, handle) != I915_CACHING_NONE;
+}
+
+static void mmap_write(int fd, uint32_t handle, uint64_t offset,
+		       const void *buf, uint64_t length)
+{
+	void *map = NULL;
+
+	if (!length)
+		return;
+
+	if (is_cache_coherent(fd, handle)) {
+		/* offset arg for mmap functions must be 0 */
+		map = __gem_mmap__cpu_coherent(fd, handle, 0, offset + length,
+					       PROT_READ | PROT_WRITE);
+		if (map)
+			gem_set_domain(fd, handle,
+				       I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
+	}
+
+	if (!map) {
+		map = __gem_mmap_offset__wc(fd, handle, 0, offset + length,
+					    PROT_READ | PROT_WRITE);
+		if (!map)
+			map = gem_mmap__wc(fd, handle, 0, offset + length,
+					   PROT_READ | PROT_WRITE);
+		gem_set_domain(fd, handle,
+			       I915_GEM_DOMAIN_WC, I915_GEM_DOMAIN_WC);
+	}
+
+	memcpy(map + offset, buf, length);
+	munmap(map, offset + length);
+}
+
+static void mmap_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t length)
+{
+	void *map = NULL;
+
+	if (!length)
+		return;
+
+	if (gem_has_llc(fd) || is_cache_coherent(fd, handle)) {
+		/* offset arg for mmap functions must be 0 */
+		map = __gem_mmap__cpu_coherent(fd, handle, 0,
+					       offset + length, PROT_READ);
+		if (map)
+			gem_set_domain(fd, handle, I915_GEM_DOMAIN_CPU, 0);
+	}
+
+	if (!map) {
+		map = __gem_mmap_offset__wc(fd, handle, 0, offset + length,
+					    PROT_READ);
+		if (!map)
+			map = gem_mmap__wc(fd, handle, 0, offset + length,
+					   PROT_READ);
+		gem_set_domain(fd, handle, I915_GEM_DOMAIN_WC, 0);
+	}
+
+	memcpy(buf, map + offset, length);
+	munmap(map, offset + length);
+}
+
 int __gem_write(int fd, uint32_t handle, uint64_t offset, const void *buf, uint64_t length)
 {
 	struct drm_i915_gem_pwrite gem_pwrite;
@@ -348,12 +413,18 @@ int __gem_write(int fd, uint32_t handle, uint64_t offset, const void *buf, uint6
  * @buf: pointer to the data to write into the buffer
  * @length: size of the subrange
  *
- * This wraps the PWRITE ioctl, which is to upload a linear data to a subrange
- * of a gem buffer object.
+ * Method to write to a gem object. Uses the PWRITE ioctl when it is
+ * available, else it uses mmap + memcpy to upload linear data to a
+ * subrange of a gem buffer object.
  */
 void gem_write(int fd, uint32_t handle, uint64_t offset, const void *buf, uint64_t length)
 {
-	igt_assert_eq(__gem_write(fd, handle, offset, buf, length), 0);
+	int ret = __gem_write(fd, handle, offset, buf, length);
+
+	igt_assert(ret == 0 || ret == -EOPNOTSUPP);
+
+	if (ret == -EOPNOTSUPP)
+		mmap_write(fd, handle, offset, buf, length);
 }
 
 int __gem_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t length)
@@ -380,12 +451,64 @@ int __gem_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t len
  * @buf: pointer to the data to read into
  * @length: size of the subrange
  *
- * This wraps the PREAD ioctl, which is to download a linear data to a subrange
- * of a gem buffer object.
+ * Method to read from a gem object. Uses the PREAD ioctl when it is
+ * available, else it uses mmap + memcpy to download linear data from a
+ * subrange of a gem buffer object.
  */
 void gem_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t length)
 {
-	igt_assert_eq(__gem_read(fd, handle, offset, buf, length), 0);
+	int ret = __gem_read(fd, handle, offset, buf, length);
+
+	igt_assert(ret == 0 || ret == -EOPNOTSUPP);
+
+	if (ret == -EOPNOTSUPP)
+		mmap_read(fd, handle, offset, buf, length);
+}
+
+/**
+ * gem_has_pwrite
+ * @fd: open i915 drm file descriptor
+ *
+ * Feature test macro to query whether pwrite ioctl is supported
+ */
+bool gem_has_pwrite(int fd)
+{
+	uint32_t handle = gem_create(fd, 4096);
+	int buf, ret;
+
+	ret = __gem_write(fd, handle, 0, &buf, sizeof(buf));
+	gem_close(fd, handle);
+
+	return ret != -EOPNOTSUPP;
+}
+
+/**
+ * gem_has_pread
+ * @fd: open i915 drm file descriptor
+ *
+ * Feature test macro to query whether pread ioctl is supported
+ */
+bool gem_has_pread(int fd)
+{
+	uint32_t handle = gem_create(fd, 4096);
+	int buf, ret;
+
+	ret = __gem_read(fd, handle, 0, &buf, sizeof(buf));
+	gem_close(fd, handle);
+
+	return ret != -EOPNOTSUPP;
+}
+
+/**
+ * gem_require_pread_pwrite
+ * @fd: open i915 drm file descriptor
+ *
+ * Feature test macro to query whether pread/pwrite ioctls are supported
+ * and skip if they are not
+ */
+void gem_require_pread_pwrite(int fd)
+{
+	igt_require(gem_has_pread(fd) && gem_has_pwrite(fd));
 }
 
 int __gem_set_domain(int fd, uint32_t handle, uint32_t read, uint32_t write)
diff --git a/lib/ioctl_wrappers.h b/lib/ioctl_wrappers.h
index b76bea564..81166000a 100644
--- a/lib/ioctl_wrappers.h
+++ b/lib/ioctl_wrappers.h
@@ -71,6 +71,9 @@ int __gem_write(int fd, uint32_t handle, uint64_t offset, const void *buf, uint6
 void gem_write(int fd, uint32_t handle, uint64_t offset,  const void *buf, uint64_t length);
 int __gem_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t length);
 void gem_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t length);
+bool gem_has_pwrite(int fd);
+bool gem_has_pread(int fd);
+void gem_require_pread_pwrite(int fd);
 int __gem_set_domain(int fd, uint32_t handle, uint32_t read, uint32_t write);
 void gem_set_domain(int fd, uint32_t handle, uint32_t read, uint32_t write);
 int gem_wait(int fd, uint32_t handle, int64_t *timeout_ns);
diff --git a/tests/i915/gem_madvise.c b/tests/i915/gem_madvise.c
index 54c9befff..92e1c5192 100644
--- a/tests/i915/gem_madvise.c
+++ b/tests/i915/gem_madvise.c
@@ -154,6 +154,7 @@ dontneed_before_pwrite(void)
 	uint32_t bbe = MI_BATCH_BUFFER_END;
 	uint32_t handle;
 
+	gem_require_pread_pwrite(fd);
 	handle = gem_create(fd, OBJECT_SIZE);
 	gem_madvise(fd, handle, I915_MADV_DONTNEED);
 
@@ -170,6 +171,7 @@ dontneed_before_exec(void)
 	struct drm_i915_gem_exec_object2 exec;
 	uint32_t buf[] = { MI_BATCH_BUFFER_END, 0 };
 
+	gem_require_pread_pwrite(fd);
 	memset(&execbuf, 0, sizeof(execbuf));
 	memset(&exec, 0, sizeof(exec));
 
diff --git a/tests/i915/gem_partial_pwrite_pread.c b/tests/i915/gem_partial_pwrite_pread.c
index b10284721..fd7b19f31 100644
--- a/tests/i915/gem_partial_pwrite_pread.c
+++ b/tests/i915/gem_partial_pwrite_pread.c
@@ -281,6 +281,7 @@ igt_main
 		data.drm_fd = drm_open_driver(DRIVER_INTEL);
 		igt_require_gem(data.drm_fd);
 		gem_require_blitter(data.drm_fd);
+		gem_require_pread_pwrite(data.drm_fd);
 
 		data.devid = intel_get_drm_devid(data.drm_fd);
 		data.bops = buf_ops_create(data.drm_fd);
diff --git a/tests/i915/gem_pread.c b/tests/i915/gem_pread.c
index 6d12b8e9f..db1eacedc 100644
--- a/tests/i915/gem_pread.c
+++ b/tests/i915/gem_pread.c
@@ -149,6 +149,7 @@ igt_main_args("s:", NULL, help_str, opt_handler, NULL)
 
 	igt_fixture {
 		fd = drm_open_driver(DRIVER_INTEL);
+		gem_require_pread_pwrite(fd);
 
 		dst = gem_create(fd, object_size);
 		src = malloc(object_size);
diff --git a/tests/i915/gem_pread_after_blit.c b/tests/i915/gem_pread_after_blit.c
index 81454c930..5c99d0887 100644
--- a/tests/i915/gem_pread_after_blit.c
+++ b/tests/i915/gem_pread_after_blit.c
@@ -212,6 +212,7 @@ igt_main
 	igt_fixture {
 		fd = drm_open_driver(DRIVER_INTEL);
 		igt_require_gem(fd);
+		gem_require_pread_pwrite(fd);
 
 		bufmgr = drm_intel_bufmgr_gem_init(fd, 4096);
 		drm_intel_bufmgr_gem_enable_reuse(bufmgr);
diff --git a/tests/i915/gem_pwrite.c b/tests/i915/gem_pwrite.c
index e491263fd..eea51f978 100644
--- a/tests/i915/gem_pwrite.c
+++ b/tests/i915/gem_pwrite.c
@@ -317,6 +317,7 @@ igt_main_args("s:", NULL, help_str, opt_handler, NULL)
 
 	igt_fixture {
 		fd = drm_open_driver(DRIVER_INTEL);
+		gem_require_pread_pwrite(fd);
 
 		dst = gem_create(fd, object_size);
 		src = malloc(object_size);
diff --git a/tests/i915/gem_pwrite_snooped.c b/tests/i915/gem_pwrite_snooped.c
index 4a3395241..a2eca6afc 100644
--- a/tests/i915/gem_pwrite_snooped.c
+++ b/tests/i915/gem_pwrite_snooped.c
@@ -132,6 +132,7 @@ igt_simple_main
 	fd = drm_open_driver(DRIVER_INTEL);
 	igt_require_gem(fd);
 	gem_require_blitter(fd);
+	gem_require_pread_pwrite(fd);
 
 	devid = intel_get_drm_devid(fd);
 	bufmgr = drm_intel_bufmgr_gem_init(fd, 4096);
diff --git a/tests/i915/gem_readwrite.c b/tests/i915/gem_readwrite.c
index 6b2977c1c..ca31741c6 100644
--- a/tests/i915/gem_readwrite.c
+++ b/tests/i915/gem_readwrite.c
@@ -83,6 +83,7 @@ igt_main
 
 	igt_fixture {
 		fd = drm_open_driver(DRIVER_INTEL);
+		gem_require_pread_pwrite(fd);
 
 		handle = gem_create(fd, OBJECT_SIZE);
 	}
diff --git a/tests/i915/gem_set_tiling_vs_pwrite.c b/tests/i915/gem_set_tiling_vs_pwrite.c
index 302ea24b6..8f38c9b9b 100644
--- a/tests/i915/gem_set_tiling_vs_pwrite.c
+++ b/tests/i915/gem_set_tiling_vs_pwrite.c
@@ -55,6 +55,7 @@ igt_simple_main
 
 	fd = drm_open_driver(DRIVER_INTEL);
 	igt_require(gem_available_fences(fd) > 0);
+	gem_require_pread_pwrite(fd);
 
 	for (int i = 0; i < OBJECT_SIZE/4; i++)
 		data[i] = i;
diff --git a/tests/i915/gem_tiled_partial_pwrite_pread.c b/tests/i915/gem_tiled_partial_pwrite_pread.c
index 7de5358b2..0c4545990 100644
--- a/tests/i915/gem_tiled_partial_pwrite_pread.c
+++ b/tests/i915/gem_tiled_partial_pwrite_pread.c
@@ -270,6 +270,7 @@ igt_main
 		igt_require_gem(fd);
 		gem_require_mappable_ggtt(fd);
 		gem_require_blitter(fd);
+		gem_require_pread_pwrite(fd);
 
 		bufmgr = drm_intel_bufmgr_gem_init(fd, 4096);
 		//drm_intel_bufmgr_gem_enable_reuse(bufmgr);
diff --git a/tests/i915/gem_tiled_pread_basic.c b/tests/i915/gem_tiled_pread_basic.c
index 7cb644104..f8f73c03a 100644
--- a/tests/i915/gem_tiled_pread_basic.c
+++ b/tests/i915/gem_tiled_pread_basic.c
@@ -127,6 +127,7 @@ igt_simple_main
 	igt_require(gem_available_fences(fd) > 0);
 	handle = create_bo(fd);
 	igt_require(gem_get_tiling(fd, handle, &tiling, &swizzle));
+	gem_require_pread_pwrite(fd);
 
 	devid = intel_get_drm_devid(fd);
 
diff --git a/tests/i915/gem_tiled_pread_pwrite.c b/tests/i915/gem_tiled_pread_pwrite.c
index f58048faa..28490840f 100644
--- a/tests/i915/gem_tiled_pread_pwrite.c
+++ b/tests/i915/gem_tiled_pread_pwrite.c
@@ -114,6 +114,7 @@ igt_simple_main
 	
 	fd = drm_open_driver(DRIVER_INTEL);
 	igt_require(gem_available_fences(fd) > 0);
+	gem_require_pread_pwrite(fd);
 
 	count = gem_available_fences(fd) + 1;
 	intel_require_memory(2 * count, sizeof(linear), CHECK_RAM);
diff --git a/tests/i915/gem_userptr_blits.c b/tests/i915/gem_userptr_blits.c
index 268423dcd..0ccfdbd9c 100644
--- a/tests/i915/gem_userptr_blits.c
+++ b/tests/i915/gem_userptr_blits.c
@@ -890,6 +890,7 @@ static int test_forbidden_ops(int fd)
 	uint32_t handle;
 	void *ptr;
 
+	gem_require_pread_pwrite(fd);
 	igt_assert(posix_memalign(&ptr, PAGE_SIZE, PAGE_SIZE) == 0);
 	gem_userptr(fd, ptr, PAGE_SIZE, 0, userptr_flags, &handle);
 
@@ -1416,6 +1417,7 @@ static void test_readonly_pwrite(int i915)
 	 */
 
 	igt_require(igt_setup_clflush());
+	gem_require_pread_pwrite(i915);
 
 	sz = 16 << 12;
 	pages = mmap(NULL, sz, PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
diff --git a/tests/i915/gen9_exec_parse.c b/tests/i915/gen9_exec_parse.c
index 7ddb5bf2b..cfb6de080 100644
--- a/tests/i915/gen9_exec_parse.c
+++ b/tests/i915/gen9_exec_parse.c
@@ -1104,8 +1104,10 @@ igt_main
 			   -EINVAL);
 	}
 
-	igt_subtest("batch-invalid-length")
+	igt_subtest("batch-invalid-length") {
+		gem_require_pread_pwrite(i915);
 		test_invalid_length(i915, handle);
+	}
 
 	igt_subtest("basic-rejected")
 		test_rejected(i915, handle, false);
-- 
2.26.2.108.g048abe1751

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [igt-dev] ✓ Fi.CI.BAT: success for lib/ioctl_wrappers: Keep IGT working without pread/pwrite ioctls (rev6)
  2020-09-30  3:40 [igt-dev] [PATCH i-g-t] lib/ioctl_wrappers: Keep IGT working without pread/pwrite ioctls Ashutosh Dixit
@ 2020-09-30  4:15 ` Patchwork
  2020-09-30 13:29 ` [igt-dev] ✓ Fi.CI.IGT: " Patchwork
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 17+ messages in thread
From: Patchwork @ 2020-09-30  4:15 UTC (permalink / raw)
  To: Ashutosh Dixit; +Cc: igt-dev


[-- Attachment #1.1: Type: text/plain, Size: 4350 bytes --]

== Series Details ==

Series: lib/ioctl_wrappers: Keep IGT working without pread/pwrite ioctls (rev6)
URL   : https://patchwork.freedesktop.org/series/81384/
State : success

== Summary ==

CI Bug Log - changes from IGT_5793 -> IGTPW_5026
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5026/index.html

Known issues
------------

  Here are the changes found in IGTPW_5026 that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic:
    - fi-byt-j1900:       [PASS][1] -> [DMESG-WARN][2] ([i915#1982]) +1 similar issue
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5793/fi-byt-j1900/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5026/fi-byt-j1900/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic.html

  
#### Possible fixes ####

  * igt@debugfs_test@read_all_entries:
    - fi-bsw-nick:        [INCOMPLETE][3] ([i915#1250] / [i915#1436]) -> [PASS][4]
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5793/fi-bsw-nick/igt@debugfs_test@read_all_entries.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5026/fi-bsw-nick/igt@debugfs_test@read_all_entries.html

  * igt@i915_selftest@live@gt_pm:
    - {fi-kbl-7560u}:     [DMESG-FAIL][5] ([i915#2524]) -> [PASS][6]
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5793/fi-kbl-7560u/igt@i915_selftest@live@gt_pm.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5026/fi-kbl-7560u/igt@i915_selftest@live@gt_pm.html

  * igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic:
    - fi-bsw-n3050:       [DMESG-WARN][7] ([i915#1982]) -> [PASS][8]
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5793/fi-bsw-n3050/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5026/fi-bsw-n3050/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic.html
    - fi-bsw-kefka:       [DMESG-WARN][9] ([i915#1982]) -> [PASS][10]
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5793/fi-bsw-kefka/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5026/fi-bsw-kefka/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic.html

  * igt@kms_flip@basic-flip-vs-wf_vblank@b-edp1:
    - fi-icl-u2:          [DMESG-WARN][11] ([i915#1982]) -> [PASS][12]
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5793/fi-icl-u2/igt@kms_flip@basic-flip-vs-wf_vblank@b-edp1.html
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5026/fi-icl-u2/igt@kms_flip@basic-flip-vs-wf_vblank@b-edp1.html

  
#### Warnings ####

  * igt@i915_pm_rpm@module-reload:
    - fi-kbl-guc:         [DMESG-FAIL][13] ([i915#2203]) -> [DMESG-WARN][14] ([i915#2203])
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5793/fi-kbl-guc/igt@i915_pm_rpm@module-reload.html
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5026/fi-kbl-guc/igt@i915_pm_rpm@module-reload.html

  
  {name}: This element is suppressed. This means it is ignored when computing
          the status of the difference (SUCCESS, WARNING, or FAILURE).

  [i915#1250]: https://gitlab.freedesktop.org/drm/intel/issues/1250
  [i915#1436]: https://gitlab.freedesktop.org/drm/intel/issues/1436
  [i915#1982]: https://gitlab.freedesktop.org/drm/intel/issues/1982
  [i915#2203]: https://gitlab.freedesktop.org/drm/intel/issues/2203
  [i915#2524]: https://gitlab.freedesktop.org/drm/intel/issues/2524


Participating hosts (46 -> 37)
------------------------------

  Missing    (9): fi-ilk-m540 fi-tgl-dsi fi-hsw-4200u fi-byt-squawks fi-bsw-cyan fi-ctg-p8600 fi-kbl-x1275 fi-byt-clapper fi-bdw-samus 


Build changes
-------------

  * CI: CI-20190529 -> None
  * IGT: IGT_5793 -> IGTPW_5026

  CI-20190529: 20190529
  CI_DRM_9075: fd24361b2b76956b5c056bc430a4c77edecb7744 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGTPW_5026: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5026/index.html
  IGT_5793: c34792447c9fc4d05dd75873cdb99d9ffe57ea23 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5026/index.html

[-- Attachment #1.2: Type: text/html, Size: 5371 bytes --]

[-- Attachment #2: Type: text/plain, Size: 154 bytes --]

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [igt-dev] ✓ Fi.CI.IGT: success for lib/ioctl_wrappers: Keep IGT working without pread/pwrite ioctls (rev6)
  2020-09-30  3:40 [igt-dev] [PATCH i-g-t] lib/ioctl_wrappers: Keep IGT working without pread/pwrite ioctls Ashutosh Dixit
  2020-09-30  4:15 ` [igt-dev] ✓ Fi.CI.BAT: success for lib/ioctl_wrappers: Keep IGT working without pread/pwrite ioctls (rev6) Patchwork
@ 2020-09-30 13:29 ` Patchwork
  2020-10-02  9:36 ` [igt-dev] [PATCH i-g-t] lib/ioctl_wrappers: Keep IGT working without pread/pwrite ioctls Chris Wilson
  2021-01-11 20:46 ` [igt-dev] [i-g-t] " Dave Airlie
  3 siblings, 0 replies; 17+ messages in thread
From: Patchwork @ 2020-09-30 13:29 UTC (permalink / raw)
  To: Ashutosh Dixit; +Cc: igt-dev


[-- Attachment #1.1: Type: text/plain, Size: 16533 bytes --]

== Series Details ==

Series: lib/ioctl_wrappers: Keep IGT working without pread/pwrite ioctls (rev6)
URL   : https://patchwork.freedesktop.org/series/81384/
State : success

== Summary ==

CI Bug Log - changes from IGT_5793_full -> IGTPW_5026_full
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5026/index.html

Known issues
------------

  Here are the changes found in IGTPW_5026_full that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@gen9_exec_parse@allowed-all:
    - shard-kbl:          [PASS][1] -> [DMESG-WARN][2] ([i915#1436] / [i915#716])
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5793/shard-kbl2/igt@gen9_exec_parse@allowed-all.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5026/shard-kbl3/igt@gen9_exec_parse@allowed-all.html

  * igt@i915_pm_dc@dc5-psr:
    - shard-iclb:         [PASS][3] -> [FAIL][4] ([i915#1899])
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5793/shard-iclb6/igt@i915_pm_dc@dc5-psr.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5026/shard-iclb2/igt@i915_pm_dc@dc5-psr.html

  * igt@kms_big_fb@linear-64bpp-rotate-180:
    - shard-iclb:         [PASS][5] -> [DMESG-WARN][6] ([i915#1982])
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5793/shard-iclb1/igt@kms_big_fb@linear-64bpp-rotate-180.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5026/shard-iclb3/igt@kms_big_fb@linear-64bpp-rotate-180.html

  * igt@kms_cursor_edge_walk@pipe-b-128x128-bottom-edge:
    - shard-apl:          [PASS][7] -> [DMESG-WARN][8] ([i915#1635] / [i915#1982])
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5793/shard-apl1/igt@kms_cursor_edge_walk@pipe-b-128x128-bottom-edge.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5026/shard-apl2/igt@kms_cursor_edge_walk@pipe-b-128x128-bottom-edge.html

  * igt@kms_cursor_legacy@flip-vs-cursor-crc-legacy:
    - shard-snb:          [PASS][9] -> [SKIP][10] ([fdo#109271]) +1 similar issue
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5793/shard-snb5/igt@kms_cursor_legacy@flip-vs-cursor-crc-legacy.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5026/shard-snb7/igt@kms_cursor_legacy@flip-vs-cursor-crc-legacy.html

  * igt@kms_flip@flip-vs-suspend@c-dp1:
    - shard-kbl:          [PASS][11] -> [DMESG-WARN][12] ([i915#180]) +2 similar issues
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5793/shard-kbl6/igt@kms_flip@flip-vs-suspend@c-dp1.html
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5026/shard-kbl1/igt@kms_flip@flip-vs-suspend@c-dp1.html

  * igt@kms_frontbuffer_tracking@fbc-1p-primscrn-cur-indfb-draw-render:
    - shard-kbl:          [PASS][13] -> [DMESG-WARN][14] ([i915#1982])
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5793/shard-kbl3/igt@kms_frontbuffer_tracking@fbc-1p-primscrn-cur-indfb-draw-render.html
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5026/shard-kbl4/igt@kms_frontbuffer_tracking@fbc-1p-primscrn-cur-indfb-draw-render.html

  * igt@kms_frontbuffer_tracking@fbcpsr-1p-rte:
    - shard-tglb:         [PASS][15] -> [DMESG-WARN][16] ([i915#1982]) +2 similar issues
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5793/shard-tglb3/igt@kms_frontbuffer_tracking@fbcpsr-1p-rte.html
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5026/shard-tglb8/igt@kms_frontbuffer_tracking@fbcpsr-1p-rte.html

  * igt@kms_psr@psr2_cursor_mmap_cpu:
    - shard-iclb:         [PASS][17] -> [SKIP][18] ([fdo#109441]) +1 similar issue
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5793/shard-iclb2/igt@kms_psr@psr2_cursor_mmap_cpu.html
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5026/shard-iclb4/igt@kms_psr@psr2_cursor_mmap_cpu.html

  * igt@kms_setmode@basic:
    - shard-apl:          [PASS][19] -> [FAIL][20] ([i915#1635] / [i915#31])
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5793/shard-apl2/igt@kms_setmode@basic.html
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5026/shard-apl3/igt@kms_setmode@basic.html

  * igt@kms_vblank@pipe-b-accuracy-idle:
    - shard-glk:          [PASS][21] -> [FAIL][22] ([i915#43])
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5793/shard-glk5/igt@kms_vblank@pipe-b-accuracy-idle.html
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5026/shard-glk9/igt@kms_vblank@pipe-b-accuracy-idle.html

  * igt@perf@non-sampling-read-error:
    - shard-tglb:         [PASS][23] -> [SKIP][24] ([i915#405])
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5793/shard-tglb1/igt@perf@non-sampling-read-error.html
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5026/shard-tglb1/igt@perf@non-sampling-read-error.html
    - shard-apl:          [PASS][25] -> [SKIP][26] ([fdo#109271] / [i915#1635])
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5793/shard-apl7/igt@perf@non-sampling-read-error.html
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5026/shard-apl3/igt@perf@non-sampling-read-error.html
    - shard-glk:          [PASS][27] -> [SKIP][28] ([fdo#109271])
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5793/shard-glk9/igt@perf@non-sampling-read-error.html
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5026/shard-glk6/igt@perf@non-sampling-read-error.html
    - shard-hsw:          [PASS][29] -> [SKIP][30] ([fdo#109271])
   [29]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5793/shard-hsw4/igt@perf@non-sampling-read-error.html
   [30]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5026/shard-hsw4/igt@perf@non-sampling-read-error.html
    - shard-kbl:          [PASS][31] -> [SKIP][32] ([fdo#109271])
   [31]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5793/shard-kbl6/igt@perf@non-sampling-read-error.html
   [32]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5026/shard-kbl3/igt@perf@non-sampling-read-error.html
    - shard-iclb:         [PASS][33] -> [SKIP][34] ([i915#405])
   [33]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5793/shard-iclb5/igt@perf@non-sampling-read-error.html
   [34]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5026/shard-iclb8/igt@perf@non-sampling-read-error.html

  
#### Possible fixes ####

  * igt@gem_exec_reloc@basic-many-active@rcs0:
    - shard-apl:          [FAIL][35] ([i915#1635] / [i915#2389]) -> [PASS][36]
   [35]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5793/shard-apl1/igt@gem_exec_reloc@basic-many-active@rcs0.html
   [36]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5026/shard-apl7/igt@gem_exec_reloc@basic-many-active@rcs0.html

  * igt@gem_exec_reloc@basic-many-active@vecs0:
    - shard-glk:          [FAIL][37] ([i915#2389]) -> [PASS][38] +1 similar issue
   [37]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5793/shard-glk2/igt@gem_exec_reloc@basic-many-active@vecs0.html
   [38]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5026/shard-glk4/igt@gem_exec_reloc@basic-many-active@vecs0.html

  * igt@gem_exec_whisper@basic-contexts-priority-all:
    - shard-glk:          [DMESG-WARN][39] ([i915#118] / [i915#95]) -> [PASS][40]
   [39]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5793/shard-glk2/igt@gem_exec_whisper@basic-contexts-priority-all.html
   [40]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5026/shard-glk5/igt@gem_exec_whisper@basic-contexts-priority-all.html

  * igt@i915_pm_dc@dc6-psr:
    - shard-iclb:         [FAIL][41] ([i915#454]) -> [PASS][42]
   [41]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5793/shard-iclb4/igt@i915_pm_dc@dc6-psr.html
   [42]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5026/shard-iclb7/igt@i915_pm_dc@dc6-psr.html

  * igt@kms_big_fb@linear-8bpp-rotate-180:
    - shard-kbl:          [DMESG-WARN][43] ([i915#1982]) -> [PASS][44]
   [43]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5793/shard-kbl4/igt@kms_big_fb@linear-8bpp-rotate-180.html
   [44]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5026/shard-kbl2/igt@kms_big_fb@linear-8bpp-rotate-180.html

  * igt@kms_flip@dpms-vs-vblank-race@a-hdmi-a1:
    - shard-glk:          [DMESG-WARN][45] ([i915#1982]) -> [PASS][46]
   [45]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5793/shard-glk3/igt@kms_flip@dpms-vs-vblank-race@a-hdmi-a1.html
   [46]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5026/shard-glk2/igt@kms_flip@dpms-vs-vblank-race@a-hdmi-a1.html

  * igt@kms_flip@plain-flip-fb-recreate-interruptible@a-hdmi-a1:
    - shard-glk:          [FAIL][47] ([i915#2122]) -> [PASS][48]
   [47]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5793/shard-glk2/igt@kms_flip@plain-flip-fb-recreate-interruptible@a-hdmi-a1.html
   [48]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5026/shard-glk5/igt@kms_flip@plain-flip-fb-recreate-interruptible@a-hdmi-a1.html

  * igt@kms_frontbuffer_tracking@fbc-1p-offscren-pri-shrfb-draw-mmap-gtt:
    - shard-iclb:         [DMESG-WARN][49] ([i915#1982]) -> [PASS][50]
   [49]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5793/shard-iclb2/igt@kms_frontbuffer_tracking@fbc-1p-offscren-pri-shrfb-draw-mmap-gtt.html
   [50]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5026/shard-iclb2/igt@kms_frontbuffer_tracking@fbc-1p-offscren-pri-shrfb-draw-mmap-gtt.html

  * igt@kms_frontbuffer_tracking@fbc-2p-primscrn-cur-indfb-draw-render:
    - shard-glk:          [FAIL][51] ([i915#49]) -> [PASS][52]
   [51]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5793/shard-glk8/igt@kms_frontbuffer_tracking@fbc-2p-primscrn-cur-indfb-draw-render.html
   [52]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5026/shard-glk4/igt@kms_frontbuffer_tracking@fbc-2p-primscrn-cur-indfb-draw-render.html

  * igt@kms_frontbuffer_tracking@fbc-rgb565-draw-pwrite:
    - shard-tglb:         [DMESG-WARN][53] ([i915#1982]) -> [PASS][54]
   [53]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5793/shard-tglb7/igt@kms_frontbuffer_tracking@fbc-rgb565-draw-pwrite.html
   [54]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5026/shard-tglb8/igt@kms_frontbuffer_tracking@fbc-rgb565-draw-pwrite.html

  * igt@kms_frontbuffer_tracking@fbc-suspend:
    - shard-kbl:          [INCOMPLETE][55] ([i915#155]) -> [PASS][56]
   [55]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5793/shard-kbl6/igt@kms_frontbuffer_tracking@fbc-suspend.html
   [56]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5026/shard-kbl2/igt@kms_frontbuffer_tracking@fbc-suspend.html

  * igt@kms_hdr@bpc-switch-suspend:
    - shard-kbl:          [DMESG-WARN][57] ([i915#180]) -> [PASS][58] +5 similar issues
   [57]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5793/shard-kbl2/igt@kms_hdr@bpc-switch-suspend.html
   [58]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5026/shard-kbl3/igt@kms_hdr@bpc-switch-suspend.html

  * igt@kms_panel_fitting@atomic-fastset:
    - shard-iclb:         [FAIL][59] ([i915#83]) -> [PASS][60]
   [59]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5793/shard-iclb1/igt@kms_panel_fitting@atomic-fastset.html
   [60]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5026/shard-iclb1/igt@kms_panel_fitting@atomic-fastset.html

  * igt@kms_psr2_su@page_flip:
    - shard-iclb:         [SKIP][61] ([fdo#109642] / [fdo#111068]) -> [PASS][62]
   [61]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5793/shard-iclb4/igt@kms_psr2_su@page_flip.html
   [62]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5026/shard-iclb2/igt@kms_psr2_su@page_flip.html

  * igt@kms_psr@psr2_suspend:
    - shard-iclb:         [SKIP][63] ([fdo#109441]) -> [PASS][64] +1 similar issue
   [63]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5793/shard-iclb4/igt@kms_psr@psr2_suspend.html
   [64]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5026/shard-iclb2/igt@kms_psr@psr2_suspend.html

  
#### Warnings ####

  * igt@gem_eio@in-flight-suspend:
    - shard-tglb:         [DMESG-WARN][65] ([i915#1436] / [i915#1602] / [i915#1887] / [i915#2411]) -> [DMESG-WARN][66] ([i915#2411])
   [65]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5793/shard-tglb3/igt@gem_eio@in-flight-suspend.html
   [66]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5026/shard-tglb3/igt@gem_eio@in-flight-suspend.html

  * igt@i915_pm_dc@dc3co-vpb-simulation:
    - shard-iclb:         [SKIP][67] ([i915#658]) -> [SKIP][68] ([i915#588])
   [67]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5793/shard-iclb7/igt@i915_pm_dc@dc3co-vpb-simulation.html
   [68]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5026/shard-iclb2/igt@i915_pm_dc@dc3co-vpb-simulation.html

  * igt@kms_content_protection@atomic:
    - shard-apl:          [TIMEOUT][69] ([i915#1319] / [i915#1635] / [i915#1958]) -> [FAIL][70] ([fdo#110321] / [fdo#110336] / [i915#1635])
   [69]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5793/shard-apl3/igt@kms_content_protection@atomic.html
   [70]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5026/shard-apl7/igt@kms_content_protection@atomic.html

  * igt@kms_content_protection@lic:
    - shard-apl:          [FAIL][71] ([fdo#110321] / [i915#1635]) -> [TIMEOUT][72] ([i915#1319] / [i915#1635] / [i915#1958])
   [71]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5793/shard-apl1/igt@kms_content_protection@lic.html
   [72]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5026/shard-apl1/igt@kms_content_protection@lic.html

  * igt@kms_plane@plane-panning-bottom-right-suspend-pipe-a-planes:
    - shard-tglb:         [DMESG-WARN][73] ([i915#2411]) -> [INCOMPLETE][74] ([i915#456])
   [73]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5793/shard-tglb1/igt@kms_plane@plane-panning-bottom-right-suspend-pipe-a-planes.html
   [74]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5026/shard-tglb2/igt@kms_plane@plane-panning-bottom-right-suspend-pipe-a-planes.html

  
  {name}: This element is suppressed. This means it is ignored when computing
          the status of the difference (SUCCESS, WARNING, or FAILURE).

  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [fdo#109441]: https://bugs.freedesktop.org/show_bug.cgi?id=109441
  [fdo#109642]: https://bugs.freedesktop.org/show_bug.cgi?id=109642
  [fdo#110321]: https://bugs.freedesktop.org/show_bug.cgi?id=110321
  [fdo#110336]: https://bugs.freedesktop.org/show_bug.cgi?id=110336
  [fdo#111068]: https://bugs.freedesktop.org/show_bug.cgi?id=111068
  [i915#118]: https://gitlab.freedesktop.org/drm/intel/issues/118
  [i915#1319]: https://gitlab.freedesktop.org/drm/intel/issues/1319
  [i915#1436]: https://gitlab.freedesktop.org/drm/intel/issues/1436
  [i915#155]: https://gitlab.freedesktop.org/drm/intel/issues/155
  [i915#1602]: https://gitlab.freedesktop.org/drm/intel/issues/1602
  [i915#1635]: https://gitlab.freedesktop.org/drm/intel/issues/1635
  [i915#180]: https://gitlab.freedesktop.org/drm/intel/issues/180
  [i915#1887]: https://gitlab.freedesktop.org/drm/intel/issues/1887
  [i915#1899]: https://gitlab.freedesktop.org/drm/intel/issues/1899
  [i915#1958]: https://gitlab.freedesktop.org/drm/intel/issues/1958
  [i915#1982]: https://gitlab.freedesktop.org/drm/intel/issues/1982
  [i915#2122]: https://gitlab.freedesktop.org/drm/intel/issues/2122
  [i915#2389]: https://gitlab.freedesktop.org/drm/intel/issues/2389
  [i915#2411]: https://gitlab.freedesktop.org/drm/intel/issues/2411
  [i915#2521]: https://gitlab.freedesktop.org/drm/intel/issues/2521
  [i915#31]: https://gitlab.freedesktop.org/drm/intel/issues/31
  [i915#405]: https://gitlab.freedesktop.org/drm/intel/issues/405
  [i915#43]: https://gitlab.freedesktop.org/drm/intel/issues/43
  [i915#454]: https://gitlab.freedesktop.org/drm/intel/issues/454
  [i915#456]: https://gitlab.freedesktop.org/drm/intel/issues/456
  [i915#49]: https://gitlab.freedesktop.org/drm/intel/issues/49
  [i915#588]: https://gitlab.freedesktop.org/drm/intel/issues/588
  [i915#658]: https://gitlab.freedesktop.org/drm/intel/issues/658
  [i915#716]: https://gitlab.freedesktop.org/drm/intel/issues/716
  [i915#83]: https://gitlab.freedesktop.org/drm/intel/issues/83
  [i915#95]: https://gitlab.freedesktop.org/drm/intel/issues/95


Participating hosts (8 -> 8)
------------------------------

  No changes in participating hosts


Build changes
-------------

  * CI: CI-20190529 -> None
  * IGT: IGT_5793 -> IGTPW_5026

  CI-20190529: 20190529
  CI_DRM_9075: fd24361b2b76956b5c056bc430a4c77edecb7744 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGTPW_5026: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5026/index.html
  IGT_5793: c34792447c9fc4d05dd75873cdb99d9ffe57ea23 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_5026/index.html

[-- Attachment #1.2: Type: text/html, Size: 19771 bytes --]

[-- Attachment #2: Type: text/plain, Size: 154 bytes --]

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [igt-dev] [PATCH i-g-t] lib/ioctl_wrappers: Keep IGT working without pread/pwrite ioctls
  2020-09-30  3:40 [igt-dev] [PATCH i-g-t] lib/ioctl_wrappers: Keep IGT working without pread/pwrite ioctls Ashutosh Dixit
  2020-09-30  4:15 ` [igt-dev] ✓ Fi.CI.BAT: success for lib/ioctl_wrappers: Keep IGT working without pread/pwrite ioctls (rev6) Patchwork
  2020-09-30 13:29 ` [igt-dev] ✓ Fi.CI.IGT: " Patchwork
@ 2020-10-02  9:36 ` Chris Wilson
  2020-10-02 19:34   ` Dixit, Ashutosh
  2021-01-11 20:46 ` [igt-dev] [i-g-t] " Dave Airlie
  3 siblings, 1 reply; 17+ messages in thread
From: Chris Wilson @ 2020-10-02  9:36 UTC (permalink / raw)
  To: Ashutosh Dixit, igt-dev

Quoting Ashutosh Dixit (2020-09-30 04:40:29)
> The general direction at this time is to phase out pread/write ioctls
> and not support them in future products. This means IGT must handle
> the absence of these ioctls. This patch does this by modifying
> gem_read() and gem_write() to do the read/write using the pread/pwrite
> ioctls first but when these ioctls are unavailable fall back to doing
> the read/write using a combination of mmap and memcpy.

Note that not all pread/pwrite can be replaced by a mmap(bo) + mempcy.
Removing pread/pwrite support for arbitrary bo is a significant ABI
regression.
-Chris
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [igt-dev] [PATCH i-g-t] lib/ioctl_wrappers: Keep IGT working without pread/pwrite ioctls
  2020-10-02  9:36 ` [igt-dev] [PATCH i-g-t] lib/ioctl_wrappers: Keep IGT working without pread/pwrite ioctls Chris Wilson
@ 2020-10-02 19:34   ` Dixit, Ashutosh
  0 siblings, 0 replies; 17+ messages in thread
From: Dixit, Ashutosh @ 2020-10-02 19:34 UTC (permalink / raw)
  To: Chris Wilson; +Cc: igt-dev

On Fri, 02 Oct 2020 02:36:41 -0700, Chris Wilson wrote:
>
> Quoting Ashutosh Dixit (2020-09-30 04:40:29)
> > The general direction at this time is to phase out pread/write ioctls
> > and not support them in future products. This means IGT must handle
> > the absence of these ioctls. This patch does this by modifying
> > gem_read() and gem_write() to do the read/write using the pread/pwrite
> > ioctls first but when these ioctls are unavailable fall back to doing
> > the read/write using a combination of mmap and memcpy.
>
> Note that not all pread/pwrite can be replaced by a mmap(bo) + mempcy.
> Removing pread/pwrite support for arbitrary bo is a significant ABI
> regression.

Dave Airlie NAK'd pread/pwrite for discrete here:

https://lists.freedesktop.org/archives/intel-gfx/2020-July/244677.html

Also UMD's are not using them anymore so the thinking is we would
discontinue pread/pwrite in i915 for future generations but retain them for
previous generations.
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [igt-dev] [i-g-t] lib/ioctl_wrappers: Keep IGT working without pread/pwrite ioctls
  2020-09-30  3:40 [igt-dev] [PATCH i-g-t] lib/ioctl_wrappers: Keep IGT working without pread/pwrite ioctls Ashutosh Dixit
                   ` (2 preceding siblings ...)
  2020-10-02  9:36 ` [igt-dev] [PATCH i-g-t] lib/ioctl_wrappers: Keep IGT working without pread/pwrite ioctls Chris Wilson
@ 2021-01-11 20:46 ` Dave Airlie
  3 siblings, 0 replies; 17+ messages in thread
From: Dave Airlie @ 2021-01-11 20:46 UTC (permalink / raw)
  To: Ashutosh Dixit; +Cc: igt-dev, airlied

[-- Attachment #1: Type: text/plain, Size: 15057 bytes --]


> The general direction at this time is to phase out pread/write ioctls
> and not support them in future products. This means IGT must handle
> the absence of these ioctls. This patch does this by modifying
> gem_read() and gem_write() to do the read/write using the pread/pwrite
> ioctls first but when these ioctls are unavailable fall back to doing
> the read/write using a combination of mmap and memcpy.
> 
> Callers who must absolutely use the pread/pwrite ioctls (such as tests
> which test these ioctls or must otherwise only use the pread/pwrite
> ioctls) must use gem_require_pread_pwrite() to skip when these ioctls
> are not available.
> 
> v1: Removed __gem_pread, gem_pread, __gem_pwrite and gem_pwrite
>     introduced previously since they are not necessary,
>     gem_require_pread_pwrite is sufficient
> v2: Fix CI failures in gem_advise and gen9_exec_parse by introducing
>     gem_require_pread_pwrite
> v3: Skip mmap for 0 length read/write's
> v4: Remove redundant igt_assert's
> v5: Re-run
> v6: s/EOPNOTSUPP/-EOPNOTSUPP/

There appears to be some push back on landing this,

Acked-by: Dave Airlie <airlied@redhat.com>

If there are testing reasons for keeping pread/pwrite then they should
be done with a test interface via debugfs or hidden behind a big
unstable testing trapdoor, not a uAPI for other userpsace to use.

Dave.

> 
> Reviewed-by: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com>
> Signed-off-by: Ashutosh Dixit <ashutosh.dixit@intel.com>
> ---
>  lib/ioctl_wrappers.c                        | 135 +++++++++++++++++++-
>  lib/ioctl_wrappers.h                        |   3 +
>  tests/i915/gem_madvise.c                    |   2 +
>  tests/i915/gem_partial_pwrite_pread.c       |   1 +
>  tests/i915/gem_pread.c                      |   1 +
>  tests/i915/gem_pread_after_blit.c           |   1 +
>  tests/i915/gem_pwrite.c                     |   1 +
>  tests/i915/gem_pwrite_snooped.c             |   1 +
>  tests/i915/gem_readwrite.c                  |   1 +
>  tests/i915/gem_set_tiling_vs_pwrite.c       |   1 +
>  tests/i915/gem_tiled_partial_pwrite_pread.c |   1 +
>  tests/i915/gem_tiled_pread_basic.c          |   1 +
>  tests/i915/gem_tiled_pread_pwrite.c         |   1 +
>  tests/i915/gem_userptr_blits.c              |   2 +
>  tests/i915/gen9_exec_parse.c                |   4 +-
>  15 files changed, 149 insertions(+), 7 deletions(-)
> 
> diff --git a/lib/ioctl_wrappers.c b/lib/ioctl_wrappers.c
> index edac50f0f..ac77b3eb6 100644
> --- a/lib/ioctl_wrappers.c
> +++ b/lib/ioctl_wrappers.c
> @@ -55,6 +55,7 @@
>  #include "igt_debugfs.h"
>  #include "igt_sysfs.h"
>  #include "config.h"
> +#include "i915/gem_mman.h"
>  
>  #ifdef HAVE_VALGRIND
>  #include <valgrind/valgrind.h>
> @@ -323,6 +324,70 @@ void gem_close(int fd, uint32_t handle)
>  	do_ioctl(fd, DRM_IOCTL_GEM_CLOSE, &close_bo);
>  }
>  
> +static bool is_cache_coherent(int fd, uint32_t handle)
> +{
> +	return gem_get_caching(fd, handle) != I915_CACHING_NONE;
> +}
> +
> +static void mmap_write(int fd, uint32_t handle, uint64_t offset,
> +		       const void *buf, uint64_t length)
> +{
> +	void *map = NULL;
> +
> +	if (!length)
> +		return;
> +
> +	if (is_cache_coherent(fd, handle)) {
> +		/* offset arg for mmap functions must be 0 */
> +		map = __gem_mmap__cpu_coherent(fd, handle, 0, offset + length,
> +					       PROT_READ | PROT_WRITE);
> +		if (map)
> +			gem_set_domain(fd, handle,
> +				       I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
> +	}
> +
> +	if (!map) {
> +		map = __gem_mmap_offset__wc(fd, handle, 0, offset + length,
> +					    PROT_READ | PROT_WRITE);
> +		if (!map)
> +			map = gem_mmap__wc(fd, handle, 0, offset + length,
> +					   PROT_READ | PROT_WRITE);
> +		gem_set_domain(fd, handle,
> +			       I915_GEM_DOMAIN_WC, I915_GEM_DOMAIN_WC);
> +	}
> +
> +	memcpy(map + offset, buf, length);
> +	munmap(map, offset + length);
> +}
> +
> +static void mmap_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t length)
> +{
> +	void *map = NULL;
> +
> +	if (!length)
> +		return;
> +
> +	if (gem_has_llc(fd) || is_cache_coherent(fd, handle)) {
> +		/* offset arg for mmap functions must be 0 */
> +		map = __gem_mmap__cpu_coherent(fd, handle, 0,
> +					       offset + length, PROT_READ);
> +		if (map)
> +			gem_set_domain(fd, handle, I915_GEM_DOMAIN_CPU, 0);
> +	}
> +
> +	if (!map) {
> +		map = __gem_mmap_offset__wc(fd, handle, 0, offset + length,
> +					    PROT_READ);
> +		if (!map)
> +			map = gem_mmap__wc(fd, handle, 0, offset + length,
> +					   PROT_READ);
> +		gem_set_domain(fd, handle, I915_GEM_DOMAIN_WC, 0);
> +	}
> +
> +	memcpy(buf, map + offset, length);
> +	munmap(map, offset + length);
> +}
> +
>  int __gem_write(int fd, uint32_t handle, uint64_t offset, const void *buf, uint64_t length)
>  {
>  	struct drm_i915_gem_pwrite gem_pwrite;
> @@ -348,12 +413,18 @@ int __gem_write(int fd, uint32_t handle, uint64_t offset, const void *buf, uint6
>   * @buf: pointer to the data to write into the buffer
>   * @length: size of the subrange
>   *
> - * This wraps the PWRITE ioctl, which is to upload a linear data to a subrange
> - * of a gem buffer object.
> + * Method to write to a gem object. Uses the PWRITE ioctl when it is
> + * available, else it uses mmap + memcpy to upload linear data to a
> + * subrange of a gem buffer object.
>   */
>  void gem_write(int fd, uint32_t handle, uint64_t offset, const void *buf, uint64_t length)
>  {
> -	igt_assert_eq(__gem_write(fd, handle, offset, buf, length), 0);
> +	int ret = __gem_write(fd, handle, offset, buf, length);
> +
> +	igt_assert(ret == 0 || ret == -EOPNOTSUPP);
> +
> +	if (ret == -EOPNOTSUPP)
> +		mmap_write(fd, handle, offset, buf, length);
>  }
>  
>  int __gem_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t length)
> @@ -380,12 +451,64 @@ int __gem_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t len
>   * @buf: pointer to the data to read into
>   * @length: size of the subrange
>   *
> - * This wraps the PREAD ioctl, which is to download a linear data to a subrange
> - * of a gem buffer object.
> + * Method to read from a gem object. Uses the PREAD ioctl when it is
> + * available, else it uses mmap + memcpy to download linear data from a
> + * subrange of a gem buffer object.
>   */
>  void gem_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t length)
>  {
> -	igt_assert_eq(__gem_read(fd, handle, offset, buf, length), 0);
> +	int ret = __gem_read(fd, handle, offset, buf, length);
> +
> +	igt_assert(ret == 0 || ret == -EOPNOTSUPP);
> +
> +	if (ret == -EOPNOTSUPP)
> +		mmap_read(fd, handle, offset, buf, length);
> +}
> +
> +/**
> + * gem_has_pwrite
> + * @fd: open i915 drm file descriptor
> + *
> + * Feature test macro to query whether pwrite ioctl is supported
> + */
> +bool gem_has_pwrite(int fd)
> +{
> +	uint32_t handle = gem_create(fd, 4096);
> +	int buf, ret;
> +
> +	ret = __gem_write(fd, handle, 0, &buf, sizeof(buf));
> +	gem_close(fd, handle);
> +
> +	return ret != -EOPNOTSUPP;
> +}
> +
> +/**
> + * gem_has_pread
> + * @fd: open i915 drm file descriptor
> + *
> + * Feature test macro to query whether pread ioctl is supported
> + */
> +bool gem_has_pread(int fd)
> +{
> +	uint32_t handle = gem_create(fd, 4096);
> +	int buf, ret;
> +
> +	ret = __gem_read(fd, handle, 0, &buf, sizeof(buf));
> +	gem_close(fd, handle);
> +
> +	return ret != -EOPNOTSUPP;
> +}
> +
> +/**
> + * gem_require_pread_pwrite
> + * @fd: open i915 drm file descriptor
> + *
> + * Feature test macro to query whether pread/pwrite ioctls are supported
> + * and skip if they are not
> + */
> +void gem_require_pread_pwrite(int fd)
> +{
> +	igt_require(gem_has_pread(fd) && gem_has_pwrite(fd));
>  }
>  
>  int __gem_set_domain(int fd, uint32_t handle, uint32_t read, uint32_t write)
> diff --git a/lib/ioctl_wrappers.h b/lib/ioctl_wrappers.h
> index b76bea564..81166000a 100644
> --- a/lib/ioctl_wrappers.h
> +++ b/lib/ioctl_wrappers.h
> @@ -71,6 +71,9 @@ int __gem_write(int fd, uint32_t handle, uint64_t offset, const void *buf, uint6
>  void gem_write(int fd, uint32_t handle, uint64_t offset,  const void *buf, uint64_t length);
>  int __gem_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t length);
>  void gem_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t length);
> +bool gem_has_pwrite(int fd);
> +bool gem_has_pread(int fd);
> +void gem_require_pread_pwrite(int fd);
>  int __gem_set_domain(int fd, uint32_t handle, uint32_t read, uint32_t write);
>  void gem_set_domain(int fd, uint32_t handle, uint32_t read, uint32_t write);
>  int gem_wait(int fd, uint32_t handle, int64_t *timeout_ns);
> diff --git a/tests/i915/gem_madvise.c b/tests/i915/gem_madvise.c
> index 54c9befff..92e1c5192 100644
> --- a/tests/i915/gem_madvise.c
> +++ b/tests/i915/gem_madvise.c
> @@ -154,6 +154,7 @@ dontneed_before_pwrite(void)
>  	uint32_t bbe = MI_BATCH_BUFFER_END;
>  	uint32_t handle;
>  
> +	gem_require_pread_pwrite(fd);
>  	handle = gem_create(fd, OBJECT_SIZE);
>  	gem_madvise(fd, handle, I915_MADV_DONTNEED);
>  
> @@ -170,6 +171,7 @@ dontneed_before_exec(void)
>  	struct drm_i915_gem_exec_object2 exec;
>  	uint32_t buf[] = { MI_BATCH_BUFFER_END, 0 };
>  
> +	gem_require_pread_pwrite(fd);
>  	memset(&execbuf, 0, sizeof(execbuf));
>  	memset(&exec, 0, sizeof(exec));
>  
> diff --git a/tests/i915/gem_partial_pwrite_pread.c b/tests/i915/gem_partial_pwrite_pread.c
> index b10284721..fd7b19f31 100644
> --- a/tests/i915/gem_partial_pwrite_pread.c
> +++ b/tests/i915/gem_partial_pwrite_pread.c
> @@ -281,6 +281,7 @@ igt_main
>  		data.drm_fd = drm_open_driver(DRIVER_INTEL);
>  		igt_require_gem(data.drm_fd);
>  		gem_require_blitter(data.drm_fd);
> +		gem_require_pread_pwrite(data.drm_fd);
>  
>  		data.devid = intel_get_drm_devid(data.drm_fd);
>  		data.bops = buf_ops_create(data.drm_fd);
> diff --git a/tests/i915/gem_pread.c b/tests/i915/gem_pread.c
> index 6d12b8e9f..db1eacedc 100644
> --- a/tests/i915/gem_pread.c
> +++ b/tests/i915/gem_pread.c
> @@ -149,6 +149,7 @@ igt_main_args("s:", NULL, help_str, opt_handler, NULL)
>  
>  	igt_fixture {
>  		fd = drm_open_driver(DRIVER_INTEL);
> +		gem_require_pread_pwrite(fd);
>  
>  		dst = gem_create(fd, object_size);
>  		src = malloc(object_size);
> diff --git a/tests/i915/gem_pread_after_blit.c b/tests/i915/gem_pread_after_blit.c
> index 81454c930..5c99d0887 100644
> --- a/tests/i915/gem_pread_after_blit.c
> +++ b/tests/i915/gem_pread_after_blit.c
> @@ -212,6 +212,7 @@ igt_main
>  	igt_fixture {
>  		fd = drm_open_driver(DRIVER_INTEL);
>  		igt_require_gem(fd);
> +		gem_require_pread_pwrite(fd);
>  
>  		bufmgr = drm_intel_bufmgr_gem_init(fd, 4096);
>  		drm_intel_bufmgr_gem_enable_reuse(bufmgr);
> diff --git a/tests/i915/gem_pwrite.c b/tests/i915/gem_pwrite.c
> index e491263fd..eea51f978 100644
> --- a/tests/i915/gem_pwrite.c
> +++ b/tests/i915/gem_pwrite.c
> @@ -317,6 +317,7 @@ igt_main_args("s:", NULL, help_str, opt_handler, NULL)
>  
>  	igt_fixture {
>  		fd = drm_open_driver(DRIVER_INTEL);
> +		gem_require_pread_pwrite(fd);
>  
>  		dst = gem_create(fd, object_size);
>  		src = malloc(object_size);
> diff --git a/tests/i915/gem_pwrite_snooped.c b/tests/i915/gem_pwrite_snooped.c
> index 4a3395241..a2eca6afc 100644
> --- a/tests/i915/gem_pwrite_snooped.c
> +++ b/tests/i915/gem_pwrite_snooped.c
> @@ -132,6 +132,7 @@ igt_simple_main
>  	fd = drm_open_driver(DRIVER_INTEL);
>  	igt_require_gem(fd);
>  	gem_require_blitter(fd);
> +	gem_require_pread_pwrite(fd);
>  
>  	devid = intel_get_drm_devid(fd);
>  	bufmgr = drm_intel_bufmgr_gem_init(fd, 4096);
> diff --git a/tests/i915/gem_readwrite.c b/tests/i915/gem_readwrite.c
> index 6b2977c1c..ca31741c6 100644
> --- a/tests/i915/gem_readwrite.c
> +++ b/tests/i915/gem_readwrite.c
> @@ -83,6 +83,7 @@ igt_main
>  
>  	igt_fixture {
>  		fd = drm_open_driver(DRIVER_INTEL);
> +		gem_require_pread_pwrite(fd);
>  
>  		handle = gem_create(fd, OBJECT_SIZE);
>  	}
> diff --git a/tests/i915/gem_set_tiling_vs_pwrite.c b/tests/i915/gem_set_tiling_vs_pwrite.c
> index 302ea24b6..8f38c9b9b 100644
> --- a/tests/i915/gem_set_tiling_vs_pwrite.c
> +++ b/tests/i915/gem_set_tiling_vs_pwrite.c
> @@ -55,6 +55,7 @@ igt_simple_main
>  
>  	fd = drm_open_driver(DRIVER_INTEL);
>  	igt_require(gem_available_fences(fd) > 0);
> +	gem_require_pread_pwrite(fd);
>  
>  	for (int i = 0; i < OBJECT_SIZE/4; i++)
>  		data[i] = i;
> diff --git a/tests/i915/gem_tiled_partial_pwrite_pread.c b/tests/i915/gem_tiled_partial_pwrite_pread.c
> index 7de5358b2..0c4545990 100644
> --- a/tests/i915/gem_tiled_partial_pwrite_pread.c
> +++ b/tests/i915/gem_tiled_partial_pwrite_pread.c
> @@ -270,6 +270,7 @@ igt_main
>  		igt_require_gem(fd);
>  		gem_require_mappable_ggtt(fd);
>  		gem_require_blitter(fd);
> +		gem_require_pread_pwrite(fd);
>  
>  		bufmgr = drm_intel_bufmgr_gem_init(fd, 4096);
>  		//drm_intel_bufmgr_gem_enable_reuse(bufmgr);
> diff --git a/tests/i915/gem_tiled_pread_basic.c b/tests/i915/gem_tiled_pread_basic.c
> index 7cb644104..f8f73c03a 100644
> --- a/tests/i915/gem_tiled_pread_basic.c
> +++ b/tests/i915/gem_tiled_pread_basic.c
> @@ -127,6 +127,7 @@ igt_simple_main
>  	igt_require(gem_available_fences(fd) > 0);
>  	handle = create_bo(fd);
>  	igt_require(gem_get_tiling(fd, handle, &tiling, &swizzle));
> +	gem_require_pread_pwrite(fd);
>  
>  	devid = intel_get_drm_devid(fd);
>  
> diff --git a/tests/i915/gem_tiled_pread_pwrite.c b/tests/i915/gem_tiled_pread_pwrite.c
> index f58048faa..28490840f 100644
> --- a/tests/i915/gem_tiled_pread_pwrite.c
> +++ b/tests/i915/gem_tiled_pread_pwrite.c
> @@ -114,6 +114,7 @@ igt_simple_main
>  	
>  	fd = drm_open_driver(DRIVER_INTEL);
>  	igt_require(gem_available_fences(fd) > 0);
> +	gem_require_pread_pwrite(fd);
>  
>  	count = gem_available_fences(fd) + 1;
>  	intel_require_memory(2 * count, sizeof(linear), CHECK_RAM);
> diff --git a/tests/i915/gem_userptr_blits.c b/tests/i915/gem_userptr_blits.c
> index 268423dcd..0ccfdbd9c 100644
> --- a/tests/i915/gem_userptr_blits.c
> +++ b/tests/i915/gem_userptr_blits.c
> @@ -890,6 +890,7 @@ static int test_forbidden_ops(int fd)
>  	uint32_t handle;
>  	void *ptr;
>  
> +	gem_require_pread_pwrite(fd);
>  	igt_assert(posix_memalign(&ptr, PAGE_SIZE, PAGE_SIZE) == 0);
>  	gem_userptr(fd, ptr, PAGE_SIZE, 0, userptr_flags, &handle);
>  
> @@ -1416,6 +1417,7 @@ static void test_readonly_pwrite(int i915)
>  	 */
>  
>  	igt_require(igt_setup_clflush());
> +	gem_require_pread_pwrite(i915);
>  
>  	sz = 16 << 12;
>  	pages = mmap(NULL, sz, PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
> diff --git a/tests/i915/gen9_exec_parse.c b/tests/i915/gen9_exec_parse.c
> index 7ddb5bf2b..cfb6de080 100644
> --- a/tests/i915/gen9_exec_parse.c
> +++ b/tests/i915/gen9_exec_parse.c
> @@ -1104,8 +1104,10 @@ igt_main
>  			   -EINVAL);
>  	}
>  
> -	igt_subtest("batch-invalid-length")
> +	igt_subtest("batch-invalid-length") {
> +		gem_require_pread_pwrite(i915);
>  		test_invalid_length(i915, handle);
> +	}
>  
>  	igt_subtest("basic-rejected")
>  		test_rejected(i915, handle, false);
> 

[-- Attachment #2: Type: text/plain, Size: 154 bytes --]

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [igt-dev] [PATCH i-g-t] lib/ioctl_wrappers: Keep IGT working without pread/pwrite ioctls
  2021-03-16  9:16     ` Tvrtko Ursulin
@ 2021-03-16 18:46       ` Dixit, Ashutosh
  0 siblings, 0 replies; 17+ messages in thread
From: Dixit, Ashutosh @ 2021-03-16 18:46 UTC (permalink / raw)
  To: Tvrtko Ursulin; +Cc: igt-dev

On Tue, 16 Mar 2021 02:16:14 -0700, Tvrtko Ursulin wrote:
> On 15/03/2021 23:19, Dixit, Ashutosh wrote:
> > On Mon, 15 Mar 2021 09:51:04 -0700, Tvrtko Ursulin wrote:
> >>> @@ -324,6 +325,70 @@ void gem_close(int fd, uint32_t handle)
> >>>	do_ioctl(fd, DRM_IOCTL_GEM_CLOSE, &close_bo);
> >>>    }
> >>>    +static bool is_cache_coherent(int fd, uint32_t handle)
> >>> +{
> >>> +	return gem_get_caching(fd, handle) != I915_CACHING_NONE;
> >>> +}
> >>> +
> >>> +static void mmap_write(int fd, uint32_t handle, uint64_t offset,
> >>> +		       const void *buf, uint64_t length)
> >>> +{
> >>> +	void *map = NULL;
> >>> +
> >>> +	if (!length)
> >>> +		return;
> >>> +
> >>> +	if (is_cache_coherent(fd, handle)) {
> >>> +		/* offset arg for mmap functions must be 0 */
> >>
> >> Offset and lenght I think. So I guess none of the tests used non-aligned
> >> access? Might be worth putting those two as asserts at the top of
> >> mmap_write and mmap_read.
> >
> > Hi Tvrtko, sorry I think you missed the logic. offset and length coming
> > into mmap_write() and mmap_read() are non-zero (so tests are using
> > non-aligned access). However __gem_mmap_offset() (called from
> > __gem_mmap__cpu_coherent() etc.) has an assert that needs the offset to be
> > 0 (which is what the comment above refers to). Therefore instead of doing
> > mmap(offset, length) below we do mmap(0, offset + length).
>
> But is offset + length is guaranteed to be page aligned? I thought mmap(2)
> requires it. Well, if it works obviously I was thinking wrong..

Yes, seems to be working. Offset for mmap(2) needs to be page aligned (the
length is probably bumped up to be page aligned by the kernel) and in the
case of __gem_mmap_offset() the offset supplied to mmap is the page aligned
offset returned by DRM_IOCTL_I915_GEM_MMAP_OFFSET.
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [igt-dev] [PATCH i-g-t] lib/ioctl_wrappers: Keep IGT working without pread/pwrite ioctls
  2021-03-15 23:19   ` Dixit, Ashutosh
@ 2021-03-16  9:16     ` Tvrtko Ursulin
  2021-03-16 18:46       ` Dixit, Ashutosh
  0 siblings, 1 reply; 17+ messages in thread
From: Tvrtko Ursulin @ 2021-03-16  9:16 UTC (permalink / raw)
  To: Dixit, Ashutosh; +Cc: igt-dev



On 15/03/2021 23:19, Dixit, Ashutosh wrote:
> On Mon, 15 Mar 2021 09:51:04 -0700, Tvrtko Ursulin wrote:
>>
>>
>> On 21/01/2021 08:37, Ashutosh Dixit wrote:
>>> The general direction at this time is to phase out pread/write ioctls
>>> and not support them in future products. This means IGT must handle
>>> the absence of these ioctls. This patch does this by modifying
>>> gem_read() and gem_write() to do the read/write using the pread/pwrite
>>> ioctls first but when these ioctls are unavailable fall back to doing
>>> the read/write using a combination of mmap and memcpy.
>>>
>>> Callers who must absolutely use the pread/pwrite ioctls (such as tests
>>> which test these ioctls or must otherwise only use the pread/pwrite
>>> ioctls) must use gem_require_pread_pwrite() to skip when these ioctls
>>> are not available.
>>>
>>> v1: Removed __gem_pread, gem_pread, __gem_pwrite and gem_pwrite
>>>       introduced previously since they are not necessary,
>>>       gem_require_pread_pwrite is sufficient
>>> v2: Fix CI failures in gem_advise and gen9_exec_parse by introducing
>>>       gem_require_pread_pwrite
>>> v3: Skip mmap for 0 length read/write's
>>> v4: Remove redundant igt_assert's
>>> v5: Re-run
>>> v6: s/EOPNOTSUPP/-EOPNOTSUPP/
>>> v7: Rebase on latest master, skip gem_exec_parallel@userptr with
>>>       gem_require_pread_pwrite
>>>
>>> Reviewed-by: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com>
>>> Signed-off-by: Ashutosh Dixit <ashutosh.dixit@intel.com>
>>> ---
>>>    lib/ioctl_wrappers.c                        | 135 +++++++++++++++++++-
>>>    lib/ioctl_wrappers.h                        |   3 +
>>>    tests/i915/gem_exec_parallel.c              |   3 +
>>>    tests/i915/gem_madvise.c                    |   2 +
>>>    tests/i915/gem_partial_pwrite_pread.c       |   1 +
>>>    tests/i915/gem_pread.c                      |   1 +
>>>    tests/i915/gem_pread_after_blit.c           |   1 +
>>>    tests/i915/gem_pwrite.c                     |   1 +
>>>    tests/i915/gem_pwrite_snooped.c             |   1 +
>>>    tests/i915/gem_readwrite.c                  |   1 +
>>>    tests/i915/gem_set_tiling_vs_pwrite.c       |   1 +
>>>    tests/i915/gem_tiled_partial_pwrite_pread.c |   1 +
>>>    tests/i915/gem_tiled_pread_basic.c          |   1 +
>>>    tests/i915/gem_tiled_pread_pwrite.c         |   1 +
>>>    tests/i915/gem_userptr_blits.c              |   2 +
>>>    tests/i915/gen9_exec_parse.c                |   4 +-
>>>    16 files changed, 152 insertions(+), 7 deletions(-)
>>>
>>> diff --git a/lib/ioctl_wrappers.c b/lib/ioctl_wrappers.c
>>> index 45415621b7..4440004c42 100644
>>> --- a/lib/ioctl_wrappers.c
>>> +++ b/lib/ioctl_wrappers.c
>>> @@ -56,6 +56,7 @@
>>>    #include "igt_debugfs.h"
>>>    #include "igt_sysfs.h"
>>>    #include "config.h"
>>> +#include "i915/gem_mman.h"
>>>      #ifdef HAVE_VALGRIND
>>>    #include <valgrind/valgrind.h>
>>> @@ -324,6 +325,70 @@ void gem_close(int fd, uint32_t handle)
>>> 	do_ioctl(fd, DRM_IOCTL_GEM_CLOSE, &close_bo);
>>>    }
>>>    +static bool is_cache_coherent(int fd, uint32_t handle)
>>> +{
>>> +	return gem_get_caching(fd, handle) != I915_CACHING_NONE;
>>> +}
>>> +
>>> +static void mmap_write(int fd, uint32_t handle, uint64_t offset,
>>> +		       const void *buf, uint64_t length)
>>> +{
>>> +	void *map = NULL;
>>> +
>>> +	if (!length)
>>> +		return;
>>> +
>>> +	if (is_cache_coherent(fd, handle)) {
>>> +		/* offset arg for mmap functions must be 0 */
>>
>> Offset and lenght I think. So I guess none of the tests used non-aligned
>> access? Might be worth putting those two as asserts at the top of
>> mmap_write and mmap_read.
> 
> Hi Tvrtko, sorry I think you missed the logic. offset and length coming
> into mmap_write() and mmap_read() are non-zero (so tests are using
> non-aligned access). However __gem_mmap_offset() (called from
> __gem_mmap__cpu_coherent() etc.) has an assert that needs the offset to be
> 0 (which is what the comment above refers to). Therefore instead of doing
> mmap(offset, length) below we do mmap(0, offset + length).

But is offset + length is guaranteed to be page aligned? I thought 
mmap(2) requires it. Well, if it works obviously I was thinking wrong..

Regards,

Tvrtko


> 
> A similar logic is used in mmap_write() in lib/intel_bufops.c.
> 
>> Patch looks good to me. I did not investigate which tests need pread/pwrite
>> and which can just work. I trust that has been established through CI runs
>> and manual inspection.
> 
> Correct.
> 
>> Acked-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
> 
> Thanks.
> 
>> Regards,
>>
>> Tvrtko
>>
>>> +		map = __gem_mmap__cpu_coherent(fd, handle, 0, offset + length,
>>> +					       PROT_READ | PROT_WRITE);
>>> +		if (map)
>>> +			gem_set_domain(fd, handle,
>>> +				       I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
>>> +	}
>>> +
>>> +	if (!map) {
>>> +		map = __gem_mmap_offset__wc(fd, handle, 0, offset + length,
>>> +					    PROT_READ | PROT_WRITE);
>>> +		if (!map)
>>> +			map = gem_mmap__wc(fd, handle, 0, offset + length,
>>> +					   PROT_READ | PROT_WRITE);
>>> +		gem_set_domain(fd, handle,
>>> +			       I915_GEM_DOMAIN_WC, I915_GEM_DOMAIN_WC);
>>> +	}
>>> +
>>> +	memcpy(map + offset, buf, length);
>>> +	munmap(map, offset + length);
>>> +}
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [igt-dev] [PATCH i-g-t] lib/ioctl_wrappers: Keep IGT working without pread/pwrite ioctls
  2021-03-15 16:51 ` Tvrtko Ursulin
@ 2021-03-15 23:19   ` Dixit, Ashutosh
  2021-03-16  9:16     ` Tvrtko Ursulin
  0 siblings, 1 reply; 17+ messages in thread
From: Dixit, Ashutosh @ 2021-03-15 23:19 UTC (permalink / raw)
  To: Tvrtko Ursulin; +Cc: igt-dev

On Mon, 15 Mar 2021 09:51:04 -0700, Tvrtko Ursulin wrote:
>
>
> On 21/01/2021 08:37, Ashutosh Dixit wrote:
> > The general direction at this time is to phase out pread/write ioctls
> > and not support them in future products. This means IGT must handle
> > the absence of these ioctls. This patch does this by modifying
> > gem_read() and gem_write() to do the read/write using the pread/pwrite
> > ioctls first but when these ioctls are unavailable fall back to doing
> > the read/write using a combination of mmap and memcpy.
> >
> > Callers who must absolutely use the pread/pwrite ioctls (such as tests
> > which test these ioctls or must otherwise only use the pread/pwrite
> > ioctls) must use gem_require_pread_pwrite() to skip when these ioctls
> > are not available.
> >
> > v1: Removed __gem_pread, gem_pread, __gem_pwrite and gem_pwrite
> >      introduced previously since they are not necessary,
> >      gem_require_pread_pwrite is sufficient
> > v2: Fix CI failures in gem_advise and gen9_exec_parse by introducing
> >      gem_require_pread_pwrite
> > v3: Skip mmap for 0 length read/write's
> > v4: Remove redundant igt_assert's
> > v5: Re-run
> > v6: s/EOPNOTSUPP/-EOPNOTSUPP/
> > v7: Rebase on latest master, skip gem_exec_parallel@userptr with
> >      gem_require_pread_pwrite
> >
> > Reviewed-by: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com>
> > Signed-off-by: Ashutosh Dixit <ashutosh.dixit@intel.com>
> > ---
> >   lib/ioctl_wrappers.c                        | 135 +++++++++++++++++++-
> >   lib/ioctl_wrappers.h                        |   3 +
> >   tests/i915/gem_exec_parallel.c              |   3 +
> >   tests/i915/gem_madvise.c                    |   2 +
> >   tests/i915/gem_partial_pwrite_pread.c       |   1 +
> >   tests/i915/gem_pread.c                      |   1 +
> >   tests/i915/gem_pread_after_blit.c           |   1 +
> >   tests/i915/gem_pwrite.c                     |   1 +
> >   tests/i915/gem_pwrite_snooped.c             |   1 +
> >   tests/i915/gem_readwrite.c                  |   1 +
> >   tests/i915/gem_set_tiling_vs_pwrite.c       |   1 +
> >   tests/i915/gem_tiled_partial_pwrite_pread.c |   1 +
> >   tests/i915/gem_tiled_pread_basic.c          |   1 +
> >   tests/i915/gem_tiled_pread_pwrite.c         |   1 +
> >   tests/i915/gem_userptr_blits.c              |   2 +
> >   tests/i915/gen9_exec_parse.c                |   4 +-
> >   16 files changed, 152 insertions(+), 7 deletions(-)
> >
> > diff --git a/lib/ioctl_wrappers.c b/lib/ioctl_wrappers.c
> > index 45415621b7..4440004c42 100644
> > --- a/lib/ioctl_wrappers.c
> > +++ b/lib/ioctl_wrappers.c
> > @@ -56,6 +56,7 @@
> >   #include "igt_debugfs.h"
> >   #include "igt_sysfs.h"
> >   #include "config.h"
> > +#include "i915/gem_mman.h"
> >     #ifdef HAVE_VALGRIND
> >   #include <valgrind/valgrind.h>
> > @@ -324,6 +325,70 @@ void gem_close(int fd, uint32_t handle)
> >	do_ioctl(fd, DRM_IOCTL_GEM_CLOSE, &close_bo);
> >   }
> >   +static bool is_cache_coherent(int fd, uint32_t handle)
> > +{
> > +	return gem_get_caching(fd, handle) != I915_CACHING_NONE;
> > +}
> > +
> > +static void mmap_write(int fd, uint32_t handle, uint64_t offset,
> > +		       const void *buf, uint64_t length)
> > +{
> > +	void *map = NULL;
> > +
> > +	if (!length)
> > +		return;
> > +
> > +	if (is_cache_coherent(fd, handle)) {
> > +		/* offset arg for mmap functions must be 0 */
>
> Offset and lenght I think. So I guess none of the tests used non-aligned
> access? Might be worth putting those two as asserts at the top of
> mmap_write and mmap_read.

Hi Tvrtko, sorry I think you missed the logic. offset and length coming
into mmap_write() and mmap_read() are non-zero (so tests are using
non-aligned access). However __gem_mmap_offset() (called from
__gem_mmap__cpu_coherent() etc.) has an assert that needs the offset to be
0 (which is what the comment above refers to). Therefore instead of doing
mmap(offset, length) below we do mmap(0, offset + length).

A similar logic is used in mmap_write() in lib/intel_bufops.c.

> Patch looks good to me. I did not investigate which tests need pread/pwrite
> and which can just work. I trust that has been established through CI runs
> and manual inspection.

Correct.

> Acked-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>

Thanks.

> Regards,
>
> Tvrtko
>
> > +		map = __gem_mmap__cpu_coherent(fd, handle, 0, offset + length,
> > +					       PROT_READ | PROT_WRITE);
> > +		if (map)
> > +			gem_set_domain(fd, handle,
> > +				       I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
> > +	}
> > +
> > +	if (!map) {
> > +		map = __gem_mmap_offset__wc(fd, handle, 0, offset + length,
> > +					    PROT_READ | PROT_WRITE);
> > +		if (!map)
> > +			map = gem_mmap__wc(fd, handle, 0, offset + length,
> > +					   PROT_READ | PROT_WRITE);
> > +		gem_set_domain(fd, handle,
> > +			       I915_GEM_DOMAIN_WC, I915_GEM_DOMAIN_WC);
> > +	}
> > +
> > +	memcpy(map + offset, buf, length);
> > +	munmap(map, offset + length);
> > +}
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [igt-dev] [PATCH i-g-t] lib/ioctl_wrappers: Keep IGT working without pread/pwrite ioctls
@ 2021-03-15 22:53 Ashutosh Dixit
  0 siblings, 0 replies; 17+ messages in thread
From: Ashutosh Dixit @ 2021-03-15 22:53 UTC (permalink / raw)
  To: igt-dev

The general direction at this time is to phase out pread/write ioctls
and not support them in future products. This means IGT must handle
the absence of these ioctls. This patch does this by modifying
gem_read() and gem_write() to do the read/write using the pread/pwrite
ioctls first but when these ioctls are unavailable fall back to doing
the read/write using a combination of mmap and memcpy.

Callers who must absolutely use the pread/pwrite ioctls (such as tests
which test these ioctls or must otherwise only use the pread/pwrite
ioctls) must use gem_require_pread_pwrite() to skip when these ioctls
are not available.

v1: Removed __gem_pread, gem_pread, __gem_pwrite and gem_pwrite
    introduced previously since they are not necessary,
    gem_require_pread_pwrite is sufficient
v2: Fix CI failures in gem_advise and gen9_exec_parse by introducing
    gem_require_pread_pwrite
v3: Skip mmap for 0 length read/write's
v4: Remove redundant igt_assert's
v5: Re-run
v6: s/EOPNOTSUPP/-EOPNOTSUPP/
v7: Rebase on latest master, skip gem_exec_parallel@userptr with
    gem_require_pread_pwrite
v8: Re-run
v9: Rebase

Acked-by: Dave Airlie <airlied@redhat.com>
Acked-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Reviewed-by: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com>
Signed-off-by: Ashutosh Dixit <ashutosh.dixit@intel.com>
---
 lib/ioctl_wrappers.c                        | 135 +++++++++++++++++++-
 lib/ioctl_wrappers.h                        |   3 +
 tests/i915/gem_exec_parallel.c              |   3 +
 tests/i915/gem_madvise.c                    |   2 +
 tests/i915/gem_partial_pwrite_pread.c       |   1 +
 tests/i915/gem_pread.c                      |   1 +
 tests/i915/gem_pread_after_blit.c           |   1 +
 tests/i915/gem_pwrite.c                     |   1 +
 tests/i915/gem_pwrite_snooped.c             |   1 +
 tests/i915/gem_readwrite.c                  |   1 +
 tests/i915/gem_set_tiling_vs_pwrite.c       |   1 +
 tests/i915/gem_tiled_partial_pwrite_pread.c |   1 +
 tests/i915/gem_tiled_pread_basic.c          |   1 +
 tests/i915/gem_tiled_pread_pwrite.c         |   1 +
 tests/i915/gem_userptr_blits.c              |   2 +
 tests/i915/gen9_exec_parse.c                |   4 +-
 16 files changed, 152 insertions(+), 7 deletions(-)

diff --git a/lib/ioctl_wrappers.c b/lib/ioctl_wrappers.c
index 45415621b7..4440004c42 100644
--- a/lib/ioctl_wrappers.c
+++ b/lib/ioctl_wrappers.c
@@ -56,6 +56,7 @@
 #include "igt_debugfs.h"
 #include "igt_sysfs.h"
 #include "config.h"
+#include "i915/gem_mman.h"
 
 #ifdef HAVE_VALGRIND
 #include <valgrind/valgrind.h>
@@ -324,6 +325,70 @@ void gem_close(int fd, uint32_t handle)
 	do_ioctl(fd, DRM_IOCTL_GEM_CLOSE, &close_bo);
 }
 
+static bool is_cache_coherent(int fd, uint32_t handle)
+{
+	return gem_get_caching(fd, handle) != I915_CACHING_NONE;
+}
+
+static void mmap_write(int fd, uint32_t handle, uint64_t offset,
+		       const void *buf, uint64_t length)
+{
+	void *map = NULL;
+
+	if (!length)
+		return;
+
+	if (is_cache_coherent(fd, handle)) {
+		/* offset arg for mmap functions must be 0 */
+		map = __gem_mmap__cpu_coherent(fd, handle, 0, offset + length,
+					       PROT_READ | PROT_WRITE);
+		if (map)
+			gem_set_domain(fd, handle,
+				       I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
+	}
+
+	if (!map) {
+		map = __gem_mmap_offset__wc(fd, handle, 0, offset + length,
+					    PROT_READ | PROT_WRITE);
+		if (!map)
+			map = gem_mmap__wc(fd, handle, 0, offset + length,
+					   PROT_READ | PROT_WRITE);
+		gem_set_domain(fd, handle,
+			       I915_GEM_DOMAIN_WC, I915_GEM_DOMAIN_WC);
+	}
+
+	memcpy(map + offset, buf, length);
+	munmap(map, offset + length);
+}
+
+static void mmap_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t length)
+{
+	void *map = NULL;
+
+	if (!length)
+		return;
+
+	if (gem_has_llc(fd) || is_cache_coherent(fd, handle)) {
+		/* offset arg for mmap functions must be 0 */
+		map = __gem_mmap__cpu_coherent(fd, handle, 0,
+					       offset + length, PROT_READ);
+		if (map)
+			gem_set_domain(fd, handle, I915_GEM_DOMAIN_CPU, 0);
+	}
+
+	if (!map) {
+		map = __gem_mmap_offset__wc(fd, handle, 0, offset + length,
+					    PROT_READ);
+		if (!map)
+			map = gem_mmap__wc(fd, handle, 0, offset + length,
+					   PROT_READ);
+		gem_set_domain(fd, handle, I915_GEM_DOMAIN_WC, 0);
+	}
+
+	memcpy(buf, map + offset, length);
+	munmap(map, offset + length);
+}
+
 int __gem_write(int fd, uint32_t handle, uint64_t offset, const void *buf, uint64_t length)
 {
 	struct drm_i915_gem_pwrite gem_pwrite;
@@ -349,12 +414,18 @@ int __gem_write(int fd, uint32_t handle, uint64_t offset, const void *buf, uint6
  * @buf: pointer to the data to write into the buffer
  * @length: size of the subrange
  *
- * This wraps the PWRITE ioctl, which is to upload a linear data to a subrange
- * of a gem buffer object.
+ * Method to write to a gem object. Uses the PWRITE ioctl when it is
+ * available, else it uses mmap + memcpy to upload linear data to a
+ * subrange of a gem buffer object.
  */
 void gem_write(int fd, uint32_t handle, uint64_t offset, const void *buf, uint64_t length)
 {
-	igt_assert_eq(__gem_write(fd, handle, offset, buf, length), 0);
+	int ret = __gem_write(fd, handle, offset, buf, length);
+
+	igt_assert(ret == 0 || ret == -EOPNOTSUPP);
+
+	if (ret == -EOPNOTSUPP)
+		mmap_write(fd, handle, offset, buf, length);
 }
 
 int __gem_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t length)
@@ -381,12 +452,64 @@ int __gem_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t len
  * @buf: pointer to the data to read into
  * @length: size of the subrange
  *
- * This wraps the PREAD ioctl, which is to download a linear data to a subrange
- * of a gem buffer object.
+ * Method to read from a gem object. Uses the PREAD ioctl when it is
+ * available, else it uses mmap + memcpy to download linear data from a
+ * subrange of a gem buffer object.
  */
 void gem_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t length)
 {
-	igt_assert_eq(__gem_read(fd, handle, offset, buf, length), 0);
+	int ret = __gem_read(fd, handle, offset, buf, length);
+
+	igt_assert(ret == 0 || ret == -EOPNOTSUPP);
+
+	if (ret == -EOPNOTSUPP)
+		mmap_read(fd, handle, offset, buf, length);
+}
+
+/**
+ * gem_has_pwrite
+ * @fd: open i915 drm file descriptor
+ *
+ * Feature test macro to query whether pwrite ioctl is supported
+ */
+bool gem_has_pwrite(int fd)
+{
+	uint32_t handle = gem_create(fd, 4096);
+	int buf, ret;
+
+	ret = __gem_write(fd, handle, 0, &buf, sizeof(buf));
+	gem_close(fd, handle);
+
+	return ret != -EOPNOTSUPP;
+}
+
+/**
+ * gem_has_pread
+ * @fd: open i915 drm file descriptor
+ *
+ * Feature test macro to query whether pread ioctl is supported
+ */
+bool gem_has_pread(int fd)
+{
+	uint32_t handle = gem_create(fd, 4096);
+	int buf, ret;
+
+	ret = __gem_read(fd, handle, 0, &buf, sizeof(buf));
+	gem_close(fd, handle);
+
+	return ret != -EOPNOTSUPP;
+}
+
+/**
+ * gem_require_pread_pwrite
+ * @fd: open i915 drm file descriptor
+ *
+ * Feature test macro to query whether pread/pwrite ioctls are supported
+ * and skip if they are not
+ */
+void gem_require_pread_pwrite(int fd)
+{
+	igt_require(gem_has_pread(fd) && gem_has_pwrite(fd));
 }
 
 int __gem_set_domain(int fd, uint32_t handle, uint32_t read, uint32_t write)
diff --git a/lib/ioctl_wrappers.h b/lib/ioctl_wrappers.h
index 69e198419c..9ea673653e 100644
--- a/lib/ioctl_wrappers.h
+++ b/lib/ioctl_wrappers.h
@@ -71,6 +71,9 @@ int __gem_write(int fd, uint32_t handle, uint64_t offset, const void *buf, uint6
 void gem_write(int fd, uint32_t handle, uint64_t offset,  const void *buf, uint64_t length);
 int __gem_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t length);
 void gem_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t length);
+bool gem_has_pwrite(int fd);
+bool gem_has_pread(int fd);
+void gem_require_pread_pwrite(int fd);
 int __gem_set_domain(int fd, uint32_t handle, uint32_t read, uint32_t write);
 void gem_set_domain(int fd, uint32_t handle, uint32_t read, uint32_t write);
 int gem_wait(int fd, uint32_t handle, int64_t *timeout_ns);
diff --git a/tests/i915/gem_exec_parallel.c b/tests/i915/gem_exec_parallel.c
index c9cf9d7afa..73cdc94b7e 100644
--- a/tests/i915/gem_exec_parallel.c
+++ b/tests/i915/gem_exec_parallel.c
@@ -211,6 +211,9 @@ static void all(int fd, struct intel_execution_engine2 *engine, unsigned flags)
 	if (flags & CONTEXTS)
 		gem_require_contexts(fd);
 
+	if (flags & USERPTR)
+		gem_require_pread_pwrite(fd);
+
 	if (flags & FDS) {
 		igt_require(gen > 5);
 		igt_require(igt_allow_unlimited_files());
diff --git a/tests/i915/gem_madvise.c b/tests/i915/gem_madvise.c
index 2cd0b5d7cc..d772d3abdd 100644
--- a/tests/i915/gem_madvise.c
+++ b/tests/i915/gem_madvise.c
@@ -155,6 +155,7 @@ dontneed_before_pwrite(void)
 	uint32_t bbe = MI_BATCH_BUFFER_END;
 	uint32_t handle;
 
+	gem_require_pread_pwrite(fd);
 	handle = gem_create(fd, OBJECT_SIZE);
 	gem_madvise(fd, handle, I915_MADV_DONTNEED);
 
@@ -171,6 +172,7 @@ dontneed_before_exec(void)
 	struct drm_i915_gem_exec_object2 exec;
 	uint32_t buf[] = { MI_BATCH_BUFFER_END, 0 };
 
+	gem_require_pread_pwrite(fd);
 	memset(&execbuf, 0, sizeof(execbuf));
 	memset(&exec, 0, sizeof(exec));
 
diff --git a/tests/i915/gem_partial_pwrite_pread.c b/tests/i915/gem_partial_pwrite_pread.c
index 72c33539d3..5a14d424b2 100644
--- a/tests/i915/gem_partial_pwrite_pread.c
+++ b/tests/i915/gem_partial_pwrite_pread.c
@@ -284,6 +284,7 @@ igt_main
 		data.drm_fd = drm_open_driver(DRIVER_INTEL);
 		igt_require_gem(data.drm_fd);
 		gem_require_blitter(data.drm_fd);
+		gem_require_pread_pwrite(data.drm_fd);
 
 		data.devid = intel_get_drm_devid(data.drm_fd);
 		data.bops = buf_ops_create(data.drm_fd);
diff --git a/tests/i915/gem_pread.c b/tests/i915/gem_pread.c
index 0c4ec0d2fe..ec9991eebd 100644
--- a/tests/i915/gem_pread.c
+++ b/tests/i915/gem_pread.c
@@ -300,6 +300,7 @@ igt_main_args("s:", NULL, help_str, opt_handler, NULL)
 
 	igt_fixture {
 		fd = drm_open_driver(DRIVER_INTEL);
+		gem_require_pread_pwrite(fd);
 
 		dst = gem_create(fd, object_size);
 		src = malloc(object_size);
diff --git a/tests/i915/gem_pread_after_blit.c b/tests/i915/gem_pread_after_blit.c
index f5eba0d50a..3b56f787aa 100644
--- a/tests/i915/gem_pread_after_blit.c
+++ b/tests/i915/gem_pread_after_blit.c
@@ -216,6 +216,7 @@ igt_main
 	igt_fixture {
 		fd = drm_open_driver(DRIVER_INTEL);
 		igt_require_gem(fd);
+		gem_require_pread_pwrite(fd);
 
 		bops = buf_ops_create(fd);
 
diff --git a/tests/i915/gem_pwrite.c b/tests/i915/gem_pwrite.c
index 98bec55821..5fd15e6a8f 100644
--- a/tests/i915/gem_pwrite.c
+++ b/tests/i915/gem_pwrite.c
@@ -488,6 +488,7 @@ igt_main_args("s:", NULL, help_str, opt_handler, NULL)
 
 	igt_fixture {
 		fd = drm_open_driver(DRIVER_INTEL);
+		gem_require_pread_pwrite(fd);
 
 		dst = gem_create(fd, object_size);
 		src = malloc(object_size);
diff --git a/tests/i915/gem_pwrite_snooped.c b/tests/i915/gem_pwrite_snooped.c
index 52ebaec2f2..e6a10747d5 100644
--- a/tests/i915/gem_pwrite_snooped.c
+++ b/tests/i915/gem_pwrite_snooped.c
@@ -133,6 +133,7 @@ igt_simple_main
 	fd = drm_open_driver(DRIVER_INTEL);
 	igt_require_gem(fd);
 	gem_require_blitter(fd);
+	gem_require_pread_pwrite(fd);
 
 	bops = buf_ops_create(fd);
 
diff --git a/tests/i915/gem_readwrite.c b/tests/i915/gem_readwrite.c
index d675810ef2..8a958cc904 100644
--- a/tests/i915/gem_readwrite.c
+++ b/tests/i915/gem_readwrite.c
@@ -85,6 +85,7 @@ igt_main
 
 	igt_fixture {
 		fd = drm_open_driver(DRIVER_INTEL);
+		gem_require_pread_pwrite(fd);
 
 		handle = gem_create(fd, OBJECT_SIZE);
 	}
diff --git a/tests/i915/gem_set_tiling_vs_pwrite.c b/tests/i915/gem_set_tiling_vs_pwrite.c
index 771dd2e136..87909d3c7c 100644
--- a/tests/i915/gem_set_tiling_vs_pwrite.c
+++ b/tests/i915/gem_set_tiling_vs_pwrite.c
@@ -57,6 +57,7 @@ igt_simple_main
 
 	fd = drm_open_driver(DRIVER_INTEL);
 	igt_require(gem_available_fences(fd) > 0);
+	gem_require_pread_pwrite(fd);
 
 	for (int i = 0; i < OBJECT_SIZE/4; i++)
 		data[i] = i;
diff --git a/tests/i915/gem_tiled_partial_pwrite_pread.c b/tests/i915/gem_tiled_partial_pwrite_pread.c
index 4f8f4190b5..95fb69c659 100644
--- a/tests/i915/gem_tiled_partial_pwrite_pread.c
+++ b/tests/i915/gem_tiled_partial_pwrite_pread.c
@@ -280,6 +280,7 @@ igt_main
 		igt_require_gem(fd);
 		gem_require_mappable_ggtt(fd);
 		gem_require_blitter(fd);
+		gem_require_pread_pwrite(fd);
 
 		bops = buf_ops_create(fd);
 
diff --git a/tests/i915/gem_tiled_pread_basic.c b/tests/i915/gem_tiled_pread_basic.c
index 862714140a..186f630f7d 100644
--- a/tests/i915/gem_tiled_pread_basic.c
+++ b/tests/i915/gem_tiled_pread_basic.c
@@ -128,6 +128,7 @@ igt_simple_main
 	igt_require(gem_available_fences(fd) > 0);
 	handle = create_bo(fd);
 	igt_require(gem_get_tiling(fd, handle, &tiling, &swizzle));
+	gem_require_pread_pwrite(fd);
 
 	devid = intel_get_drm_devid(fd);
 
diff --git a/tests/i915/gem_tiled_pread_pwrite.c b/tests/i915/gem_tiled_pread_pwrite.c
index b73fa12626..ef1e1b3c3c 100644
--- a/tests/i915/gem_tiled_pread_pwrite.c
+++ b/tests/i915/gem_tiled_pread_pwrite.c
@@ -114,6 +114,7 @@ igt_simple_main
 	
 	fd = drm_open_driver(DRIVER_INTEL);
 	igt_require(gem_available_fences(fd) > 0);
+	gem_require_pread_pwrite(fd);
 
 	count = gem_available_fences(fd) + 1;
 	intel_require_memory(2 * count, sizeof(linear), CHECK_RAM);
diff --git a/tests/i915/gem_userptr_blits.c b/tests/i915/gem_userptr_blits.c
index 1bc2d3600b..7a80c01611 100644
--- a/tests/i915/gem_userptr_blits.c
+++ b/tests/i915/gem_userptr_blits.c
@@ -1120,6 +1120,7 @@ static int test_forbidden_ops(int fd)
 	uint32_t handle;
 	void *ptr;
 
+	gem_require_pread_pwrite(fd);
 	igt_assert(posix_memalign(&ptr, PAGE_SIZE, PAGE_SIZE) == 0);
 	gem_userptr(fd, ptr, PAGE_SIZE, 0, userptr_flags, &handle);
 
@@ -1648,6 +1649,7 @@ static void test_readonly_pwrite(int i915)
 	 */
 
 	igt_require(igt_setup_clflush());
+	gem_require_pread_pwrite(i915);
 
 	sz = 16 << 12;
 	pages = mmap(NULL, sz, PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
diff --git a/tests/i915/gen9_exec_parse.c b/tests/i915/gen9_exec_parse.c
index 6f54c4e133..f9de90d2cf 100644
--- a/tests/i915/gen9_exec_parse.c
+++ b/tests/i915/gen9_exec_parse.c
@@ -1235,8 +1235,10 @@ igt_main
 			   -EINVAL);
 	}
 
-	igt_subtest("batch-invalid-length")
+	igt_subtest("batch-invalid-length") {
+		gem_require_pread_pwrite(i915);
 		test_invalid_length(i915, handle);
+	}
 
 	igt_subtest("basic-rejected")
 		test_rejected(i915, handle, false);
-- 
2.29.2

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [igt-dev] [PATCH i-g-t] lib/ioctl_wrappers: Keep IGT working without pread/pwrite ioctls
  2021-01-21  8:37 Ashutosh Dixit
@ 2021-03-15 16:51 ` Tvrtko Ursulin
  2021-03-15 23:19   ` Dixit, Ashutosh
  0 siblings, 1 reply; 17+ messages in thread
From: Tvrtko Ursulin @ 2021-03-15 16:51 UTC (permalink / raw)
  To: Ashutosh Dixit, igt-dev


On 21/01/2021 08:37, Ashutosh Dixit wrote:
> The general direction at this time is to phase out pread/write ioctls
> and not support them in future products. This means IGT must handle
> the absence of these ioctls. This patch does this by modifying
> gem_read() and gem_write() to do the read/write using the pread/pwrite
> ioctls first but when these ioctls are unavailable fall back to doing
> the read/write using a combination of mmap and memcpy.
> 
> Callers who must absolutely use the pread/pwrite ioctls (such as tests
> which test these ioctls or must otherwise only use the pread/pwrite
> ioctls) must use gem_require_pread_pwrite() to skip when these ioctls
> are not available.
> 
> v1: Removed __gem_pread, gem_pread, __gem_pwrite and gem_pwrite
>      introduced previously since they are not necessary,
>      gem_require_pread_pwrite is sufficient
> v2: Fix CI failures in gem_advise and gen9_exec_parse by introducing
>      gem_require_pread_pwrite
> v3: Skip mmap for 0 length read/write's
> v4: Remove redundant igt_assert's
> v5: Re-run
> v6: s/EOPNOTSUPP/-EOPNOTSUPP/
> v7: Rebase on latest master, skip gem_exec_parallel@userptr with
>      gem_require_pread_pwrite
> 
> Reviewed-by: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com>
> Signed-off-by: Ashutosh Dixit <ashutosh.dixit@intel.com>
> ---
>   lib/ioctl_wrappers.c                        | 135 +++++++++++++++++++-
>   lib/ioctl_wrappers.h                        |   3 +
>   tests/i915/gem_exec_parallel.c              |   3 +
>   tests/i915/gem_madvise.c                    |   2 +
>   tests/i915/gem_partial_pwrite_pread.c       |   1 +
>   tests/i915/gem_pread.c                      |   1 +
>   tests/i915/gem_pread_after_blit.c           |   1 +
>   tests/i915/gem_pwrite.c                     |   1 +
>   tests/i915/gem_pwrite_snooped.c             |   1 +
>   tests/i915/gem_readwrite.c                  |   1 +
>   tests/i915/gem_set_tiling_vs_pwrite.c       |   1 +
>   tests/i915/gem_tiled_partial_pwrite_pread.c |   1 +
>   tests/i915/gem_tiled_pread_basic.c          |   1 +
>   tests/i915/gem_tiled_pread_pwrite.c         |   1 +
>   tests/i915/gem_userptr_blits.c              |   2 +
>   tests/i915/gen9_exec_parse.c                |   4 +-
>   16 files changed, 152 insertions(+), 7 deletions(-)
> 
> diff --git a/lib/ioctl_wrappers.c b/lib/ioctl_wrappers.c
> index 45415621b7..4440004c42 100644
> --- a/lib/ioctl_wrappers.c
> +++ b/lib/ioctl_wrappers.c
> @@ -56,6 +56,7 @@
>   #include "igt_debugfs.h"
>   #include "igt_sysfs.h"
>   #include "config.h"
> +#include "i915/gem_mman.h"
>   
>   #ifdef HAVE_VALGRIND
>   #include <valgrind/valgrind.h>
> @@ -324,6 +325,70 @@ void gem_close(int fd, uint32_t handle)
>   	do_ioctl(fd, DRM_IOCTL_GEM_CLOSE, &close_bo);
>   }
>   
> +static bool is_cache_coherent(int fd, uint32_t handle)
> +{
> +	return gem_get_caching(fd, handle) != I915_CACHING_NONE;
> +}
> +
> +static void mmap_write(int fd, uint32_t handle, uint64_t offset,
> +		       const void *buf, uint64_t length)
> +{
> +	void *map = NULL;
> +
> +	if (!length)
> +		return;
> +
> +	if (is_cache_coherent(fd, handle)) {
> +		/* offset arg for mmap functions must be 0 */

Offset and lenght I think. So I guess none of the tests used non-aligned 
access? Might be worth putting those two as asserts at the top of 
mmap_write and mmap_read.

Patch looks good to me. I did not investigate which tests need 
pread/pwrite and which can just work. I trust that has been established 
through CI runs and manual inspection.

Acked-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>

Regards,

Tvrtko

> +		map = __gem_mmap__cpu_coherent(fd, handle, 0, offset + length,
> +					       PROT_READ | PROT_WRITE);
> +		if (map)
> +			gem_set_domain(fd, handle,
> +				       I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
> +	}
> +
> +	if (!map) {
> +		map = __gem_mmap_offset__wc(fd, handle, 0, offset + length,
> +					    PROT_READ | PROT_WRITE);
> +		if (!map)
> +			map = gem_mmap__wc(fd, handle, 0, offset + length,
> +					   PROT_READ | PROT_WRITE);
> +		gem_set_domain(fd, handle,
> +			       I915_GEM_DOMAIN_WC, I915_GEM_DOMAIN_WC);
> +	}
> +
> +	memcpy(map + offset, buf, length);
> +	munmap(map, offset + length);
> +}
> +
> +static void mmap_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t length)
> +{
> +	void *map = NULL;
> +
> +	if (!length)
> +		return;
> +
> +	if (gem_has_llc(fd) || is_cache_coherent(fd, handle)) {
> +		/* offset arg for mmap functions must be 0 */
> +		map = __gem_mmap__cpu_coherent(fd, handle, 0,
> +					       offset + length, PROT_READ);
> +		if (map)
> +			gem_set_domain(fd, handle, I915_GEM_DOMAIN_CPU, 0);
> +	}
> +
> +	if (!map) {
> +		map = __gem_mmap_offset__wc(fd, handle, 0, offset + length,
> +					    PROT_READ);
> +		if (!map)
> +			map = gem_mmap__wc(fd, handle, 0, offset + length,
> +					   PROT_READ);
> +		gem_set_domain(fd, handle, I915_GEM_DOMAIN_WC, 0);
> +	}
> +
> +	memcpy(buf, map + offset, length);
> +	munmap(map, offset + length);
> +}
> +
>   int __gem_write(int fd, uint32_t handle, uint64_t offset, const void *buf, uint64_t length)
>   {
>   	struct drm_i915_gem_pwrite gem_pwrite;
> @@ -349,12 +414,18 @@ int __gem_write(int fd, uint32_t handle, uint64_t offset, const void *buf, uint6
>    * @buf: pointer to the data to write into the buffer
>    * @length: size of the subrange
>    *
> - * This wraps the PWRITE ioctl, which is to upload a linear data to a subrange
> - * of a gem buffer object.
> + * Method to write to a gem object. Uses the PWRITE ioctl when it is
> + * available, else it uses mmap + memcpy to upload linear data to a
> + * subrange of a gem buffer object.
>    */
>   void gem_write(int fd, uint32_t handle, uint64_t offset, const void *buf, uint64_t length)
>   {
> -	igt_assert_eq(__gem_write(fd, handle, offset, buf, length), 0);
> +	int ret = __gem_write(fd, handle, offset, buf, length);
> +
> +	igt_assert(ret == 0 || ret == -EOPNOTSUPP);
> +
> +	if (ret == -EOPNOTSUPP)
> +		mmap_write(fd, handle, offset, buf, length);
>   }
>   
>   int __gem_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t length)
> @@ -381,12 +452,64 @@ int __gem_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t len
>    * @buf: pointer to the data to read into
>    * @length: size of the subrange
>    *
> - * This wraps the PREAD ioctl, which is to download a linear data to a subrange
> - * of a gem buffer object.
> + * Method to read from a gem object. Uses the PREAD ioctl when it is
> + * available, else it uses mmap + memcpy to download linear data from a
> + * subrange of a gem buffer object.
>    */
>   void gem_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t length)
>   {
> -	igt_assert_eq(__gem_read(fd, handle, offset, buf, length), 0);
> +	int ret = __gem_read(fd, handle, offset, buf, length);
> +
> +	igt_assert(ret == 0 || ret == -EOPNOTSUPP);
> +
> +	if (ret == -EOPNOTSUPP)
> +		mmap_read(fd, handle, offset, buf, length);
> +}
> +
> +/**
> + * gem_has_pwrite
> + * @fd: open i915 drm file descriptor
> + *
> + * Feature test macro to query whether pwrite ioctl is supported
> + */
> +bool gem_has_pwrite(int fd)
> +{
> +	uint32_t handle = gem_create(fd, 4096);
> +	int buf, ret;
> +
> +	ret = __gem_write(fd, handle, 0, &buf, sizeof(buf));
> +	gem_close(fd, handle);
> +
> +	return ret != -EOPNOTSUPP;
> +}
> +
> +/**
> + * gem_has_pread
> + * @fd: open i915 drm file descriptor
> + *
> + * Feature test macro to query whether pread ioctl is supported
> + */
> +bool gem_has_pread(int fd)
> +{
> +	uint32_t handle = gem_create(fd, 4096);
> +	int buf, ret;
> +
> +	ret = __gem_read(fd, handle, 0, &buf, sizeof(buf));
> +	gem_close(fd, handle);
> +
> +	return ret != -EOPNOTSUPP;
> +}
> +
> +/**
> + * gem_require_pread_pwrite
> + * @fd: open i915 drm file descriptor
> + *
> + * Feature test macro to query whether pread/pwrite ioctls are supported
> + * and skip if they are not
> + */
> +void gem_require_pread_pwrite(int fd)
> +{
> +	igt_require(gem_has_pread(fd) && gem_has_pwrite(fd));
>   }
>   
>   int __gem_set_domain(int fd, uint32_t handle, uint32_t read, uint32_t write)
> diff --git a/lib/ioctl_wrappers.h b/lib/ioctl_wrappers.h
> index 69e198419c..9ea673653e 100644
> --- a/lib/ioctl_wrappers.h
> +++ b/lib/ioctl_wrappers.h
> @@ -71,6 +71,9 @@ int __gem_write(int fd, uint32_t handle, uint64_t offset, const void *buf, uint6
>   void gem_write(int fd, uint32_t handle, uint64_t offset,  const void *buf, uint64_t length);
>   int __gem_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t length);
>   void gem_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t length);
> +bool gem_has_pwrite(int fd);
> +bool gem_has_pread(int fd);
> +void gem_require_pread_pwrite(int fd);
>   int __gem_set_domain(int fd, uint32_t handle, uint32_t read, uint32_t write);
>   void gem_set_domain(int fd, uint32_t handle, uint32_t read, uint32_t write);
>   int gem_wait(int fd, uint32_t handle, int64_t *timeout_ns);
> diff --git a/tests/i915/gem_exec_parallel.c b/tests/i915/gem_exec_parallel.c
> index d3dd06a654..a0469a6438 100644
> --- a/tests/i915/gem_exec_parallel.c
> +++ b/tests/i915/gem_exec_parallel.c
> @@ -204,6 +204,9 @@ static void all(int fd, struct intel_execution_engine2 *engine, unsigned flags)
>   	if (flags & CONTEXTS)
>   		gem_require_contexts(fd);
>   
> +	if (flags & USERPTR)
> +		gem_require_pread_pwrite(fd);
> +
>   	if (flags & FDS) {
>   		igt_require(gen > 5);
>   		igt_require(igt_allow_unlimited_files());
> diff --git a/tests/i915/gem_madvise.c b/tests/i915/gem_madvise.c
> index 623c8b0913..f85c351857 100644
> --- a/tests/i915/gem_madvise.c
> +++ b/tests/i915/gem_madvise.c
> @@ -155,6 +155,7 @@ dontneed_before_pwrite(void)
>   	uint32_t bbe = MI_BATCH_BUFFER_END;
>   	uint32_t handle;
>   
> +	gem_require_pread_pwrite(fd);
>   	handle = gem_create(fd, OBJECT_SIZE);
>   	gem_madvise(fd, handle, I915_MADV_DONTNEED);
>   
> @@ -171,6 +172,7 @@ dontneed_before_exec(void)
>   	struct drm_i915_gem_exec_object2 exec;
>   	uint32_t buf[] = { MI_BATCH_BUFFER_END, 0 };
>   
> +	gem_require_pread_pwrite(fd);
>   	memset(&execbuf, 0, sizeof(execbuf));
>   	memset(&exec, 0, sizeof(exec));
>   
> diff --git a/tests/i915/gem_partial_pwrite_pread.c b/tests/i915/gem_partial_pwrite_pread.c
> index 72c33539d3..5a14d424b2 100644
> --- a/tests/i915/gem_partial_pwrite_pread.c
> +++ b/tests/i915/gem_partial_pwrite_pread.c
> @@ -284,6 +284,7 @@ igt_main
>   		data.drm_fd = drm_open_driver(DRIVER_INTEL);
>   		igt_require_gem(data.drm_fd);
>   		gem_require_blitter(data.drm_fd);
> +		gem_require_pread_pwrite(data.drm_fd);
>   
>   		data.devid = intel_get_drm_devid(data.drm_fd);
>   		data.bops = buf_ops_create(data.drm_fd);
> diff --git a/tests/i915/gem_pread.c b/tests/i915/gem_pread.c
> index 0c4ec0d2fe..ec9991eebd 100644
> --- a/tests/i915/gem_pread.c
> +++ b/tests/i915/gem_pread.c
> @@ -300,6 +300,7 @@ igt_main_args("s:", NULL, help_str, opt_handler, NULL)
>   
>   	igt_fixture {
>   		fd = drm_open_driver(DRIVER_INTEL);
> +		gem_require_pread_pwrite(fd);
>   
>   		dst = gem_create(fd, object_size);
>   		src = malloc(object_size);
> diff --git a/tests/i915/gem_pread_after_blit.c b/tests/i915/gem_pread_after_blit.c
> index f5eba0d50a..3b56f787aa 100644
> --- a/tests/i915/gem_pread_after_blit.c
> +++ b/tests/i915/gem_pread_after_blit.c
> @@ -216,6 +216,7 @@ igt_main
>   	igt_fixture {
>   		fd = drm_open_driver(DRIVER_INTEL);
>   		igt_require_gem(fd);
> +		gem_require_pread_pwrite(fd);
>   
>   		bops = buf_ops_create(fd);
>   
> diff --git a/tests/i915/gem_pwrite.c b/tests/i915/gem_pwrite.c
> index 98bec55821..5fd15e6a8f 100644
> --- a/tests/i915/gem_pwrite.c
> +++ b/tests/i915/gem_pwrite.c
> @@ -488,6 +488,7 @@ igt_main_args("s:", NULL, help_str, opt_handler, NULL)
>   
>   	igt_fixture {
>   		fd = drm_open_driver(DRIVER_INTEL);
> +		gem_require_pread_pwrite(fd);
>   
>   		dst = gem_create(fd, object_size);
>   		src = malloc(object_size);
> diff --git a/tests/i915/gem_pwrite_snooped.c b/tests/i915/gem_pwrite_snooped.c
> index 52ebaec2f2..e6a10747d5 100644
> --- a/tests/i915/gem_pwrite_snooped.c
> +++ b/tests/i915/gem_pwrite_snooped.c
> @@ -133,6 +133,7 @@ igt_simple_main
>   	fd = drm_open_driver(DRIVER_INTEL);
>   	igt_require_gem(fd);
>   	gem_require_blitter(fd);
> +	gem_require_pread_pwrite(fd);
>   
>   	bops = buf_ops_create(fd);
>   
> diff --git a/tests/i915/gem_readwrite.c b/tests/i915/gem_readwrite.c
> index d675810ef2..8a958cc904 100644
> --- a/tests/i915/gem_readwrite.c
> +++ b/tests/i915/gem_readwrite.c
> @@ -85,6 +85,7 @@ igt_main
>   
>   	igt_fixture {
>   		fd = drm_open_driver(DRIVER_INTEL);
> +		gem_require_pread_pwrite(fd);
>   
>   		handle = gem_create(fd, OBJECT_SIZE);
>   	}
> diff --git a/tests/i915/gem_set_tiling_vs_pwrite.c b/tests/i915/gem_set_tiling_vs_pwrite.c
> index 771dd2e136..87909d3c7c 100644
> --- a/tests/i915/gem_set_tiling_vs_pwrite.c
> +++ b/tests/i915/gem_set_tiling_vs_pwrite.c
> @@ -57,6 +57,7 @@ igt_simple_main
>   
>   	fd = drm_open_driver(DRIVER_INTEL);
>   	igt_require(gem_available_fences(fd) > 0);
> +	gem_require_pread_pwrite(fd);
>   
>   	for (int i = 0; i < OBJECT_SIZE/4; i++)
>   		data[i] = i;
> diff --git a/tests/i915/gem_tiled_partial_pwrite_pread.c b/tests/i915/gem_tiled_partial_pwrite_pread.c
> index 4f8f4190b5..95fb69c659 100644
> --- a/tests/i915/gem_tiled_partial_pwrite_pread.c
> +++ b/tests/i915/gem_tiled_partial_pwrite_pread.c
> @@ -280,6 +280,7 @@ igt_main
>   		igt_require_gem(fd);
>   		gem_require_mappable_ggtt(fd);
>   		gem_require_blitter(fd);
> +		gem_require_pread_pwrite(fd);
>   
>   		bops = buf_ops_create(fd);
>   
> diff --git a/tests/i915/gem_tiled_pread_basic.c b/tests/i915/gem_tiled_pread_basic.c
> index 862714140a..186f630f7d 100644
> --- a/tests/i915/gem_tiled_pread_basic.c
> +++ b/tests/i915/gem_tiled_pread_basic.c
> @@ -128,6 +128,7 @@ igt_simple_main
>   	igt_require(gem_available_fences(fd) > 0);
>   	handle = create_bo(fd);
>   	igt_require(gem_get_tiling(fd, handle, &tiling, &swizzle));
> +	gem_require_pread_pwrite(fd);
>   
>   	devid = intel_get_drm_devid(fd);
>   
> diff --git a/tests/i915/gem_tiled_pread_pwrite.c b/tests/i915/gem_tiled_pread_pwrite.c
> index b73fa12626..ef1e1b3c3c 100644
> --- a/tests/i915/gem_tiled_pread_pwrite.c
> +++ b/tests/i915/gem_tiled_pread_pwrite.c
> @@ -114,6 +114,7 @@ igt_simple_main
>   	
>   	fd = drm_open_driver(DRIVER_INTEL);
>   	igt_require(gem_available_fences(fd) > 0);
> +	gem_require_pread_pwrite(fd);
>   
>   	count = gem_available_fences(fd) + 1;
>   	intel_require_memory(2 * count, sizeof(linear), CHECK_RAM);
> diff --git a/tests/i915/gem_userptr_blits.c b/tests/i915/gem_userptr_blits.c
> index 8765123e09..ded761a550 100644
> --- a/tests/i915/gem_userptr_blits.c
> +++ b/tests/i915/gem_userptr_blits.c
> @@ -1137,6 +1137,7 @@ static int test_forbidden_ops(int fd)
>   	uint32_t handle;
>   	void *ptr;
>   
> +	gem_require_pread_pwrite(fd);
>   	igt_assert(posix_memalign(&ptr, PAGE_SIZE, PAGE_SIZE) == 0);
>   	gem_userptr(fd, ptr, PAGE_SIZE, 0, userptr_flags, &handle);
>   
> @@ -1664,6 +1665,7 @@ static void test_readonly_pwrite(int i915)
>   	 */
>   
>   	igt_require(igt_setup_clflush());
> +	gem_require_pread_pwrite(i915);
>   
>   	sz = 16 << 12;
>   	pages = mmap(NULL, sz, PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
> diff --git a/tests/i915/gen9_exec_parse.c b/tests/i915/gen9_exec_parse.c
> index 6f54c4e133..f9de90d2cf 100644
> --- a/tests/i915/gen9_exec_parse.c
> +++ b/tests/i915/gen9_exec_parse.c
> @@ -1235,8 +1235,10 @@ igt_main
>   			   -EINVAL);
>   	}
>   
> -	igt_subtest("batch-invalid-length")
> +	igt_subtest("batch-invalid-length") {
> +		gem_require_pread_pwrite(i915);
>   		test_invalid_length(i915, handle);
> +	}
>   
>   	igt_subtest("basic-rejected")
>   		test_rejected(i915, handle, false);
> 
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [igt-dev] [PATCH i-g-t] lib/ioctl_wrappers: Keep IGT working without pread/pwrite ioctls
@ 2021-01-21  8:37 Ashutosh Dixit
  2021-03-15 16:51 ` Tvrtko Ursulin
  0 siblings, 1 reply; 17+ messages in thread
From: Ashutosh Dixit @ 2021-01-21  8:37 UTC (permalink / raw)
  To: igt-dev

The general direction at this time is to phase out pread/write ioctls
and not support them in future products. This means IGT must handle
the absence of these ioctls. This patch does this by modifying
gem_read() and gem_write() to do the read/write using the pread/pwrite
ioctls first but when these ioctls are unavailable fall back to doing
the read/write using a combination of mmap and memcpy.

Callers who must absolutely use the pread/pwrite ioctls (such as tests
which test these ioctls or must otherwise only use the pread/pwrite
ioctls) must use gem_require_pread_pwrite() to skip when these ioctls
are not available.

v1: Removed __gem_pread, gem_pread, __gem_pwrite and gem_pwrite
    introduced previously since they are not necessary,
    gem_require_pread_pwrite is sufficient
v2: Fix CI failures in gem_advise and gen9_exec_parse by introducing
    gem_require_pread_pwrite
v3: Skip mmap for 0 length read/write's
v4: Remove redundant igt_assert's
v5: Re-run
v6: s/EOPNOTSUPP/-EOPNOTSUPP/
v7: Rebase on latest master, skip gem_exec_parallel@userptr with
    gem_require_pread_pwrite

Reviewed-by: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com>
Signed-off-by: Ashutosh Dixit <ashutosh.dixit@intel.com>
---
 lib/ioctl_wrappers.c                        | 135 +++++++++++++++++++-
 lib/ioctl_wrappers.h                        |   3 +
 tests/i915/gem_exec_parallel.c              |   3 +
 tests/i915/gem_madvise.c                    |   2 +
 tests/i915/gem_partial_pwrite_pread.c       |   1 +
 tests/i915/gem_pread.c                      |   1 +
 tests/i915/gem_pread_after_blit.c           |   1 +
 tests/i915/gem_pwrite.c                     |   1 +
 tests/i915/gem_pwrite_snooped.c             |   1 +
 tests/i915/gem_readwrite.c                  |   1 +
 tests/i915/gem_set_tiling_vs_pwrite.c       |   1 +
 tests/i915/gem_tiled_partial_pwrite_pread.c |   1 +
 tests/i915/gem_tiled_pread_basic.c          |   1 +
 tests/i915/gem_tiled_pread_pwrite.c         |   1 +
 tests/i915/gem_userptr_blits.c              |   2 +
 tests/i915/gen9_exec_parse.c                |   4 +-
 16 files changed, 152 insertions(+), 7 deletions(-)

diff --git a/lib/ioctl_wrappers.c b/lib/ioctl_wrappers.c
index 45415621b7..4440004c42 100644
--- a/lib/ioctl_wrappers.c
+++ b/lib/ioctl_wrappers.c
@@ -56,6 +56,7 @@
 #include "igt_debugfs.h"
 #include "igt_sysfs.h"
 #include "config.h"
+#include "i915/gem_mman.h"
 
 #ifdef HAVE_VALGRIND
 #include <valgrind/valgrind.h>
@@ -324,6 +325,70 @@ void gem_close(int fd, uint32_t handle)
 	do_ioctl(fd, DRM_IOCTL_GEM_CLOSE, &close_bo);
 }
 
+static bool is_cache_coherent(int fd, uint32_t handle)
+{
+	return gem_get_caching(fd, handle) != I915_CACHING_NONE;
+}
+
+static void mmap_write(int fd, uint32_t handle, uint64_t offset,
+		       const void *buf, uint64_t length)
+{
+	void *map = NULL;
+
+	if (!length)
+		return;
+
+	if (is_cache_coherent(fd, handle)) {
+		/* offset arg for mmap functions must be 0 */
+		map = __gem_mmap__cpu_coherent(fd, handle, 0, offset + length,
+					       PROT_READ | PROT_WRITE);
+		if (map)
+			gem_set_domain(fd, handle,
+				       I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
+	}
+
+	if (!map) {
+		map = __gem_mmap_offset__wc(fd, handle, 0, offset + length,
+					    PROT_READ | PROT_WRITE);
+		if (!map)
+			map = gem_mmap__wc(fd, handle, 0, offset + length,
+					   PROT_READ | PROT_WRITE);
+		gem_set_domain(fd, handle,
+			       I915_GEM_DOMAIN_WC, I915_GEM_DOMAIN_WC);
+	}
+
+	memcpy(map + offset, buf, length);
+	munmap(map, offset + length);
+}
+
+static void mmap_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t length)
+{
+	void *map = NULL;
+
+	if (!length)
+		return;
+
+	if (gem_has_llc(fd) || is_cache_coherent(fd, handle)) {
+		/* offset arg for mmap functions must be 0 */
+		map = __gem_mmap__cpu_coherent(fd, handle, 0,
+					       offset + length, PROT_READ);
+		if (map)
+			gem_set_domain(fd, handle, I915_GEM_DOMAIN_CPU, 0);
+	}
+
+	if (!map) {
+		map = __gem_mmap_offset__wc(fd, handle, 0, offset + length,
+					    PROT_READ);
+		if (!map)
+			map = gem_mmap__wc(fd, handle, 0, offset + length,
+					   PROT_READ);
+		gem_set_domain(fd, handle, I915_GEM_DOMAIN_WC, 0);
+	}
+
+	memcpy(buf, map + offset, length);
+	munmap(map, offset + length);
+}
+
 int __gem_write(int fd, uint32_t handle, uint64_t offset, const void *buf, uint64_t length)
 {
 	struct drm_i915_gem_pwrite gem_pwrite;
@@ -349,12 +414,18 @@ int __gem_write(int fd, uint32_t handle, uint64_t offset, const void *buf, uint6
  * @buf: pointer to the data to write into the buffer
  * @length: size of the subrange
  *
- * This wraps the PWRITE ioctl, which is to upload a linear data to a subrange
- * of a gem buffer object.
+ * Method to write to a gem object. Uses the PWRITE ioctl when it is
+ * available, else it uses mmap + memcpy to upload linear data to a
+ * subrange of a gem buffer object.
  */
 void gem_write(int fd, uint32_t handle, uint64_t offset, const void *buf, uint64_t length)
 {
-	igt_assert_eq(__gem_write(fd, handle, offset, buf, length), 0);
+	int ret = __gem_write(fd, handle, offset, buf, length);
+
+	igt_assert(ret == 0 || ret == -EOPNOTSUPP);
+
+	if (ret == -EOPNOTSUPP)
+		mmap_write(fd, handle, offset, buf, length);
 }
 
 int __gem_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t length)
@@ -381,12 +452,64 @@ int __gem_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t len
  * @buf: pointer to the data to read into
  * @length: size of the subrange
  *
- * This wraps the PREAD ioctl, which is to download a linear data to a subrange
- * of a gem buffer object.
+ * Method to read from a gem object. Uses the PREAD ioctl when it is
+ * available, else it uses mmap + memcpy to download linear data from a
+ * subrange of a gem buffer object.
  */
 void gem_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t length)
 {
-	igt_assert_eq(__gem_read(fd, handle, offset, buf, length), 0);
+	int ret = __gem_read(fd, handle, offset, buf, length);
+
+	igt_assert(ret == 0 || ret == -EOPNOTSUPP);
+
+	if (ret == -EOPNOTSUPP)
+		mmap_read(fd, handle, offset, buf, length);
+}
+
+/**
+ * gem_has_pwrite
+ * @fd: open i915 drm file descriptor
+ *
+ * Feature test macro to query whether pwrite ioctl is supported
+ */
+bool gem_has_pwrite(int fd)
+{
+	uint32_t handle = gem_create(fd, 4096);
+	int buf, ret;
+
+	ret = __gem_write(fd, handle, 0, &buf, sizeof(buf));
+	gem_close(fd, handle);
+
+	return ret != -EOPNOTSUPP;
+}
+
+/**
+ * gem_has_pread
+ * @fd: open i915 drm file descriptor
+ *
+ * Feature test macro to query whether pread ioctl is supported
+ */
+bool gem_has_pread(int fd)
+{
+	uint32_t handle = gem_create(fd, 4096);
+	int buf, ret;
+
+	ret = __gem_read(fd, handle, 0, &buf, sizeof(buf));
+	gem_close(fd, handle);
+
+	return ret != -EOPNOTSUPP;
+}
+
+/**
+ * gem_require_pread_pwrite
+ * @fd: open i915 drm file descriptor
+ *
+ * Feature test macro to query whether pread/pwrite ioctls are supported
+ * and skip if they are not
+ */
+void gem_require_pread_pwrite(int fd)
+{
+	igt_require(gem_has_pread(fd) && gem_has_pwrite(fd));
 }
 
 int __gem_set_domain(int fd, uint32_t handle, uint32_t read, uint32_t write)
diff --git a/lib/ioctl_wrappers.h b/lib/ioctl_wrappers.h
index 69e198419c..9ea673653e 100644
--- a/lib/ioctl_wrappers.h
+++ b/lib/ioctl_wrappers.h
@@ -71,6 +71,9 @@ int __gem_write(int fd, uint32_t handle, uint64_t offset, const void *buf, uint6
 void gem_write(int fd, uint32_t handle, uint64_t offset,  const void *buf, uint64_t length);
 int __gem_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t length);
 void gem_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t length);
+bool gem_has_pwrite(int fd);
+bool gem_has_pread(int fd);
+void gem_require_pread_pwrite(int fd);
 int __gem_set_domain(int fd, uint32_t handle, uint32_t read, uint32_t write);
 void gem_set_domain(int fd, uint32_t handle, uint32_t read, uint32_t write);
 int gem_wait(int fd, uint32_t handle, int64_t *timeout_ns);
diff --git a/tests/i915/gem_exec_parallel.c b/tests/i915/gem_exec_parallel.c
index d3dd06a654..a0469a6438 100644
--- a/tests/i915/gem_exec_parallel.c
+++ b/tests/i915/gem_exec_parallel.c
@@ -204,6 +204,9 @@ static void all(int fd, struct intel_execution_engine2 *engine, unsigned flags)
 	if (flags & CONTEXTS)
 		gem_require_contexts(fd);
 
+	if (flags & USERPTR)
+		gem_require_pread_pwrite(fd);
+
 	if (flags & FDS) {
 		igt_require(gen > 5);
 		igt_require(igt_allow_unlimited_files());
diff --git a/tests/i915/gem_madvise.c b/tests/i915/gem_madvise.c
index 623c8b0913..f85c351857 100644
--- a/tests/i915/gem_madvise.c
+++ b/tests/i915/gem_madvise.c
@@ -155,6 +155,7 @@ dontneed_before_pwrite(void)
 	uint32_t bbe = MI_BATCH_BUFFER_END;
 	uint32_t handle;
 
+	gem_require_pread_pwrite(fd);
 	handle = gem_create(fd, OBJECT_SIZE);
 	gem_madvise(fd, handle, I915_MADV_DONTNEED);
 
@@ -171,6 +172,7 @@ dontneed_before_exec(void)
 	struct drm_i915_gem_exec_object2 exec;
 	uint32_t buf[] = { MI_BATCH_BUFFER_END, 0 };
 
+	gem_require_pread_pwrite(fd);
 	memset(&execbuf, 0, sizeof(execbuf));
 	memset(&exec, 0, sizeof(exec));
 
diff --git a/tests/i915/gem_partial_pwrite_pread.c b/tests/i915/gem_partial_pwrite_pread.c
index 72c33539d3..5a14d424b2 100644
--- a/tests/i915/gem_partial_pwrite_pread.c
+++ b/tests/i915/gem_partial_pwrite_pread.c
@@ -284,6 +284,7 @@ igt_main
 		data.drm_fd = drm_open_driver(DRIVER_INTEL);
 		igt_require_gem(data.drm_fd);
 		gem_require_blitter(data.drm_fd);
+		gem_require_pread_pwrite(data.drm_fd);
 
 		data.devid = intel_get_drm_devid(data.drm_fd);
 		data.bops = buf_ops_create(data.drm_fd);
diff --git a/tests/i915/gem_pread.c b/tests/i915/gem_pread.c
index 0c4ec0d2fe..ec9991eebd 100644
--- a/tests/i915/gem_pread.c
+++ b/tests/i915/gem_pread.c
@@ -300,6 +300,7 @@ igt_main_args("s:", NULL, help_str, opt_handler, NULL)
 
 	igt_fixture {
 		fd = drm_open_driver(DRIVER_INTEL);
+		gem_require_pread_pwrite(fd);
 
 		dst = gem_create(fd, object_size);
 		src = malloc(object_size);
diff --git a/tests/i915/gem_pread_after_blit.c b/tests/i915/gem_pread_after_blit.c
index f5eba0d50a..3b56f787aa 100644
--- a/tests/i915/gem_pread_after_blit.c
+++ b/tests/i915/gem_pread_after_blit.c
@@ -216,6 +216,7 @@ igt_main
 	igt_fixture {
 		fd = drm_open_driver(DRIVER_INTEL);
 		igt_require_gem(fd);
+		gem_require_pread_pwrite(fd);
 
 		bops = buf_ops_create(fd);
 
diff --git a/tests/i915/gem_pwrite.c b/tests/i915/gem_pwrite.c
index 98bec55821..5fd15e6a8f 100644
--- a/tests/i915/gem_pwrite.c
+++ b/tests/i915/gem_pwrite.c
@@ -488,6 +488,7 @@ igt_main_args("s:", NULL, help_str, opt_handler, NULL)
 
 	igt_fixture {
 		fd = drm_open_driver(DRIVER_INTEL);
+		gem_require_pread_pwrite(fd);
 
 		dst = gem_create(fd, object_size);
 		src = malloc(object_size);
diff --git a/tests/i915/gem_pwrite_snooped.c b/tests/i915/gem_pwrite_snooped.c
index 52ebaec2f2..e6a10747d5 100644
--- a/tests/i915/gem_pwrite_snooped.c
+++ b/tests/i915/gem_pwrite_snooped.c
@@ -133,6 +133,7 @@ igt_simple_main
 	fd = drm_open_driver(DRIVER_INTEL);
 	igt_require_gem(fd);
 	gem_require_blitter(fd);
+	gem_require_pread_pwrite(fd);
 
 	bops = buf_ops_create(fd);
 
diff --git a/tests/i915/gem_readwrite.c b/tests/i915/gem_readwrite.c
index d675810ef2..8a958cc904 100644
--- a/tests/i915/gem_readwrite.c
+++ b/tests/i915/gem_readwrite.c
@@ -85,6 +85,7 @@ igt_main
 
 	igt_fixture {
 		fd = drm_open_driver(DRIVER_INTEL);
+		gem_require_pread_pwrite(fd);
 
 		handle = gem_create(fd, OBJECT_SIZE);
 	}
diff --git a/tests/i915/gem_set_tiling_vs_pwrite.c b/tests/i915/gem_set_tiling_vs_pwrite.c
index 771dd2e136..87909d3c7c 100644
--- a/tests/i915/gem_set_tiling_vs_pwrite.c
+++ b/tests/i915/gem_set_tiling_vs_pwrite.c
@@ -57,6 +57,7 @@ igt_simple_main
 
 	fd = drm_open_driver(DRIVER_INTEL);
 	igt_require(gem_available_fences(fd) > 0);
+	gem_require_pread_pwrite(fd);
 
 	for (int i = 0; i < OBJECT_SIZE/4; i++)
 		data[i] = i;
diff --git a/tests/i915/gem_tiled_partial_pwrite_pread.c b/tests/i915/gem_tiled_partial_pwrite_pread.c
index 4f8f4190b5..95fb69c659 100644
--- a/tests/i915/gem_tiled_partial_pwrite_pread.c
+++ b/tests/i915/gem_tiled_partial_pwrite_pread.c
@@ -280,6 +280,7 @@ igt_main
 		igt_require_gem(fd);
 		gem_require_mappable_ggtt(fd);
 		gem_require_blitter(fd);
+		gem_require_pread_pwrite(fd);
 
 		bops = buf_ops_create(fd);
 
diff --git a/tests/i915/gem_tiled_pread_basic.c b/tests/i915/gem_tiled_pread_basic.c
index 862714140a..186f630f7d 100644
--- a/tests/i915/gem_tiled_pread_basic.c
+++ b/tests/i915/gem_tiled_pread_basic.c
@@ -128,6 +128,7 @@ igt_simple_main
 	igt_require(gem_available_fences(fd) > 0);
 	handle = create_bo(fd);
 	igt_require(gem_get_tiling(fd, handle, &tiling, &swizzle));
+	gem_require_pread_pwrite(fd);
 
 	devid = intel_get_drm_devid(fd);
 
diff --git a/tests/i915/gem_tiled_pread_pwrite.c b/tests/i915/gem_tiled_pread_pwrite.c
index b73fa12626..ef1e1b3c3c 100644
--- a/tests/i915/gem_tiled_pread_pwrite.c
+++ b/tests/i915/gem_tiled_pread_pwrite.c
@@ -114,6 +114,7 @@ igt_simple_main
 	
 	fd = drm_open_driver(DRIVER_INTEL);
 	igt_require(gem_available_fences(fd) > 0);
+	gem_require_pread_pwrite(fd);
 
 	count = gem_available_fences(fd) + 1;
 	intel_require_memory(2 * count, sizeof(linear), CHECK_RAM);
diff --git a/tests/i915/gem_userptr_blits.c b/tests/i915/gem_userptr_blits.c
index 8765123e09..ded761a550 100644
--- a/tests/i915/gem_userptr_blits.c
+++ b/tests/i915/gem_userptr_blits.c
@@ -1137,6 +1137,7 @@ static int test_forbidden_ops(int fd)
 	uint32_t handle;
 	void *ptr;
 
+	gem_require_pread_pwrite(fd);
 	igt_assert(posix_memalign(&ptr, PAGE_SIZE, PAGE_SIZE) == 0);
 	gem_userptr(fd, ptr, PAGE_SIZE, 0, userptr_flags, &handle);
 
@@ -1664,6 +1665,7 @@ static void test_readonly_pwrite(int i915)
 	 */
 
 	igt_require(igt_setup_clflush());
+	gem_require_pread_pwrite(i915);
 
 	sz = 16 << 12;
 	pages = mmap(NULL, sz, PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
diff --git a/tests/i915/gen9_exec_parse.c b/tests/i915/gen9_exec_parse.c
index 6f54c4e133..f9de90d2cf 100644
--- a/tests/i915/gen9_exec_parse.c
+++ b/tests/i915/gen9_exec_parse.c
@@ -1235,8 +1235,10 @@ igt_main
 			   -EINVAL);
 	}
 
-	igt_subtest("batch-invalid-length")
+	igt_subtest("batch-invalid-length") {
+		gem_require_pread_pwrite(i915);
 		test_invalid_length(i915, handle);
+	}
 
 	igt_subtest("basic-rejected")
 		test_rejected(i915, handle, false);
-- 
2.29.2

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [igt-dev] [PATCH i-g-t] lib/ioctl_wrappers: Keep IGT working without pread/pwrite ioctls
@ 2020-09-16 20:11 Ashutosh Dixit
  0 siblings, 0 replies; 17+ messages in thread
From: Ashutosh Dixit @ 2020-09-16 20:11 UTC (permalink / raw)
  To: igt-dev

The general direction at this time is to phase out pread/write ioctls
and not support them in future products. This means IGT must handle
the absence of these ioctls. This patch does this by modifying
gem_read() and gem_write() to do the read/write using the pread/pwrite
ioctls first but when these ioctls are unavailable fall back to doing
the read/write using a combination of mmap and memcpy.

Callers who must absolutely use the pread/pwrite ioctls (such as tests
which test these ioctls or must otherwise only use the pread/pwrite
ioctls) must use gem_require_pread_pwrite() to skip when these ioctls
are not available.

v1: Removed __gem_pread, gem_pread, __gem_pwrite and gem_pwrite
    introduced previously since they are not necessary,
    gem_require_pread_pwrite is sufficient
v2: Fix CI failures in gem_advise and gen9_exec_parse by introducing
    gem_require_pread_pwrite
v3: Skip mmap for 0 length read/write's
v4: Remove redundant igt_assert's

Signed-off-by: Ashutosh Dixit <ashutosh.dixit@intel.com>
---
 lib/ioctl_wrappers.c                        | 135 +++++++++++++++++++-
 lib/ioctl_wrappers.h                        |   3 +
 tests/i915/gem_madvise.c                    |   2 +
 tests/i915/gem_partial_pwrite_pread.c       |   1 +
 tests/i915/gem_pread.c                      |   1 +
 tests/i915/gem_pread_after_blit.c           |   1 +
 tests/i915/gem_pwrite.c                     |   1 +
 tests/i915/gem_pwrite_snooped.c             |   1 +
 tests/i915/gem_readwrite.c                  |   1 +
 tests/i915/gem_set_tiling_vs_pwrite.c       |   1 +
 tests/i915/gem_tiled_partial_pwrite_pread.c |   1 +
 tests/i915/gem_tiled_pread_basic.c          |   1 +
 tests/i915/gem_tiled_pread_pwrite.c         |   1 +
 tests/i915/gem_userptr_blits.c              |   2 +
 tests/i915/gen9_exec_parse.c                |   4 +-
 15 files changed, 149 insertions(+), 7 deletions(-)

diff --git a/lib/ioctl_wrappers.c b/lib/ioctl_wrappers.c
index 3781286d8e..1e80e30bd5 100644
--- a/lib/ioctl_wrappers.c
+++ b/lib/ioctl_wrappers.c
@@ -55,6 +55,7 @@
 #include "igt_debugfs.h"
 #include "igt_sysfs.h"
 #include "config.h"
+#include "i915/gem_mman.h"
 
 #ifdef HAVE_VALGRIND
 #include <valgrind/valgrind.h>
@@ -323,6 +324,70 @@ void gem_close(int fd, uint32_t handle)
 	do_ioctl(fd, DRM_IOCTL_GEM_CLOSE, &close_bo);
 }
 
+static bool is_cache_coherent(int fd, uint32_t handle)
+{
+	return gem_get_caching(fd, handle) != I915_CACHING_NONE;
+}
+
+static void mmap_write(int fd, uint32_t handle, uint64_t offset,
+		       const void *buf, uint64_t length)
+{
+	void *map = NULL;
+
+	if (!length)
+		return;
+
+	if (is_cache_coherent(fd, handle)) {
+		/* offset arg for mmap functions must be 0 */
+		map = __gem_mmap__cpu_coherent(fd, handle, 0, offset + length,
+					       PROT_READ | PROT_WRITE);
+		if (map)
+			gem_set_domain(fd, handle,
+				       I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
+	}
+
+	if (!map) {
+		map = __gem_mmap_offset__wc(fd, handle, 0, offset + length,
+					    PROT_READ | PROT_WRITE);
+		if (!map)
+			map = gem_mmap__wc(fd, handle, 0, offset + length,
+					   PROT_READ | PROT_WRITE);
+		gem_set_domain(fd, handle,
+			       I915_GEM_DOMAIN_WC, I915_GEM_DOMAIN_WC);
+	}
+
+	memcpy(map + offset, buf, length);
+	munmap(map, offset + length);
+}
+
+static void mmap_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t length)
+{
+	void *map = NULL;
+
+	if (!length)
+		return;
+
+	if (gem_has_llc(fd) || is_cache_coherent(fd, handle)) {
+		/* offset arg for mmap functions must be 0 */
+		map = __gem_mmap__cpu_coherent(fd, handle, 0,
+					       offset + length, PROT_READ);
+		if (map)
+			gem_set_domain(fd, handle, I915_GEM_DOMAIN_CPU, 0);
+	}
+
+	if (!map) {
+		map = __gem_mmap_offset__wc(fd, handle, 0, offset + length,
+					    PROT_READ);
+		if (!map)
+			map = gem_mmap__wc(fd, handle, 0, offset + length,
+					   PROT_READ);
+		gem_set_domain(fd, handle, I915_GEM_DOMAIN_WC, 0);
+	}
+
+	memcpy(buf, map + offset, length);
+	munmap(map, offset + length);
+}
+
 int __gem_write(int fd, uint32_t handle, uint64_t offset, const void *buf, uint64_t length)
 {
 	struct drm_i915_gem_pwrite gem_pwrite;
@@ -348,12 +413,18 @@ int __gem_write(int fd, uint32_t handle, uint64_t offset, const void *buf, uint6
  * @buf: pointer to the data to write into the buffer
  * @length: size of the subrange
  *
- * This wraps the PWRITE ioctl, which is to upload a linear data to a subrange
- * of a gem buffer object.
+ * Method to write to a gem object. Uses the PWRITE ioctl when it is
+ * available, else it uses mmap + memcpy to upload linear data to a
+ * subrange of a gem buffer object.
  */
 void gem_write(int fd, uint32_t handle, uint64_t offset, const void *buf, uint64_t length)
 {
-	igt_assert_eq(__gem_write(fd, handle, offset, buf, length), 0);
+	int ret = __gem_write(fd, handle, offset, buf, length);
+
+	igt_assert(ret == 0 || ret == EOPNOTSUPP);
+
+	if (ret == EOPNOTSUPP)
+		mmap_write(fd, handle, offset, buf, length);
 }
 
 int __gem_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t length)
@@ -380,12 +451,64 @@ int __gem_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t len
  * @buf: pointer to the data to read into
  * @length: size of the subrange
  *
- * This wraps the PREAD ioctl, which is to download a linear data to a subrange
- * of a gem buffer object.
+ * Method to read from a gem object. Uses the PREAD ioctl when it is
+ * available, else it uses mmap + memcpy to download linear data from a
+ * subrange of a gem buffer object.
  */
 void gem_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t length)
 {
-	igt_assert_eq(__gem_read(fd, handle, offset, buf, length), 0);
+	int ret = __gem_read(fd, handle, offset, buf, length);
+
+	igt_assert(ret == 0 || ret == EOPNOTSUPP);
+
+	if (ret == EOPNOTSUPP)
+		mmap_read(fd, handle, offset, buf, length);
+}
+
+/**
+ * gem_has_pwrite
+ * @fd: open i915 drm file descriptor
+ *
+ * Feature test macro to query whether pwrite ioctl is supported
+ */
+bool gem_has_pwrite(int fd)
+{
+	uint32_t handle = gem_create(fd, 4096);
+	int buf, ret;
+
+	ret = __gem_write(fd, handle, 0, &buf, sizeof(buf));
+	gem_close(fd, handle);
+
+	return ret != EOPNOTSUPP;
+}
+
+/**
+ * gem_has_pread
+ * @fd: open i915 drm file descriptor
+ *
+ * Feature test macro to query whether pread ioctl is supported
+ */
+bool gem_has_pread(int fd)
+{
+	uint32_t handle = gem_create(fd, 4096);
+	int buf, ret;
+
+	ret = __gem_read(fd, handle, 0, &buf, sizeof(buf));
+	gem_close(fd, handle);
+
+	return ret != EOPNOTSUPP;
+}
+
+/**
+ * gem_require_pread_pwrite
+ * @fd: open i915 drm file descriptor
+ *
+ * Feature test macro to query whether pread/pwrite ioctls are supported
+ * and skip if they are not
+ */
+void gem_require_pread_pwrite(int fd)
+{
+	igt_require(gem_has_pread(fd) && gem_has_pwrite(fd));
 }
 
 int __gem_set_domain(int fd, uint32_t handle, uint32_t read, uint32_t write)
diff --git a/lib/ioctl_wrappers.h b/lib/ioctl_wrappers.h
index 870ac8b7bc..6ba551a71b 100644
--- a/lib/ioctl_wrappers.h
+++ b/lib/ioctl_wrappers.h
@@ -71,6 +71,9 @@ int __gem_write(int fd, uint32_t handle, uint64_t offset, const void *buf, uint6
 void gem_write(int fd, uint32_t handle, uint64_t offset,  const void *buf, uint64_t length);
 int __gem_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t length);
 void gem_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t length);
+bool gem_has_pwrite(int fd);
+bool gem_has_pread(int fd);
+void gem_require_pread_pwrite(int fd);
 int __gem_set_domain(int fd, uint32_t handle, uint32_t read, uint32_t write);
 void gem_set_domain(int fd, uint32_t handle, uint32_t read, uint32_t write);
 int gem_wait(int fd, uint32_t handle, int64_t *timeout_ns);
diff --git a/tests/i915/gem_madvise.c b/tests/i915/gem_madvise.c
index 54c9befff2..92e1c5192d 100644
--- a/tests/i915/gem_madvise.c
+++ b/tests/i915/gem_madvise.c
@@ -154,6 +154,7 @@ dontneed_before_pwrite(void)
 	uint32_t bbe = MI_BATCH_BUFFER_END;
 	uint32_t handle;
 
+	gem_require_pread_pwrite(fd);
 	handle = gem_create(fd, OBJECT_SIZE);
 	gem_madvise(fd, handle, I915_MADV_DONTNEED);
 
@@ -170,6 +171,7 @@ dontneed_before_exec(void)
 	struct drm_i915_gem_exec_object2 exec;
 	uint32_t buf[] = { MI_BATCH_BUFFER_END, 0 };
 
+	gem_require_pread_pwrite(fd);
 	memset(&execbuf, 0, sizeof(execbuf));
 	memset(&exec, 0, sizeof(exec));
 
diff --git a/tests/i915/gem_partial_pwrite_pread.c b/tests/i915/gem_partial_pwrite_pread.c
index b102847212..fd7b19f31b 100644
--- a/tests/i915/gem_partial_pwrite_pread.c
+++ b/tests/i915/gem_partial_pwrite_pread.c
@@ -281,6 +281,7 @@ igt_main
 		data.drm_fd = drm_open_driver(DRIVER_INTEL);
 		igt_require_gem(data.drm_fd);
 		gem_require_blitter(data.drm_fd);
+		gem_require_pread_pwrite(data.drm_fd);
 
 		data.devid = intel_get_drm_devid(data.drm_fd);
 		data.bops = buf_ops_create(data.drm_fd);
diff --git a/tests/i915/gem_pread.c b/tests/i915/gem_pread.c
index 6d12b8e9f8..db1eacedc2 100644
--- a/tests/i915/gem_pread.c
+++ b/tests/i915/gem_pread.c
@@ -149,6 +149,7 @@ igt_main_args("s:", NULL, help_str, opt_handler, NULL)
 
 	igt_fixture {
 		fd = drm_open_driver(DRIVER_INTEL);
+		gem_require_pread_pwrite(fd);
 
 		dst = gem_create(fd, object_size);
 		src = malloc(object_size);
diff --git a/tests/i915/gem_pread_after_blit.c b/tests/i915/gem_pread_after_blit.c
index 81454c9303..5c99d0887c 100644
--- a/tests/i915/gem_pread_after_blit.c
+++ b/tests/i915/gem_pread_after_blit.c
@@ -212,6 +212,7 @@ igt_main
 	igt_fixture {
 		fd = drm_open_driver(DRIVER_INTEL);
 		igt_require_gem(fd);
+		gem_require_pread_pwrite(fd);
 
 		bufmgr = drm_intel_bufmgr_gem_init(fd, 4096);
 		drm_intel_bufmgr_gem_enable_reuse(bufmgr);
diff --git a/tests/i915/gem_pwrite.c b/tests/i915/gem_pwrite.c
index e491263fd3..eea51f9780 100644
--- a/tests/i915/gem_pwrite.c
+++ b/tests/i915/gem_pwrite.c
@@ -317,6 +317,7 @@ igt_main_args("s:", NULL, help_str, opt_handler, NULL)
 
 	igt_fixture {
 		fd = drm_open_driver(DRIVER_INTEL);
+		gem_require_pread_pwrite(fd);
 
 		dst = gem_create(fd, object_size);
 		src = malloc(object_size);
diff --git a/tests/i915/gem_pwrite_snooped.c b/tests/i915/gem_pwrite_snooped.c
index 4a33952414..a2eca6afc5 100644
--- a/tests/i915/gem_pwrite_snooped.c
+++ b/tests/i915/gem_pwrite_snooped.c
@@ -132,6 +132,7 @@ igt_simple_main
 	fd = drm_open_driver(DRIVER_INTEL);
 	igt_require_gem(fd);
 	gem_require_blitter(fd);
+	gem_require_pread_pwrite(fd);
 
 	devid = intel_get_drm_devid(fd);
 	bufmgr = drm_intel_bufmgr_gem_init(fd, 4096);
diff --git a/tests/i915/gem_readwrite.c b/tests/i915/gem_readwrite.c
index 6b2977c1c4..ca31741c60 100644
--- a/tests/i915/gem_readwrite.c
+++ b/tests/i915/gem_readwrite.c
@@ -83,6 +83,7 @@ igt_main
 
 	igt_fixture {
 		fd = drm_open_driver(DRIVER_INTEL);
+		gem_require_pread_pwrite(fd);
 
 		handle = gem_create(fd, OBJECT_SIZE);
 	}
diff --git a/tests/i915/gem_set_tiling_vs_pwrite.c b/tests/i915/gem_set_tiling_vs_pwrite.c
index 302ea24b6d..8f38c9b9b7 100644
--- a/tests/i915/gem_set_tiling_vs_pwrite.c
+++ b/tests/i915/gem_set_tiling_vs_pwrite.c
@@ -55,6 +55,7 @@ igt_simple_main
 
 	fd = drm_open_driver(DRIVER_INTEL);
 	igt_require(gem_available_fences(fd) > 0);
+	gem_require_pread_pwrite(fd);
 
 	for (int i = 0; i < OBJECT_SIZE/4; i++)
 		data[i] = i;
diff --git a/tests/i915/gem_tiled_partial_pwrite_pread.c b/tests/i915/gem_tiled_partial_pwrite_pread.c
index 7de5358b20..0c4545990c 100644
--- a/tests/i915/gem_tiled_partial_pwrite_pread.c
+++ b/tests/i915/gem_tiled_partial_pwrite_pread.c
@@ -270,6 +270,7 @@ igt_main
 		igt_require_gem(fd);
 		gem_require_mappable_ggtt(fd);
 		gem_require_blitter(fd);
+		gem_require_pread_pwrite(fd);
 
 		bufmgr = drm_intel_bufmgr_gem_init(fd, 4096);
 		//drm_intel_bufmgr_gem_enable_reuse(bufmgr);
diff --git a/tests/i915/gem_tiled_pread_basic.c b/tests/i915/gem_tiled_pread_basic.c
index 7cb644104f..f8f73c03a2 100644
--- a/tests/i915/gem_tiled_pread_basic.c
+++ b/tests/i915/gem_tiled_pread_basic.c
@@ -127,6 +127,7 @@ igt_simple_main
 	igt_require(gem_available_fences(fd) > 0);
 	handle = create_bo(fd);
 	igt_require(gem_get_tiling(fd, handle, &tiling, &swizzle));
+	gem_require_pread_pwrite(fd);
 
 	devid = intel_get_drm_devid(fd);
 
diff --git a/tests/i915/gem_tiled_pread_pwrite.c b/tests/i915/gem_tiled_pread_pwrite.c
index f58048faa1..28490840fd 100644
--- a/tests/i915/gem_tiled_pread_pwrite.c
+++ b/tests/i915/gem_tiled_pread_pwrite.c
@@ -114,6 +114,7 @@ igt_simple_main
 	
 	fd = drm_open_driver(DRIVER_INTEL);
 	igt_require(gem_available_fences(fd) > 0);
+	gem_require_pread_pwrite(fd);
 
 	count = gem_available_fences(fd) + 1;
 	intel_require_memory(2 * count, sizeof(linear), CHECK_RAM);
diff --git a/tests/i915/gem_userptr_blits.c b/tests/i915/gem_userptr_blits.c
index 268423dcd1..0ccfdbd9cc 100644
--- a/tests/i915/gem_userptr_blits.c
+++ b/tests/i915/gem_userptr_blits.c
@@ -890,6 +890,7 @@ static int test_forbidden_ops(int fd)
 	uint32_t handle;
 	void *ptr;
 
+	gem_require_pread_pwrite(fd);
 	igt_assert(posix_memalign(&ptr, PAGE_SIZE, PAGE_SIZE) == 0);
 	gem_userptr(fd, ptr, PAGE_SIZE, 0, userptr_flags, &handle);
 
@@ -1416,6 +1417,7 @@ static void test_readonly_pwrite(int i915)
 	 */
 
 	igt_require(igt_setup_clflush());
+	gem_require_pread_pwrite(i915);
 
 	sz = 16 << 12;
 	pages = mmap(NULL, sz, PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
diff --git a/tests/i915/gen9_exec_parse.c b/tests/i915/gen9_exec_parse.c
index 8cd82f5688..eddc0f871f 100644
--- a/tests/i915/gen9_exec_parse.c
+++ b/tests/i915/gen9_exec_parse.c
@@ -1029,8 +1029,10 @@ igt_main
 			   -EINVAL);
 	}
 
-	igt_subtest("batch-invalid-length")
+	igt_subtest("batch-invalid-length") {
+		gem_require_pread_pwrite(i915);
 		test_invalid_length(i915, handle);
+	}
 
 	igt_subtest("basic-rejected")
 		test_rejected(i915, handle, false);
-- 
2.26.2.593.gb994622632

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [igt-dev] [PATCH i-g-t] lib/ioctl_wrappers: Keep IGT working without pread/pwrite ioctls
  2020-09-06 23:43 Ashutosh Dixit
@ 2020-09-09  7:03 ` Zbigniew Kempczyński
  0 siblings, 0 replies; 17+ messages in thread
From: Zbigniew Kempczyński @ 2020-09-09  7:03 UTC (permalink / raw)
  To: Ashutosh Dixit; +Cc: igt-dev

On Sun, Sep 06, 2020 at 07:43:40PM -0400, Ashutosh Dixit wrote:
> The general direction at this time is to phase out pread/write ioctls
> and not support them in future products. This means IGT must handle
> the absence of these ioctls. This patch does this by modifying
> gem_read() and gem_write() to do the read/write using the pread/pwrite
> ioctls first but when these ioctls are unavailable fall back to doing
> the read/write using a combination of mmap and memcpy.
> 
> Callers who must absolutely use the pread/pwrite ioctls (such as tests
> which test these ioctls or must otherwise only use the pread/pwrite
> ioctls) must use gem_require_pread_pwrite() to skip when these ioctls
> are not available.
> 
> v1: Removed __gem_pread, gem_pread, __gem_pwrite and gem_pwrite
>     introduced previously since they don't appear necessary
> v2: Fix CI failures in gem_advise and gen9_exec_parse by introducing
>     gem_require_pread_pwrite
> v3: Skip mmap for 0 length read/write's
> 
> Signed-off-by: Ashutosh Dixit <ashutosh.dixit@intel.com>

Looks good IMO. As function names are gem_read/gem_write fallback 
from pread/pwrite to mmap on newer platforms is good idea.

Reviewed-by: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com>

> ---
>  lib/ioctl_wrappers.c                        | 139 +++++++++++++++++++-
>  lib/ioctl_wrappers.h                        |   3 +
>  tests/i915/gem_madvise.c                    |   2 +
>  tests/i915/gem_partial_pwrite_pread.c       |   1 +
>  tests/i915/gem_pread.c                      |   1 +
>  tests/i915/gem_pread_after_blit.c           |   1 +
>  tests/i915/gem_pwrite.c                     |   1 +
>  tests/i915/gem_pwrite_snooped.c             |   1 +
>  tests/i915/gem_readwrite.c                  |   1 +
>  tests/i915/gem_set_tiling_vs_pwrite.c       |   1 +
>  tests/i915/gem_tiled_partial_pwrite_pread.c |   1 +
>  tests/i915/gem_tiled_pread_basic.c          |   1 +
>  tests/i915/gem_tiled_pread_pwrite.c         |   1 +
>  tests/i915/gem_userptr_blits.c              |   2 +
>  tests/i915/gen9_exec_parse.c                |   4 +-
>  15 files changed, 153 insertions(+), 7 deletions(-)
> 
> diff --git a/lib/ioctl_wrappers.c b/lib/ioctl_wrappers.c
> index 3781286d8..12451d1d5 100644
> --- a/lib/ioctl_wrappers.c
> +++ b/lib/ioctl_wrappers.c
> @@ -55,6 +55,7 @@
>  #include "igt_debugfs.h"
>  #include "igt_sysfs.h"
>  #include "config.h"
> +#include "i915/gem_mman.h"
>  
>  #ifdef HAVE_VALGRIND
>  #include <valgrind/valgrind.h>
> @@ -323,6 +324,74 @@ void gem_close(int fd, uint32_t handle)
>  	do_ioctl(fd, DRM_IOCTL_GEM_CLOSE, &close_bo);
>  }
>  
> +static bool is_cache_coherent(int fd, uint32_t handle)
> +{
> +	return gem_get_caching(fd, handle) != I915_CACHING_NONE;
> +}
> +
> +static void mmap_write(int fd, uint32_t handle, uint64_t offset,
> +		       const void *buf, uint64_t length)
> +{
> +	void *map = NULL;
> +
> +	if (!length)
> +		return;
> +
> +	if (is_cache_coherent(fd, handle)) {
> +		/* offset arg for mmap functions must be 0 */
> +		map = __gem_mmap__cpu_coherent(fd, handle, 0, offset + length,
> +					       PROT_READ | PROT_WRITE);
> +		if (map)
> +			gem_set_domain(fd, handle,
> +				       I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
> +	}
> +
> +	if (!map) {
> +		map = __gem_mmap_offset__wc(fd, handle, 0, offset + length,
> +					    PROT_READ | PROT_WRITE);
> +		if (!map)
> +			map = gem_mmap__wc(fd, handle, 0, offset + length,
> +					   PROT_READ | PROT_WRITE);
> +		if (map)
> +			gem_set_domain(fd, handle,
> +				       I915_GEM_DOMAIN_WC, I915_GEM_DOMAIN_WC);
> +	}
> +
> +	igt_assert(map);
> +	memcpy(map + offset, buf, length);
> +	munmap(map, offset + length);
> +}
> +
> +static void mmap_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t length)
> +{
> +	void *map = NULL;
> +
> +	if (!length)
> +		return;
> +
> +	if (gem_has_llc(fd) || is_cache_coherent(fd, handle)) {
> +		/* offset arg for mmap functions must be 0 */
> +		map = __gem_mmap__cpu_coherent(fd, handle, 0,
> +					       offset + length, PROT_READ);
> +		if (map)
> +			gem_set_domain(fd, handle, I915_GEM_DOMAIN_CPU, 0);
> +	}
> +
> +	if (!map) {
> +		map = __gem_mmap_offset__wc(fd, handle, 0, offset + length,
> +					    PROT_READ);
> +		if (!map)
> +			map = gem_mmap__wc(fd, handle, 0, offset + length,
> +					   PROT_READ);
> +		if (map)
> +			gem_set_domain(fd, handle, I915_GEM_DOMAIN_WC, 0);
> +	}
> +
> +	igt_assert(map);
> +	memcpy(buf, map + offset, length);
> +	munmap(map, offset + length);
> +}
> +
>  int __gem_write(int fd, uint32_t handle, uint64_t offset, const void *buf, uint64_t length)
>  {
>  	struct drm_i915_gem_pwrite gem_pwrite;
> @@ -348,12 +417,18 @@ int __gem_write(int fd, uint32_t handle, uint64_t offset, const void *buf, uint6
>   * @buf: pointer to the data to write into the buffer
>   * @length: size of the subrange
>   *
> - * This wraps the PWRITE ioctl, which is to upload a linear data to a subrange
> - * of a gem buffer object.
> + * Method to write to a gem object. Uses the PWRITE ioctl when it is
> + * available, else it uses mmap + memcpy to upload linear data to a
> + * subrange of a gem buffer object.
>   */
>  void gem_write(int fd, uint32_t handle, uint64_t offset, const void *buf, uint64_t length)
>  {
> -	igt_assert_eq(__gem_write(fd, handle, offset, buf, length), 0);
> +	int ret = __gem_write(fd, handle, offset, buf, length);
> +
> +	igt_assert(ret == 0 || ret == EOPNOTSUPP);
> +
> +	if (ret == EOPNOTSUPP)
> +		mmap_write(fd, handle, offset, buf, length);
>  }
>  
>  int __gem_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t length)
> @@ -380,12 +455,64 @@ int __gem_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t len
>   * @buf: pointer to the data to read into
>   * @length: size of the subrange
>   *
> - * This wraps the PREAD ioctl, which is to download a linear data to a subrange
> - * of a gem buffer object.
> + * Method to read from a gem object. Uses the PREAD ioctl when it is
> + * available, else it uses mmap + memcpy to download linear data from a
> + * subrange of a gem buffer object.
>   */
>  void gem_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t length)
>  {
> -	igt_assert_eq(__gem_read(fd, handle, offset, buf, length), 0);
> +	int ret = __gem_read(fd, handle, offset, buf, length);
> +
> +	igt_assert(ret == 0 || ret == EOPNOTSUPP);
> +
> +	if (ret == EOPNOTSUPP)
> +		mmap_read(fd, handle, offset, buf, length);
> +}
> +
> +/**
> + * gem_has_pwrite
> + * @fd: open i915 drm file descriptor
> + *
> + * Feature test macro to query whether pwrite ioctl is supported
> + */
> +bool gem_has_pwrite(int fd)
> +{
> +	uint32_t handle = gem_create(fd, 4096);
> +	int buf, ret;
> +
> +	ret = __gem_write(fd, handle, 0, &buf, sizeof(buf));
> +	gem_close(fd, handle);
> +
> +	return ret != EOPNOTSUPP;
> +}
> +
> +/**
> + * gem_has_pread
> + * @fd: open i915 drm file descriptor
> + *
> + * Feature test macro to query whether pread ioctl is supported
> + */
> +bool gem_has_pread(int fd)
> +{
> +	uint32_t handle = gem_create(fd, 4096);
> +	int buf, ret;
> +
> +	ret = __gem_read(fd, handle, 0, &buf, sizeof(buf));
> +	gem_close(fd, handle);
> +
> +	return ret != EOPNOTSUPP;
> +}
> +
> +/**
> + * gem_require_pread_pwrite
> + * @fd: open i915 drm file descriptor
> + *
> + * Feature test macro to query whether pread/pwrite ioctls are supported
> + * and skip if they are not
> + */
> +void gem_require_pread_pwrite(int fd)
> +{
> +	igt_require(gem_has_pread(fd) && gem_has_pwrite(fd));
>  }
>  
>  int __gem_set_domain(int fd, uint32_t handle, uint32_t read, uint32_t write)
> diff --git a/lib/ioctl_wrappers.h b/lib/ioctl_wrappers.h
> index 870ac8b7b..6ba551a71 100644
> --- a/lib/ioctl_wrappers.h
> +++ b/lib/ioctl_wrappers.h
> @@ -71,6 +71,9 @@ int __gem_write(int fd, uint32_t handle, uint64_t offset, const void *buf, uint6
>  void gem_write(int fd, uint32_t handle, uint64_t offset,  const void *buf, uint64_t length);
>  int __gem_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t length);
>  void gem_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t length);
> +bool gem_has_pwrite(int fd);
> +bool gem_has_pread(int fd);
> +void gem_require_pread_pwrite(int fd);
>  int __gem_set_domain(int fd, uint32_t handle, uint32_t read, uint32_t write);
>  void gem_set_domain(int fd, uint32_t handle, uint32_t read, uint32_t write);
>  int gem_wait(int fd, uint32_t handle, int64_t *timeout_ns);
> diff --git a/tests/i915/gem_madvise.c b/tests/i915/gem_madvise.c
> index 54c9befff..92e1c5192 100644
> --- a/tests/i915/gem_madvise.c
> +++ b/tests/i915/gem_madvise.c
> @@ -154,6 +154,7 @@ dontneed_before_pwrite(void)
>  	uint32_t bbe = MI_BATCH_BUFFER_END;
>  	uint32_t handle;
>  
> +	gem_require_pread_pwrite(fd);
>  	handle = gem_create(fd, OBJECT_SIZE);
>  	gem_madvise(fd, handle, I915_MADV_DONTNEED);
>  
> @@ -170,6 +171,7 @@ dontneed_before_exec(void)
>  	struct drm_i915_gem_exec_object2 exec;
>  	uint32_t buf[] = { MI_BATCH_BUFFER_END, 0 };
>  
> +	gem_require_pread_pwrite(fd);
>  	memset(&execbuf, 0, sizeof(execbuf));
>  	memset(&exec, 0, sizeof(exec));
>  
> diff --git a/tests/i915/gem_partial_pwrite_pread.c b/tests/i915/gem_partial_pwrite_pread.c
> index b4bae9b6d..136a53558 100644
> --- a/tests/i915/gem_partial_pwrite_pread.c
> +++ b/tests/i915/gem_partial_pwrite_pread.c
> @@ -284,6 +284,7 @@ igt_main
>  		data.drm_fd = drm_open_driver(DRIVER_INTEL);
>  		igt_require_gem(data.drm_fd);
>  		gem_require_blitter(data.drm_fd);
> +		gem_require_pread_pwrite(data.drm_fd);
>  
>  		data.devid = intel_get_drm_devid(data.drm_fd);
>  		data.bops = buf_ops_create(data.drm_fd);
> diff --git a/tests/i915/gem_pread.c b/tests/i915/gem_pread.c
> index 6d12b8e9f..db1eacedc 100644
> --- a/tests/i915/gem_pread.c
> +++ b/tests/i915/gem_pread.c
> @@ -149,6 +149,7 @@ igt_main_args("s:", NULL, help_str, opt_handler, NULL)
>  
>  	igt_fixture {
>  		fd = drm_open_driver(DRIVER_INTEL);
> +		gem_require_pread_pwrite(fd);
>  
>  		dst = gem_create(fd, object_size);
>  		src = malloc(object_size);
> diff --git a/tests/i915/gem_pread_after_blit.c b/tests/i915/gem_pread_after_blit.c
> index 81454c930..5c99d0887 100644
> --- a/tests/i915/gem_pread_after_blit.c
> +++ b/tests/i915/gem_pread_after_blit.c
> @@ -212,6 +212,7 @@ igt_main
>  	igt_fixture {
>  		fd = drm_open_driver(DRIVER_INTEL);
>  		igt_require_gem(fd);
> +		gem_require_pread_pwrite(fd);
>  
>  		bufmgr = drm_intel_bufmgr_gem_init(fd, 4096);
>  		drm_intel_bufmgr_gem_enable_reuse(bufmgr);
> diff --git a/tests/i915/gem_pwrite.c b/tests/i915/gem_pwrite.c
> index e491263fd..eea51f978 100644
> --- a/tests/i915/gem_pwrite.c
> +++ b/tests/i915/gem_pwrite.c
> @@ -317,6 +317,7 @@ igt_main_args("s:", NULL, help_str, opt_handler, NULL)
>  
>  	igt_fixture {
>  		fd = drm_open_driver(DRIVER_INTEL);
> +		gem_require_pread_pwrite(fd);
>  
>  		dst = gem_create(fd, object_size);
>  		src = malloc(object_size);
> diff --git a/tests/i915/gem_pwrite_snooped.c b/tests/i915/gem_pwrite_snooped.c
> index 4a3395241..a2eca6afc 100644
> --- a/tests/i915/gem_pwrite_snooped.c
> +++ b/tests/i915/gem_pwrite_snooped.c
> @@ -132,6 +132,7 @@ igt_simple_main
>  	fd = drm_open_driver(DRIVER_INTEL);
>  	igt_require_gem(fd);
>  	gem_require_blitter(fd);
> +	gem_require_pread_pwrite(fd);
>  
>  	devid = intel_get_drm_devid(fd);
>  	bufmgr = drm_intel_bufmgr_gem_init(fd, 4096);
> diff --git a/tests/i915/gem_readwrite.c b/tests/i915/gem_readwrite.c
> index 6b2977c1c..ca31741c6 100644
> --- a/tests/i915/gem_readwrite.c
> +++ b/tests/i915/gem_readwrite.c
> @@ -83,6 +83,7 @@ igt_main
>  
>  	igt_fixture {
>  		fd = drm_open_driver(DRIVER_INTEL);
> +		gem_require_pread_pwrite(fd);
>  
>  		handle = gem_create(fd, OBJECT_SIZE);
>  	}
> diff --git a/tests/i915/gem_set_tiling_vs_pwrite.c b/tests/i915/gem_set_tiling_vs_pwrite.c
> index 302ea24b6..8f38c9b9b 100644
> --- a/tests/i915/gem_set_tiling_vs_pwrite.c
> +++ b/tests/i915/gem_set_tiling_vs_pwrite.c
> @@ -55,6 +55,7 @@ igt_simple_main
>  
>  	fd = drm_open_driver(DRIVER_INTEL);
>  	igt_require(gem_available_fences(fd) > 0);
> +	gem_require_pread_pwrite(fd);
>  
>  	for (int i = 0; i < OBJECT_SIZE/4; i++)
>  		data[i] = i;
> diff --git a/tests/i915/gem_tiled_partial_pwrite_pread.c b/tests/i915/gem_tiled_partial_pwrite_pread.c
> index 7de5358b2..0c4545990 100644
> --- a/tests/i915/gem_tiled_partial_pwrite_pread.c
> +++ b/tests/i915/gem_tiled_partial_pwrite_pread.c
> @@ -270,6 +270,7 @@ igt_main
>  		igt_require_gem(fd);
>  		gem_require_mappable_ggtt(fd);
>  		gem_require_blitter(fd);
> +		gem_require_pread_pwrite(fd);
>  
>  		bufmgr = drm_intel_bufmgr_gem_init(fd, 4096);
>  		//drm_intel_bufmgr_gem_enable_reuse(bufmgr);
> diff --git a/tests/i915/gem_tiled_pread_basic.c b/tests/i915/gem_tiled_pread_basic.c
> index 7cb644104..f8f73c03a 100644
> --- a/tests/i915/gem_tiled_pread_basic.c
> +++ b/tests/i915/gem_tiled_pread_basic.c
> @@ -127,6 +127,7 @@ igt_simple_main
>  	igt_require(gem_available_fences(fd) > 0);
>  	handle = create_bo(fd);
>  	igt_require(gem_get_tiling(fd, handle, &tiling, &swizzle));
> +	gem_require_pread_pwrite(fd);
>  
>  	devid = intel_get_drm_devid(fd);
>  
> diff --git a/tests/i915/gem_tiled_pread_pwrite.c b/tests/i915/gem_tiled_pread_pwrite.c
> index f58048faa..28490840f 100644
> --- a/tests/i915/gem_tiled_pread_pwrite.c
> +++ b/tests/i915/gem_tiled_pread_pwrite.c
> @@ -114,6 +114,7 @@ igt_simple_main
>  	
>  	fd = drm_open_driver(DRIVER_INTEL);
>  	igt_require(gem_available_fences(fd) > 0);
> +	gem_require_pread_pwrite(fd);
>  
>  	count = gem_available_fences(fd) + 1;
>  	intel_require_memory(2 * count, sizeof(linear), CHECK_RAM);
> diff --git a/tests/i915/gem_userptr_blits.c b/tests/i915/gem_userptr_blits.c
> index 268423dcd..0ccfdbd9c 100644
> --- a/tests/i915/gem_userptr_blits.c
> +++ b/tests/i915/gem_userptr_blits.c
> @@ -890,6 +890,7 @@ static int test_forbidden_ops(int fd)
>  	uint32_t handle;
>  	void *ptr;
>  
> +	gem_require_pread_pwrite(fd);
>  	igt_assert(posix_memalign(&ptr, PAGE_SIZE, PAGE_SIZE) == 0);
>  	gem_userptr(fd, ptr, PAGE_SIZE, 0, userptr_flags, &handle);
>  
> @@ -1416,6 +1417,7 @@ static void test_readonly_pwrite(int i915)
>  	 */
>  
>  	igt_require(igt_setup_clflush());
> +	gem_require_pread_pwrite(i915);
>  
>  	sz = 16 << 12;
>  	pages = mmap(NULL, sz, PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
> diff --git a/tests/i915/gen9_exec_parse.c b/tests/i915/gen9_exec_parse.c
> index 8cd82f568..eddc0f871 100644
> --- a/tests/i915/gen9_exec_parse.c
> +++ b/tests/i915/gen9_exec_parse.c
> @@ -1029,8 +1029,10 @@ igt_main
>  			   -EINVAL);
>  	}
>  
> -	igt_subtest("batch-invalid-length")
> +	igt_subtest("batch-invalid-length") {
> +		gem_require_pread_pwrite(i915);
>  		test_invalid_length(i915, handle);
> +	}
>  
>  	igt_subtest("basic-rejected")
>  		test_rejected(i915, handle, false);
> -- 
> 2.27.0.112.g101b3204f3
> 
> _______________________________________________
> igt-dev mailing list
> igt-dev@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/igt-dev
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [igt-dev] [PATCH i-g-t] lib/ioctl_wrappers: Keep IGT working without pread/pwrite ioctls
@ 2020-09-06 23:43 Ashutosh Dixit
  2020-09-09  7:03 ` Zbigniew Kempczyński
  0 siblings, 1 reply; 17+ messages in thread
From: Ashutosh Dixit @ 2020-09-06 23:43 UTC (permalink / raw)
  To: igt-dev

The general direction at this time is to phase out pread/write ioctls
and not support them in future products. This means IGT must handle
the absence of these ioctls. This patch does this by modifying
gem_read() and gem_write() to do the read/write using the pread/pwrite
ioctls first but when these ioctls are unavailable fall back to doing
the read/write using a combination of mmap and memcpy.

Callers who must absolutely use the pread/pwrite ioctls (such as tests
which test these ioctls or must otherwise only use the pread/pwrite
ioctls) must use gem_require_pread_pwrite() to skip when these ioctls
are not available.

v1: Removed __gem_pread, gem_pread, __gem_pwrite and gem_pwrite
    introduced previously since they don't appear necessary
v2: Fix CI failures in gem_advise and gen9_exec_parse by introducing
    gem_require_pread_pwrite
v3: Skip mmap for 0 length read/write's

Signed-off-by: Ashutosh Dixit <ashutosh.dixit@intel.com>
---
 lib/ioctl_wrappers.c                        | 139 +++++++++++++++++++-
 lib/ioctl_wrappers.h                        |   3 +
 tests/i915/gem_madvise.c                    |   2 +
 tests/i915/gem_partial_pwrite_pread.c       |   1 +
 tests/i915/gem_pread.c                      |   1 +
 tests/i915/gem_pread_after_blit.c           |   1 +
 tests/i915/gem_pwrite.c                     |   1 +
 tests/i915/gem_pwrite_snooped.c             |   1 +
 tests/i915/gem_readwrite.c                  |   1 +
 tests/i915/gem_set_tiling_vs_pwrite.c       |   1 +
 tests/i915/gem_tiled_partial_pwrite_pread.c |   1 +
 tests/i915/gem_tiled_pread_basic.c          |   1 +
 tests/i915/gem_tiled_pread_pwrite.c         |   1 +
 tests/i915/gem_userptr_blits.c              |   2 +
 tests/i915/gen9_exec_parse.c                |   4 +-
 15 files changed, 153 insertions(+), 7 deletions(-)

diff --git a/lib/ioctl_wrappers.c b/lib/ioctl_wrappers.c
index 3781286d8..12451d1d5 100644
--- a/lib/ioctl_wrappers.c
+++ b/lib/ioctl_wrappers.c
@@ -55,6 +55,7 @@
 #include "igt_debugfs.h"
 #include "igt_sysfs.h"
 #include "config.h"
+#include "i915/gem_mman.h"
 
 #ifdef HAVE_VALGRIND
 #include <valgrind/valgrind.h>
@@ -323,6 +324,74 @@ void gem_close(int fd, uint32_t handle)
 	do_ioctl(fd, DRM_IOCTL_GEM_CLOSE, &close_bo);
 }
 
+static bool is_cache_coherent(int fd, uint32_t handle)
+{
+	return gem_get_caching(fd, handle) != I915_CACHING_NONE;
+}
+
+static void mmap_write(int fd, uint32_t handle, uint64_t offset,
+		       const void *buf, uint64_t length)
+{
+	void *map = NULL;
+
+	if (!length)
+		return;
+
+	if (is_cache_coherent(fd, handle)) {
+		/* offset arg for mmap functions must be 0 */
+		map = __gem_mmap__cpu_coherent(fd, handle, 0, offset + length,
+					       PROT_READ | PROT_WRITE);
+		if (map)
+			gem_set_domain(fd, handle,
+				       I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
+	}
+
+	if (!map) {
+		map = __gem_mmap_offset__wc(fd, handle, 0, offset + length,
+					    PROT_READ | PROT_WRITE);
+		if (!map)
+			map = gem_mmap__wc(fd, handle, 0, offset + length,
+					   PROT_READ | PROT_WRITE);
+		if (map)
+			gem_set_domain(fd, handle,
+				       I915_GEM_DOMAIN_WC, I915_GEM_DOMAIN_WC);
+	}
+
+	igt_assert(map);
+	memcpy(map + offset, buf, length);
+	munmap(map, offset + length);
+}
+
+static void mmap_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t length)
+{
+	void *map = NULL;
+
+	if (!length)
+		return;
+
+	if (gem_has_llc(fd) || is_cache_coherent(fd, handle)) {
+		/* offset arg for mmap functions must be 0 */
+		map = __gem_mmap__cpu_coherent(fd, handle, 0,
+					       offset + length, PROT_READ);
+		if (map)
+			gem_set_domain(fd, handle, I915_GEM_DOMAIN_CPU, 0);
+	}
+
+	if (!map) {
+		map = __gem_mmap_offset__wc(fd, handle, 0, offset + length,
+					    PROT_READ);
+		if (!map)
+			map = gem_mmap__wc(fd, handle, 0, offset + length,
+					   PROT_READ);
+		if (map)
+			gem_set_domain(fd, handle, I915_GEM_DOMAIN_WC, 0);
+	}
+
+	igt_assert(map);
+	memcpy(buf, map + offset, length);
+	munmap(map, offset + length);
+}
+
 int __gem_write(int fd, uint32_t handle, uint64_t offset, const void *buf, uint64_t length)
 {
 	struct drm_i915_gem_pwrite gem_pwrite;
@@ -348,12 +417,18 @@ int __gem_write(int fd, uint32_t handle, uint64_t offset, const void *buf, uint6
  * @buf: pointer to the data to write into the buffer
  * @length: size of the subrange
  *
- * This wraps the PWRITE ioctl, which is to upload a linear data to a subrange
- * of a gem buffer object.
+ * Method to write to a gem object. Uses the PWRITE ioctl when it is
+ * available, else it uses mmap + memcpy to upload linear data to a
+ * subrange of a gem buffer object.
  */
 void gem_write(int fd, uint32_t handle, uint64_t offset, const void *buf, uint64_t length)
 {
-	igt_assert_eq(__gem_write(fd, handle, offset, buf, length), 0);
+	int ret = __gem_write(fd, handle, offset, buf, length);
+
+	igt_assert(ret == 0 || ret == EOPNOTSUPP);
+
+	if (ret == EOPNOTSUPP)
+		mmap_write(fd, handle, offset, buf, length);
 }
 
 int __gem_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t length)
@@ -380,12 +455,64 @@ int __gem_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t len
  * @buf: pointer to the data to read into
  * @length: size of the subrange
  *
- * This wraps the PREAD ioctl, which is to download a linear data to a subrange
- * of a gem buffer object.
+ * Method to read from a gem object. Uses the PREAD ioctl when it is
+ * available, else it uses mmap + memcpy to download linear data from a
+ * subrange of a gem buffer object.
  */
 void gem_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t length)
 {
-	igt_assert_eq(__gem_read(fd, handle, offset, buf, length), 0);
+	int ret = __gem_read(fd, handle, offset, buf, length);
+
+	igt_assert(ret == 0 || ret == EOPNOTSUPP);
+
+	if (ret == EOPNOTSUPP)
+		mmap_read(fd, handle, offset, buf, length);
+}
+
+/**
+ * gem_has_pwrite
+ * @fd: open i915 drm file descriptor
+ *
+ * Feature test macro to query whether pwrite ioctl is supported
+ */
+bool gem_has_pwrite(int fd)
+{
+	uint32_t handle = gem_create(fd, 4096);
+	int buf, ret;
+
+	ret = __gem_write(fd, handle, 0, &buf, sizeof(buf));
+	gem_close(fd, handle);
+
+	return ret != EOPNOTSUPP;
+}
+
+/**
+ * gem_has_pread
+ * @fd: open i915 drm file descriptor
+ *
+ * Feature test macro to query whether pread ioctl is supported
+ */
+bool gem_has_pread(int fd)
+{
+	uint32_t handle = gem_create(fd, 4096);
+	int buf, ret;
+
+	ret = __gem_read(fd, handle, 0, &buf, sizeof(buf));
+	gem_close(fd, handle);
+
+	return ret != EOPNOTSUPP;
+}
+
+/**
+ * gem_require_pread_pwrite
+ * @fd: open i915 drm file descriptor
+ *
+ * Feature test macro to query whether pread/pwrite ioctls are supported
+ * and skip if they are not
+ */
+void gem_require_pread_pwrite(int fd)
+{
+	igt_require(gem_has_pread(fd) && gem_has_pwrite(fd));
 }
 
 int __gem_set_domain(int fd, uint32_t handle, uint32_t read, uint32_t write)
diff --git a/lib/ioctl_wrappers.h b/lib/ioctl_wrappers.h
index 870ac8b7b..6ba551a71 100644
--- a/lib/ioctl_wrappers.h
+++ b/lib/ioctl_wrappers.h
@@ -71,6 +71,9 @@ int __gem_write(int fd, uint32_t handle, uint64_t offset, const void *buf, uint6
 void gem_write(int fd, uint32_t handle, uint64_t offset,  const void *buf, uint64_t length);
 int __gem_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t length);
 void gem_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t length);
+bool gem_has_pwrite(int fd);
+bool gem_has_pread(int fd);
+void gem_require_pread_pwrite(int fd);
 int __gem_set_domain(int fd, uint32_t handle, uint32_t read, uint32_t write);
 void gem_set_domain(int fd, uint32_t handle, uint32_t read, uint32_t write);
 int gem_wait(int fd, uint32_t handle, int64_t *timeout_ns);
diff --git a/tests/i915/gem_madvise.c b/tests/i915/gem_madvise.c
index 54c9befff..92e1c5192 100644
--- a/tests/i915/gem_madvise.c
+++ b/tests/i915/gem_madvise.c
@@ -154,6 +154,7 @@ dontneed_before_pwrite(void)
 	uint32_t bbe = MI_BATCH_BUFFER_END;
 	uint32_t handle;
 
+	gem_require_pread_pwrite(fd);
 	handle = gem_create(fd, OBJECT_SIZE);
 	gem_madvise(fd, handle, I915_MADV_DONTNEED);
 
@@ -170,6 +171,7 @@ dontneed_before_exec(void)
 	struct drm_i915_gem_exec_object2 exec;
 	uint32_t buf[] = { MI_BATCH_BUFFER_END, 0 };
 
+	gem_require_pread_pwrite(fd);
 	memset(&execbuf, 0, sizeof(execbuf));
 	memset(&exec, 0, sizeof(exec));
 
diff --git a/tests/i915/gem_partial_pwrite_pread.c b/tests/i915/gem_partial_pwrite_pread.c
index b4bae9b6d..136a53558 100644
--- a/tests/i915/gem_partial_pwrite_pread.c
+++ b/tests/i915/gem_partial_pwrite_pread.c
@@ -284,6 +284,7 @@ igt_main
 		data.drm_fd = drm_open_driver(DRIVER_INTEL);
 		igt_require_gem(data.drm_fd);
 		gem_require_blitter(data.drm_fd);
+		gem_require_pread_pwrite(data.drm_fd);
 
 		data.devid = intel_get_drm_devid(data.drm_fd);
 		data.bops = buf_ops_create(data.drm_fd);
diff --git a/tests/i915/gem_pread.c b/tests/i915/gem_pread.c
index 6d12b8e9f..db1eacedc 100644
--- a/tests/i915/gem_pread.c
+++ b/tests/i915/gem_pread.c
@@ -149,6 +149,7 @@ igt_main_args("s:", NULL, help_str, opt_handler, NULL)
 
 	igt_fixture {
 		fd = drm_open_driver(DRIVER_INTEL);
+		gem_require_pread_pwrite(fd);
 
 		dst = gem_create(fd, object_size);
 		src = malloc(object_size);
diff --git a/tests/i915/gem_pread_after_blit.c b/tests/i915/gem_pread_after_blit.c
index 81454c930..5c99d0887 100644
--- a/tests/i915/gem_pread_after_blit.c
+++ b/tests/i915/gem_pread_after_blit.c
@@ -212,6 +212,7 @@ igt_main
 	igt_fixture {
 		fd = drm_open_driver(DRIVER_INTEL);
 		igt_require_gem(fd);
+		gem_require_pread_pwrite(fd);
 
 		bufmgr = drm_intel_bufmgr_gem_init(fd, 4096);
 		drm_intel_bufmgr_gem_enable_reuse(bufmgr);
diff --git a/tests/i915/gem_pwrite.c b/tests/i915/gem_pwrite.c
index e491263fd..eea51f978 100644
--- a/tests/i915/gem_pwrite.c
+++ b/tests/i915/gem_pwrite.c
@@ -317,6 +317,7 @@ igt_main_args("s:", NULL, help_str, opt_handler, NULL)
 
 	igt_fixture {
 		fd = drm_open_driver(DRIVER_INTEL);
+		gem_require_pread_pwrite(fd);
 
 		dst = gem_create(fd, object_size);
 		src = malloc(object_size);
diff --git a/tests/i915/gem_pwrite_snooped.c b/tests/i915/gem_pwrite_snooped.c
index 4a3395241..a2eca6afc 100644
--- a/tests/i915/gem_pwrite_snooped.c
+++ b/tests/i915/gem_pwrite_snooped.c
@@ -132,6 +132,7 @@ igt_simple_main
 	fd = drm_open_driver(DRIVER_INTEL);
 	igt_require_gem(fd);
 	gem_require_blitter(fd);
+	gem_require_pread_pwrite(fd);
 
 	devid = intel_get_drm_devid(fd);
 	bufmgr = drm_intel_bufmgr_gem_init(fd, 4096);
diff --git a/tests/i915/gem_readwrite.c b/tests/i915/gem_readwrite.c
index 6b2977c1c..ca31741c6 100644
--- a/tests/i915/gem_readwrite.c
+++ b/tests/i915/gem_readwrite.c
@@ -83,6 +83,7 @@ igt_main
 
 	igt_fixture {
 		fd = drm_open_driver(DRIVER_INTEL);
+		gem_require_pread_pwrite(fd);
 
 		handle = gem_create(fd, OBJECT_SIZE);
 	}
diff --git a/tests/i915/gem_set_tiling_vs_pwrite.c b/tests/i915/gem_set_tiling_vs_pwrite.c
index 302ea24b6..8f38c9b9b 100644
--- a/tests/i915/gem_set_tiling_vs_pwrite.c
+++ b/tests/i915/gem_set_tiling_vs_pwrite.c
@@ -55,6 +55,7 @@ igt_simple_main
 
 	fd = drm_open_driver(DRIVER_INTEL);
 	igt_require(gem_available_fences(fd) > 0);
+	gem_require_pread_pwrite(fd);
 
 	for (int i = 0; i < OBJECT_SIZE/4; i++)
 		data[i] = i;
diff --git a/tests/i915/gem_tiled_partial_pwrite_pread.c b/tests/i915/gem_tiled_partial_pwrite_pread.c
index 7de5358b2..0c4545990 100644
--- a/tests/i915/gem_tiled_partial_pwrite_pread.c
+++ b/tests/i915/gem_tiled_partial_pwrite_pread.c
@@ -270,6 +270,7 @@ igt_main
 		igt_require_gem(fd);
 		gem_require_mappable_ggtt(fd);
 		gem_require_blitter(fd);
+		gem_require_pread_pwrite(fd);
 
 		bufmgr = drm_intel_bufmgr_gem_init(fd, 4096);
 		//drm_intel_bufmgr_gem_enable_reuse(bufmgr);
diff --git a/tests/i915/gem_tiled_pread_basic.c b/tests/i915/gem_tiled_pread_basic.c
index 7cb644104..f8f73c03a 100644
--- a/tests/i915/gem_tiled_pread_basic.c
+++ b/tests/i915/gem_tiled_pread_basic.c
@@ -127,6 +127,7 @@ igt_simple_main
 	igt_require(gem_available_fences(fd) > 0);
 	handle = create_bo(fd);
 	igt_require(gem_get_tiling(fd, handle, &tiling, &swizzle));
+	gem_require_pread_pwrite(fd);
 
 	devid = intel_get_drm_devid(fd);
 
diff --git a/tests/i915/gem_tiled_pread_pwrite.c b/tests/i915/gem_tiled_pread_pwrite.c
index f58048faa..28490840f 100644
--- a/tests/i915/gem_tiled_pread_pwrite.c
+++ b/tests/i915/gem_tiled_pread_pwrite.c
@@ -114,6 +114,7 @@ igt_simple_main
 	
 	fd = drm_open_driver(DRIVER_INTEL);
 	igt_require(gem_available_fences(fd) > 0);
+	gem_require_pread_pwrite(fd);
 
 	count = gem_available_fences(fd) + 1;
 	intel_require_memory(2 * count, sizeof(linear), CHECK_RAM);
diff --git a/tests/i915/gem_userptr_blits.c b/tests/i915/gem_userptr_blits.c
index 268423dcd..0ccfdbd9c 100644
--- a/tests/i915/gem_userptr_blits.c
+++ b/tests/i915/gem_userptr_blits.c
@@ -890,6 +890,7 @@ static int test_forbidden_ops(int fd)
 	uint32_t handle;
 	void *ptr;
 
+	gem_require_pread_pwrite(fd);
 	igt_assert(posix_memalign(&ptr, PAGE_SIZE, PAGE_SIZE) == 0);
 	gem_userptr(fd, ptr, PAGE_SIZE, 0, userptr_flags, &handle);
 
@@ -1416,6 +1417,7 @@ static void test_readonly_pwrite(int i915)
 	 */
 
 	igt_require(igt_setup_clflush());
+	gem_require_pread_pwrite(i915);
 
 	sz = 16 << 12;
 	pages = mmap(NULL, sz, PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
diff --git a/tests/i915/gen9_exec_parse.c b/tests/i915/gen9_exec_parse.c
index 8cd82f568..eddc0f871 100644
--- a/tests/i915/gen9_exec_parse.c
+++ b/tests/i915/gen9_exec_parse.c
@@ -1029,8 +1029,10 @@ igt_main
 			   -EINVAL);
 	}
 
-	igt_subtest("batch-invalid-length")
+	igt_subtest("batch-invalid-length") {
+		gem_require_pread_pwrite(i915);
 		test_invalid_length(i915, handle);
+	}
 
 	igt_subtest("basic-rejected")
 		test_rejected(i915, handle, false);
-- 
2.27.0.112.g101b3204f3

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [igt-dev] [PATCH i-g-t] lib/ioctl_wrappers: Keep IGT working without pread/pwrite ioctls
@ 2020-09-06 17:49 Ashutosh Dixit
  0 siblings, 0 replies; 17+ messages in thread
From: Ashutosh Dixit @ 2020-09-06 17:49 UTC (permalink / raw)
  To: igt-dev

The general direction at this time is to phase out pread/write ioctls
and not support them in future products. This means IGT must handle
the absence of these ioctls. This patch does this by modifying
gem_read() and gem_write() to do the read/write using the pread/pwrite
ioctls first but when these ioctls are unavailable fall back to doing
the read/write using a combination of mmap and memcpy.

Callers who must absolutely use the pread/pwrite ioctls (such as tests
which test these ioctls or must otherwise only use the pread/pwrite
ioctls) must use gem_require_pread_pwrite() to skip when these ioctls
are not available.

v2: Removed __gem_pread, gem_pread, __gem_pwrite and gem_pwrite
    introduced in v1 since they don't appear necessary
v3: Fix CI failures in gem_advise and gen9_exec_parse by introducing
    gem_require_pread_pwrite

Signed-off-by: Ashutosh Dixit <ashutosh.dixit@intel.com>
---
 lib/ioctl_wrappers.c                        | 133 +++++++++++++++++++-
 lib/ioctl_wrappers.h                        |   3 +
 tests/i915/gem_madvise.c                    |   2 +
 tests/i915/gem_partial_pwrite_pread.c       |   1 +
 tests/i915/gem_pread.c                      |   1 +
 tests/i915/gem_pread_after_blit.c           |   1 +
 tests/i915/gem_pwrite.c                     |   1 +
 tests/i915/gem_pwrite_snooped.c             |   1 +
 tests/i915/gem_readwrite.c                  |   1 +
 tests/i915/gem_set_tiling_vs_pwrite.c       |   1 +
 tests/i915/gem_tiled_partial_pwrite_pread.c |   1 +
 tests/i915/gem_tiled_pread_basic.c          |   1 +
 tests/i915/gem_tiled_pread_pwrite.c         |   1 +
 tests/i915/gem_userptr_blits.c              |   2 +
 tests/i915/gen9_exec_parse.c                |   5 +-
 15 files changed, 148 insertions(+), 7 deletions(-)

diff --git a/lib/ioctl_wrappers.c b/lib/ioctl_wrappers.c
index 3781286d8..ff483fbbc 100644
--- a/lib/ioctl_wrappers.c
+++ b/lib/ioctl_wrappers.c
@@ -55,6 +55,7 @@
 #include "igt_debugfs.h"
 #include "igt_sysfs.h"
 #include "config.h"
+#include "i915/gem_mman.h"
 
 #ifdef HAVE_VALGRIND
 #include <valgrind/valgrind.h>
@@ -323,6 +324,68 @@ void gem_close(int fd, uint32_t handle)
 	do_ioctl(fd, DRM_IOCTL_GEM_CLOSE, &close_bo);
 }
 
+static bool is_cache_coherent(int fd, uint32_t handle)
+{
+	return gem_get_caching(fd, handle) != I915_CACHING_NONE;
+}
+
+static void mmap_write(int fd, uint32_t handle, uint64_t offset,
+		       const void *buf, uint64_t length)
+{
+	void *map = NULL;
+
+	if (is_cache_coherent(fd, handle)) {
+		/* offset arg for mmap functions must be 0 */
+		map = __gem_mmap__cpu_coherent(fd, handle, 0, offset + length,
+					       PROT_READ | PROT_WRITE);
+		if (map)
+			gem_set_domain(fd, handle,
+				       I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
+	}
+
+	if (!map) {
+		map = __gem_mmap_offset__wc(fd, handle, 0, offset + length,
+					    PROT_READ | PROT_WRITE);
+		if (!map)
+			map = gem_mmap__wc(fd, handle, 0, offset + length,
+					   PROT_READ | PROT_WRITE);
+		if (map)
+			gem_set_domain(fd, handle,
+				       I915_GEM_DOMAIN_WC, I915_GEM_DOMAIN_WC);
+	}
+
+	igt_assert(map);
+	memcpy(map + offset, buf, length);
+	munmap(map, offset + length);
+}
+
+static void mmap_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t length)
+{
+	void *map = NULL;
+
+	if (gem_has_llc(fd) || is_cache_coherent(fd, handle)) {
+		/* offset arg for mmap functions must be 0 */
+		map = __gem_mmap__cpu_coherent(fd, handle, 0,
+					       offset + length, PROT_READ);
+		if (map)
+			gem_set_domain(fd, handle, I915_GEM_DOMAIN_CPU, 0);
+	}
+
+	if (!map) {
+		map = __gem_mmap_offset__wc(fd, handle, 0, offset + length,
+					    PROT_READ);
+		if (!map)
+			map = gem_mmap__wc(fd, handle, 0, offset + length,
+					   PROT_READ);
+		if (map)
+			gem_set_domain(fd, handle, I915_GEM_DOMAIN_WC, 0);
+	}
+
+	igt_assert(map);
+	memcpy(buf, map + offset, length);
+	munmap(map, offset + length);
+}
+
 int __gem_write(int fd, uint32_t handle, uint64_t offset, const void *buf, uint64_t length)
 {
 	struct drm_i915_gem_pwrite gem_pwrite;
@@ -348,12 +411,18 @@ int __gem_write(int fd, uint32_t handle, uint64_t offset, const void *buf, uint6
  * @buf: pointer to the data to write into the buffer
  * @length: size of the subrange
  *
- * This wraps the PWRITE ioctl, which is to upload a linear data to a subrange
- * of a gem buffer object.
+ * Method to write to a gem object. Uses the PWRITE ioctl when it is
+ * available, else it uses mmap + memcpy to upload linear data to a
+ * subrange of a gem buffer object.
  */
 void gem_write(int fd, uint32_t handle, uint64_t offset, const void *buf, uint64_t length)
 {
-	igt_assert_eq(__gem_write(fd, handle, offset, buf, length), 0);
+	int ret = __gem_write(fd, handle, offset, buf, length);
+
+	igt_assert(ret == 0 || ret == EOPNOTSUPP);
+
+	if (ret == EOPNOTSUPP)
+		mmap_write(fd, handle, offset, buf, length);
 }
 
 int __gem_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t length)
@@ -380,12 +449,64 @@ int __gem_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t len
  * @buf: pointer to the data to read into
  * @length: size of the subrange
  *
- * This wraps the PREAD ioctl, which is to download a linear data to a subrange
- * of a gem buffer object.
+ * Method to read from a gem object. Uses the PREAD ioctl when it is
+ * available, else it uses mmap + memcpy to download linear data from a
+ * subrange of a gem buffer object.
  */
 void gem_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t length)
 {
-	igt_assert_eq(__gem_read(fd, handle, offset, buf, length), 0);
+	int ret = __gem_read(fd, handle, offset, buf, length);
+
+	igt_assert(ret == 0 || ret == EOPNOTSUPP);
+
+	if (ret == EOPNOTSUPP)
+		mmap_read(fd, handle, offset, buf, length);
+}
+
+/**
+ * gem_has_pwrite
+ * @fd: open i915 drm file descriptor
+ *
+ * Feature test macro to query whether pwrite ioctl is supported
+ */
+bool gem_has_pwrite(int fd)
+{
+	uint32_t handle = gem_create(fd, 4096);
+	int buf, ret;
+
+	ret = __gem_write(fd, handle, 0, &buf, sizeof(buf));
+	gem_close(fd, handle);
+
+	return ret != EOPNOTSUPP;
+}
+
+/**
+ * gem_has_pread
+ * @fd: open i915 drm file descriptor
+ *
+ * Feature test macro to query whether pread ioctl is supported
+ */
+bool gem_has_pread(int fd)
+{
+	uint32_t handle = gem_create(fd, 4096);
+	int buf, ret;
+
+	ret = __gem_read(fd, handle, 0, &buf, sizeof(buf));
+	gem_close(fd, handle);
+
+	return ret != EOPNOTSUPP;
+}
+
+/**
+ * gem_require_pread_pwrite
+ * @fd: open i915 drm file descriptor
+ *
+ * Feature test macro to query whether pread/pwrite ioctls are supported
+ * and skip if they are not
+ */
+void gem_require_pread_pwrite(int fd)
+{
+	igt_require(gem_has_pread(fd) && gem_has_pwrite(fd));
 }
 
 int __gem_set_domain(int fd, uint32_t handle, uint32_t read, uint32_t write)
diff --git a/lib/ioctl_wrappers.h b/lib/ioctl_wrappers.h
index 870ac8b7b..6ba551a71 100644
--- a/lib/ioctl_wrappers.h
+++ b/lib/ioctl_wrappers.h
@@ -71,6 +71,9 @@ int __gem_write(int fd, uint32_t handle, uint64_t offset, const void *buf, uint6
 void gem_write(int fd, uint32_t handle, uint64_t offset,  const void *buf, uint64_t length);
 int __gem_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t length);
 void gem_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t length);
+bool gem_has_pwrite(int fd);
+bool gem_has_pread(int fd);
+void gem_require_pread_pwrite(int fd);
 int __gem_set_domain(int fd, uint32_t handle, uint32_t read, uint32_t write);
 void gem_set_domain(int fd, uint32_t handle, uint32_t read, uint32_t write);
 int gem_wait(int fd, uint32_t handle, int64_t *timeout_ns);
diff --git a/tests/i915/gem_madvise.c b/tests/i915/gem_madvise.c
index 54c9befff..92e1c5192 100644
--- a/tests/i915/gem_madvise.c
+++ b/tests/i915/gem_madvise.c
@@ -154,6 +154,7 @@ dontneed_before_pwrite(void)
 	uint32_t bbe = MI_BATCH_BUFFER_END;
 	uint32_t handle;
 
+	gem_require_pread_pwrite(fd);
 	handle = gem_create(fd, OBJECT_SIZE);
 	gem_madvise(fd, handle, I915_MADV_DONTNEED);
 
@@ -170,6 +171,7 @@ dontneed_before_exec(void)
 	struct drm_i915_gem_exec_object2 exec;
 	uint32_t buf[] = { MI_BATCH_BUFFER_END, 0 };
 
+	gem_require_pread_pwrite(fd);
 	memset(&execbuf, 0, sizeof(execbuf));
 	memset(&exec, 0, sizeof(exec));
 
diff --git a/tests/i915/gem_partial_pwrite_pread.c b/tests/i915/gem_partial_pwrite_pread.c
index b4bae9b6d..136a53558 100644
--- a/tests/i915/gem_partial_pwrite_pread.c
+++ b/tests/i915/gem_partial_pwrite_pread.c
@@ -284,6 +284,7 @@ igt_main
 		data.drm_fd = drm_open_driver(DRIVER_INTEL);
 		igt_require_gem(data.drm_fd);
 		gem_require_blitter(data.drm_fd);
+		gem_require_pread_pwrite(data.drm_fd);
 
 		data.devid = intel_get_drm_devid(data.drm_fd);
 		data.bops = buf_ops_create(data.drm_fd);
diff --git a/tests/i915/gem_pread.c b/tests/i915/gem_pread.c
index 6d12b8e9f..db1eacedc 100644
--- a/tests/i915/gem_pread.c
+++ b/tests/i915/gem_pread.c
@@ -149,6 +149,7 @@ igt_main_args("s:", NULL, help_str, opt_handler, NULL)
 
 	igt_fixture {
 		fd = drm_open_driver(DRIVER_INTEL);
+		gem_require_pread_pwrite(fd);
 
 		dst = gem_create(fd, object_size);
 		src = malloc(object_size);
diff --git a/tests/i915/gem_pread_after_blit.c b/tests/i915/gem_pread_after_blit.c
index 81454c930..5c99d0887 100644
--- a/tests/i915/gem_pread_after_blit.c
+++ b/tests/i915/gem_pread_after_blit.c
@@ -212,6 +212,7 @@ igt_main
 	igt_fixture {
 		fd = drm_open_driver(DRIVER_INTEL);
 		igt_require_gem(fd);
+		gem_require_pread_pwrite(fd);
 
 		bufmgr = drm_intel_bufmgr_gem_init(fd, 4096);
 		drm_intel_bufmgr_gem_enable_reuse(bufmgr);
diff --git a/tests/i915/gem_pwrite.c b/tests/i915/gem_pwrite.c
index e491263fd..eea51f978 100644
--- a/tests/i915/gem_pwrite.c
+++ b/tests/i915/gem_pwrite.c
@@ -317,6 +317,7 @@ igt_main_args("s:", NULL, help_str, opt_handler, NULL)
 
 	igt_fixture {
 		fd = drm_open_driver(DRIVER_INTEL);
+		gem_require_pread_pwrite(fd);
 
 		dst = gem_create(fd, object_size);
 		src = malloc(object_size);
diff --git a/tests/i915/gem_pwrite_snooped.c b/tests/i915/gem_pwrite_snooped.c
index 4a3395241..a2eca6afc 100644
--- a/tests/i915/gem_pwrite_snooped.c
+++ b/tests/i915/gem_pwrite_snooped.c
@@ -132,6 +132,7 @@ igt_simple_main
 	fd = drm_open_driver(DRIVER_INTEL);
 	igt_require_gem(fd);
 	gem_require_blitter(fd);
+	gem_require_pread_pwrite(fd);
 
 	devid = intel_get_drm_devid(fd);
 	bufmgr = drm_intel_bufmgr_gem_init(fd, 4096);
diff --git a/tests/i915/gem_readwrite.c b/tests/i915/gem_readwrite.c
index 6b2977c1c..ca31741c6 100644
--- a/tests/i915/gem_readwrite.c
+++ b/tests/i915/gem_readwrite.c
@@ -83,6 +83,7 @@ igt_main
 
 	igt_fixture {
 		fd = drm_open_driver(DRIVER_INTEL);
+		gem_require_pread_pwrite(fd);
 
 		handle = gem_create(fd, OBJECT_SIZE);
 	}
diff --git a/tests/i915/gem_set_tiling_vs_pwrite.c b/tests/i915/gem_set_tiling_vs_pwrite.c
index 302ea24b6..8f38c9b9b 100644
--- a/tests/i915/gem_set_tiling_vs_pwrite.c
+++ b/tests/i915/gem_set_tiling_vs_pwrite.c
@@ -55,6 +55,7 @@ igt_simple_main
 
 	fd = drm_open_driver(DRIVER_INTEL);
 	igt_require(gem_available_fences(fd) > 0);
+	gem_require_pread_pwrite(fd);
 
 	for (int i = 0; i < OBJECT_SIZE/4; i++)
 		data[i] = i;
diff --git a/tests/i915/gem_tiled_partial_pwrite_pread.c b/tests/i915/gem_tiled_partial_pwrite_pread.c
index 7de5358b2..0c4545990 100644
--- a/tests/i915/gem_tiled_partial_pwrite_pread.c
+++ b/tests/i915/gem_tiled_partial_pwrite_pread.c
@@ -270,6 +270,7 @@ igt_main
 		igt_require_gem(fd);
 		gem_require_mappable_ggtt(fd);
 		gem_require_blitter(fd);
+		gem_require_pread_pwrite(fd);
 
 		bufmgr = drm_intel_bufmgr_gem_init(fd, 4096);
 		//drm_intel_bufmgr_gem_enable_reuse(bufmgr);
diff --git a/tests/i915/gem_tiled_pread_basic.c b/tests/i915/gem_tiled_pread_basic.c
index 7cb644104..f8f73c03a 100644
--- a/tests/i915/gem_tiled_pread_basic.c
+++ b/tests/i915/gem_tiled_pread_basic.c
@@ -127,6 +127,7 @@ igt_simple_main
 	igt_require(gem_available_fences(fd) > 0);
 	handle = create_bo(fd);
 	igt_require(gem_get_tiling(fd, handle, &tiling, &swizzle));
+	gem_require_pread_pwrite(fd);
 
 	devid = intel_get_drm_devid(fd);
 
diff --git a/tests/i915/gem_tiled_pread_pwrite.c b/tests/i915/gem_tiled_pread_pwrite.c
index f58048faa..28490840f 100644
--- a/tests/i915/gem_tiled_pread_pwrite.c
+++ b/tests/i915/gem_tiled_pread_pwrite.c
@@ -114,6 +114,7 @@ igt_simple_main
 	
 	fd = drm_open_driver(DRIVER_INTEL);
 	igt_require(gem_available_fences(fd) > 0);
+	gem_require_pread_pwrite(fd);
 
 	count = gem_available_fences(fd) + 1;
 	intel_require_memory(2 * count, sizeof(linear), CHECK_RAM);
diff --git a/tests/i915/gem_userptr_blits.c b/tests/i915/gem_userptr_blits.c
index 268423dcd..0ccfdbd9c 100644
--- a/tests/i915/gem_userptr_blits.c
+++ b/tests/i915/gem_userptr_blits.c
@@ -890,6 +890,7 @@ static int test_forbidden_ops(int fd)
 	uint32_t handle;
 	void *ptr;
 
+	gem_require_pread_pwrite(fd);
 	igt_assert(posix_memalign(&ptr, PAGE_SIZE, PAGE_SIZE) == 0);
 	gem_userptr(fd, ptr, PAGE_SIZE, 0, userptr_flags, &handle);
 
@@ -1416,6 +1417,7 @@ static void test_readonly_pwrite(int i915)
 	 */
 
 	igt_require(igt_setup_clflush());
+	gem_require_pread_pwrite(i915);
 
 	sz = 16 << 12;
 	pages = mmap(NULL, sz, PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
diff --git a/tests/i915/gen9_exec_parse.c b/tests/i915/gen9_exec_parse.c
index 8cd82f568..eb7cd9f74 100644
--- a/tests/i915/gen9_exec_parse.c
+++ b/tests/i915/gen9_exec_parse.c
@@ -1024,13 +1024,16 @@ igt_main
 	igt_subtest("batch-zero-length") {
 		const uint32_t noop[] = { 0, MI_BATCH_BUFFER_END };
 
+		gem_require_pread_pwrite(i915);
 		exec_batch(i915, I915_EXEC_BLT, handle,
 			   noop, 0,
 			   -EINVAL);
 	}
 
-	igt_subtest("batch-invalid-length")
+	igt_subtest("batch-invalid-length") {
+		gem_require_pread_pwrite(i915);
 		test_invalid_length(i915, handle);
+	}
 
 	igt_subtest("basic-rejected")
 		test_rejected(i915, handle, false);
-- 
2.27.0.112.g101b3204f3

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [igt-dev] [PATCH i-g-t] lib/ioctl_wrappers: Keep IGT working without pread/pwrite ioctls
@ 2020-09-04 20:25 Ashutosh Dixit
  0 siblings, 0 replies; 17+ messages in thread
From: Ashutosh Dixit @ 2020-09-04 20:25 UTC (permalink / raw)
  To: igt-dev

The general direction at this time is to phase out pread/write ioctls
and not support them in future products. This means IGT must handle
the absence of these ioctls. This patch does this by modifying
gem_read() and gem_write() to do the read/write using the pread/pwrite
ioctls first but when these ioctls are unavailable fall back to doing
the read/write using a combination of mmap and memcpy.

Callers who must absolutely use the pread/pwrite ioctls (such as tests
which test these ioctls or must otherwise only use the pread/pwrite
ioctls) must use gem_require_pread_pwrite() to skip when these ioctls
are not available.

v2: Removed __gem_pread, gem_pread, __gem_pwrite and gem_pwrite
    introduced in v1 since they don't appear necessary

Signed-off-by: Ashutosh Dixit <ashutosh.dixit@intel.com>
---
 lib/ioctl_wrappers.c                        | 133 +++++++++++++++++++-
 lib/ioctl_wrappers.h                        |   3 +
 tests/i915/gem_madvise.c                    |   1 +
 tests/i915/gem_partial_pwrite_pread.c       |   1 +
 tests/i915/gem_pread.c                      |   1 +
 tests/i915/gem_pread_after_blit.c           |   1 +
 tests/i915/gem_pwrite.c                     |   1 +
 tests/i915/gem_pwrite_snooped.c             |   1 +
 tests/i915/gem_readwrite.c                  |   1 +
 tests/i915/gem_set_tiling_vs_pwrite.c       |   1 +
 tests/i915/gem_tiled_partial_pwrite_pread.c |   1 +
 tests/i915/gem_tiled_pread_basic.c          |   1 +
 tests/i915/gem_tiled_pread_pwrite.c         |   1 +
 tests/i915/gem_userptr_blits.c              |   2 +
 tests/i915/gen9_exec_parse.c                |   4 +-
 15 files changed, 146 insertions(+), 7 deletions(-)

diff --git a/lib/ioctl_wrappers.c b/lib/ioctl_wrappers.c
index 3781286d8..ff483fbbc 100644
--- a/lib/ioctl_wrappers.c
+++ b/lib/ioctl_wrappers.c
@@ -55,6 +55,7 @@
 #include "igt_debugfs.h"
 #include "igt_sysfs.h"
 #include "config.h"
+#include "i915/gem_mman.h"
 
 #ifdef HAVE_VALGRIND
 #include <valgrind/valgrind.h>
@@ -323,6 +324,68 @@ void gem_close(int fd, uint32_t handle)
 	do_ioctl(fd, DRM_IOCTL_GEM_CLOSE, &close_bo);
 }
 
+static bool is_cache_coherent(int fd, uint32_t handle)
+{
+	return gem_get_caching(fd, handle) != I915_CACHING_NONE;
+}
+
+static void mmap_write(int fd, uint32_t handle, uint64_t offset,
+		       const void *buf, uint64_t length)
+{
+	void *map = NULL;
+
+	if (is_cache_coherent(fd, handle)) {
+		/* offset arg for mmap functions must be 0 */
+		map = __gem_mmap__cpu_coherent(fd, handle, 0, offset + length,
+					       PROT_READ | PROT_WRITE);
+		if (map)
+			gem_set_domain(fd, handle,
+				       I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
+	}
+
+	if (!map) {
+		map = __gem_mmap_offset__wc(fd, handle, 0, offset + length,
+					    PROT_READ | PROT_WRITE);
+		if (!map)
+			map = gem_mmap__wc(fd, handle, 0, offset + length,
+					   PROT_READ | PROT_WRITE);
+		if (map)
+			gem_set_domain(fd, handle,
+				       I915_GEM_DOMAIN_WC, I915_GEM_DOMAIN_WC);
+	}
+
+	igt_assert(map);
+	memcpy(map + offset, buf, length);
+	munmap(map, offset + length);
+}
+
+static void mmap_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t length)
+{
+	void *map = NULL;
+
+	if (gem_has_llc(fd) || is_cache_coherent(fd, handle)) {
+		/* offset arg for mmap functions must be 0 */
+		map = __gem_mmap__cpu_coherent(fd, handle, 0,
+					       offset + length, PROT_READ);
+		if (map)
+			gem_set_domain(fd, handle, I915_GEM_DOMAIN_CPU, 0);
+	}
+
+	if (!map) {
+		map = __gem_mmap_offset__wc(fd, handle, 0, offset + length,
+					    PROT_READ);
+		if (!map)
+			map = gem_mmap__wc(fd, handle, 0, offset + length,
+					   PROT_READ);
+		if (map)
+			gem_set_domain(fd, handle, I915_GEM_DOMAIN_WC, 0);
+	}
+
+	igt_assert(map);
+	memcpy(buf, map + offset, length);
+	munmap(map, offset + length);
+}
+
 int __gem_write(int fd, uint32_t handle, uint64_t offset, const void *buf, uint64_t length)
 {
 	struct drm_i915_gem_pwrite gem_pwrite;
@@ -348,12 +411,18 @@ int __gem_write(int fd, uint32_t handle, uint64_t offset, const void *buf, uint6
  * @buf: pointer to the data to write into the buffer
  * @length: size of the subrange
  *
- * This wraps the PWRITE ioctl, which is to upload a linear data to a subrange
- * of a gem buffer object.
+ * Method to write to a gem object. Uses the PWRITE ioctl when it is
+ * available, else it uses mmap + memcpy to upload linear data to a
+ * subrange of a gem buffer object.
  */
 void gem_write(int fd, uint32_t handle, uint64_t offset, const void *buf, uint64_t length)
 {
-	igt_assert_eq(__gem_write(fd, handle, offset, buf, length), 0);
+	int ret = __gem_write(fd, handle, offset, buf, length);
+
+	igt_assert(ret == 0 || ret == EOPNOTSUPP);
+
+	if (ret == EOPNOTSUPP)
+		mmap_write(fd, handle, offset, buf, length);
 }
 
 int __gem_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t length)
@@ -380,12 +449,64 @@ int __gem_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t len
  * @buf: pointer to the data to read into
  * @length: size of the subrange
  *
- * This wraps the PREAD ioctl, which is to download a linear data to a subrange
- * of a gem buffer object.
+ * Method to read from a gem object. Uses the PREAD ioctl when it is
+ * available, else it uses mmap + memcpy to download linear data from a
+ * subrange of a gem buffer object.
  */
 void gem_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t length)
 {
-	igt_assert_eq(__gem_read(fd, handle, offset, buf, length), 0);
+	int ret = __gem_read(fd, handle, offset, buf, length);
+
+	igt_assert(ret == 0 || ret == EOPNOTSUPP);
+
+	if (ret == EOPNOTSUPP)
+		mmap_read(fd, handle, offset, buf, length);
+}
+
+/**
+ * gem_has_pwrite
+ * @fd: open i915 drm file descriptor
+ *
+ * Feature test macro to query whether pwrite ioctl is supported
+ */
+bool gem_has_pwrite(int fd)
+{
+	uint32_t handle = gem_create(fd, 4096);
+	int buf, ret;
+
+	ret = __gem_write(fd, handle, 0, &buf, sizeof(buf));
+	gem_close(fd, handle);
+
+	return ret != EOPNOTSUPP;
+}
+
+/**
+ * gem_has_pread
+ * @fd: open i915 drm file descriptor
+ *
+ * Feature test macro to query whether pread ioctl is supported
+ */
+bool gem_has_pread(int fd)
+{
+	uint32_t handle = gem_create(fd, 4096);
+	int buf, ret;
+
+	ret = __gem_read(fd, handle, 0, &buf, sizeof(buf));
+	gem_close(fd, handle);
+
+	return ret != EOPNOTSUPP;
+}
+
+/**
+ * gem_require_pread_pwrite
+ * @fd: open i915 drm file descriptor
+ *
+ * Feature test macro to query whether pread/pwrite ioctls are supported
+ * and skip if they are not
+ */
+void gem_require_pread_pwrite(int fd)
+{
+	igt_require(gem_has_pread(fd) && gem_has_pwrite(fd));
 }
 
 int __gem_set_domain(int fd, uint32_t handle, uint32_t read, uint32_t write)
diff --git a/lib/ioctl_wrappers.h b/lib/ioctl_wrappers.h
index 870ac8b7b..6ba551a71 100644
--- a/lib/ioctl_wrappers.h
+++ b/lib/ioctl_wrappers.h
@@ -71,6 +71,9 @@ int __gem_write(int fd, uint32_t handle, uint64_t offset, const void *buf, uint6
 void gem_write(int fd, uint32_t handle, uint64_t offset,  const void *buf, uint64_t length);
 int __gem_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t length);
 void gem_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t length);
+bool gem_has_pwrite(int fd);
+bool gem_has_pread(int fd);
+void gem_require_pread_pwrite(int fd);
 int __gem_set_domain(int fd, uint32_t handle, uint32_t read, uint32_t write);
 void gem_set_domain(int fd, uint32_t handle, uint32_t read, uint32_t write);
 int gem_wait(int fd, uint32_t handle, int64_t *timeout_ns);
diff --git a/tests/i915/gem_madvise.c b/tests/i915/gem_madvise.c
index 54c9befff..20c3d44ce 100644
--- a/tests/i915/gem_madvise.c
+++ b/tests/i915/gem_madvise.c
@@ -154,6 +154,7 @@ dontneed_before_pwrite(void)
 	uint32_t bbe = MI_BATCH_BUFFER_END;
 	uint32_t handle;
 
+	gem_require_pread_pwrite(fd);
 	handle = gem_create(fd, OBJECT_SIZE);
 	gem_madvise(fd, handle, I915_MADV_DONTNEED);
 
diff --git a/tests/i915/gem_partial_pwrite_pread.c b/tests/i915/gem_partial_pwrite_pread.c
index b4bae9b6d..136a53558 100644
--- a/tests/i915/gem_partial_pwrite_pread.c
+++ b/tests/i915/gem_partial_pwrite_pread.c
@@ -284,6 +284,7 @@ igt_main
 		data.drm_fd = drm_open_driver(DRIVER_INTEL);
 		igt_require_gem(data.drm_fd);
 		gem_require_blitter(data.drm_fd);
+		gem_require_pread_pwrite(data.drm_fd);
 
 		data.devid = intel_get_drm_devid(data.drm_fd);
 		data.bops = buf_ops_create(data.drm_fd);
diff --git a/tests/i915/gem_pread.c b/tests/i915/gem_pread.c
index 6d12b8e9f..db1eacedc 100644
--- a/tests/i915/gem_pread.c
+++ b/tests/i915/gem_pread.c
@@ -149,6 +149,7 @@ igt_main_args("s:", NULL, help_str, opt_handler, NULL)
 
 	igt_fixture {
 		fd = drm_open_driver(DRIVER_INTEL);
+		gem_require_pread_pwrite(fd);
 
 		dst = gem_create(fd, object_size);
 		src = malloc(object_size);
diff --git a/tests/i915/gem_pread_after_blit.c b/tests/i915/gem_pread_after_blit.c
index 81454c930..5c99d0887 100644
--- a/tests/i915/gem_pread_after_blit.c
+++ b/tests/i915/gem_pread_after_blit.c
@@ -212,6 +212,7 @@ igt_main
 	igt_fixture {
 		fd = drm_open_driver(DRIVER_INTEL);
 		igt_require_gem(fd);
+		gem_require_pread_pwrite(fd);
 
 		bufmgr = drm_intel_bufmgr_gem_init(fd, 4096);
 		drm_intel_bufmgr_gem_enable_reuse(bufmgr);
diff --git a/tests/i915/gem_pwrite.c b/tests/i915/gem_pwrite.c
index e491263fd..eea51f978 100644
--- a/tests/i915/gem_pwrite.c
+++ b/tests/i915/gem_pwrite.c
@@ -317,6 +317,7 @@ igt_main_args("s:", NULL, help_str, opt_handler, NULL)
 
 	igt_fixture {
 		fd = drm_open_driver(DRIVER_INTEL);
+		gem_require_pread_pwrite(fd);
 
 		dst = gem_create(fd, object_size);
 		src = malloc(object_size);
diff --git a/tests/i915/gem_pwrite_snooped.c b/tests/i915/gem_pwrite_snooped.c
index 4a3395241..a2eca6afc 100644
--- a/tests/i915/gem_pwrite_snooped.c
+++ b/tests/i915/gem_pwrite_snooped.c
@@ -132,6 +132,7 @@ igt_simple_main
 	fd = drm_open_driver(DRIVER_INTEL);
 	igt_require_gem(fd);
 	gem_require_blitter(fd);
+	gem_require_pread_pwrite(fd);
 
 	devid = intel_get_drm_devid(fd);
 	bufmgr = drm_intel_bufmgr_gem_init(fd, 4096);
diff --git a/tests/i915/gem_readwrite.c b/tests/i915/gem_readwrite.c
index 6b2977c1c..ca31741c6 100644
--- a/tests/i915/gem_readwrite.c
+++ b/tests/i915/gem_readwrite.c
@@ -83,6 +83,7 @@ igt_main
 
 	igt_fixture {
 		fd = drm_open_driver(DRIVER_INTEL);
+		gem_require_pread_pwrite(fd);
 
 		handle = gem_create(fd, OBJECT_SIZE);
 	}
diff --git a/tests/i915/gem_set_tiling_vs_pwrite.c b/tests/i915/gem_set_tiling_vs_pwrite.c
index 302ea24b6..8f38c9b9b 100644
--- a/tests/i915/gem_set_tiling_vs_pwrite.c
+++ b/tests/i915/gem_set_tiling_vs_pwrite.c
@@ -55,6 +55,7 @@ igt_simple_main
 
 	fd = drm_open_driver(DRIVER_INTEL);
 	igt_require(gem_available_fences(fd) > 0);
+	gem_require_pread_pwrite(fd);
 
 	for (int i = 0; i < OBJECT_SIZE/4; i++)
 		data[i] = i;
diff --git a/tests/i915/gem_tiled_partial_pwrite_pread.c b/tests/i915/gem_tiled_partial_pwrite_pread.c
index 7de5358b2..0c4545990 100644
--- a/tests/i915/gem_tiled_partial_pwrite_pread.c
+++ b/tests/i915/gem_tiled_partial_pwrite_pread.c
@@ -270,6 +270,7 @@ igt_main
 		igt_require_gem(fd);
 		gem_require_mappable_ggtt(fd);
 		gem_require_blitter(fd);
+		gem_require_pread_pwrite(fd);
 
 		bufmgr = drm_intel_bufmgr_gem_init(fd, 4096);
 		//drm_intel_bufmgr_gem_enable_reuse(bufmgr);
diff --git a/tests/i915/gem_tiled_pread_basic.c b/tests/i915/gem_tiled_pread_basic.c
index 7cb644104..f8f73c03a 100644
--- a/tests/i915/gem_tiled_pread_basic.c
+++ b/tests/i915/gem_tiled_pread_basic.c
@@ -127,6 +127,7 @@ igt_simple_main
 	igt_require(gem_available_fences(fd) > 0);
 	handle = create_bo(fd);
 	igt_require(gem_get_tiling(fd, handle, &tiling, &swizzle));
+	gem_require_pread_pwrite(fd);
 
 	devid = intel_get_drm_devid(fd);
 
diff --git a/tests/i915/gem_tiled_pread_pwrite.c b/tests/i915/gem_tiled_pread_pwrite.c
index f58048faa..28490840f 100644
--- a/tests/i915/gem_tiled_pread_pwrite.c
+++ b/tests/i915/gem_tiled_pread_pwrite.c
@@ -114,6 +114,7 @@ igt_simple_main
 	
 	fd = drm_open_driver(DRIVER_INTEL);
 	igt_require(gem_available_fences(fd) > 0);
+	gem_require_pread_pwrite(fd);
 
 	count = gem_available_fences(fd) + 1;
 	intel_require_memory(2 * count, sizeof(linear), CHECK_RAM);
diff --git a/tests/i915/gem_userptr_blits.c b/tests/i915/gem_userptr_blits.c
index 268423dcd..0ccfdbd9c 100644
--- a/tests/i915/gem_userptr_blits.c
+++ b/tests/i915/gem_userptr_blits.c
@@ -890,6 +890,7 @@ static int test_forbidden_ops(int fd)
 	uint32_t handle;
 	void *ptr;
 
+	gem_require_pread_pwrite(fd);
 	igt_assert(posix_memalign(&ptr, PAGE_SIZE, PAGE_SIZE) == 0);
 	gem_userptr(fd, ptr, PAGE_SIZE, 0, userptr_flags, &handle);
 
@@ -1416,6 +1417,7 @@ static void test_readonly_pwrite(int i915)
 	 */
 
 	igt_require(igt_setup_clflush());
+	gem_require_pread_pwrite(i915);
 
 	sz = 16 << 12;
 	pages = mmap(NULL, sz, PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
diff --git a/tests/i915/gen9_exec_parse.c b/tests/i915/gen9_exec_parse.c
index 8cd82f568..eddc0f871 100644
--- a/tests/i915/gen9_exec_parse.c
+++ b/tests/i915/gen9_exec_parse.c
@@ -1029,8 +1029,10 @@ igt_main
 			   -EINVAL);
 	}
 
-	igt_subtest("batch-invalid-length")
+	igt_subtest("batch-invalid-length") {
+		gem_require_pread_pwrite(i915);
 		test_invalid_length(i915, handle);
+	}
 
 	igt_subtest("basic-rejected")
 		test_rejected(i915, handle, false);
-- 
2.27.0.112.g101b3204f3

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2021-03-16 18:46 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-30  3:40 [igt-dev] [PATCH i-g-t] lib/ioctl_wrappers: Keep IGT working without pread/pwrite ioctls Ashutosh Dixit
2020-09-30  4:15 ` [igt-dev] ✓ Fi.CI.BAT: success for lib/ioctl_wrappers: Keep IGT working without pread/pwrite ioctls (rev6) Patchwork
2020-09-30 13:29 ` [igt-dev] ✓ Fi.CI.IGT: " Patchwork
2020-10-02  9:36 ` [igt-dev] [PATCH i-g-t] lib/ioctl_wrappers: Keep IGT working without pread/pwrite ioctls Chris Wilson
2020-10-02 19:34   ` Dixit, Ashutosh
2021-01-11 20:46 ` [igt-dev] [i-g-t] " Dave Airlie
  -- strict thread matches above, loose matches on Subject: below --
2021-03-15 22:53 [igt-dev] [PATCH i-g-t] " Ashutosh Dixit
2021-01-21  8:37 Ashutosh Dixit
2021-03-15 16:51 ` Tvrtko Ursulin
2021-03-15 23:19   ` Dixit, Ashutosh
2021-03-16  9:16     ` Tvrtko Ursulin
2021-03-16 18:46       ` Dixit, Ashutosh
2020-09-16 20:11 Ashutosh Dixit
2020-09-06 23:43 Ashutosh Dixit
2020-09-09  7:03 ` Zbigniew Kempczyński
2020-09-06 17:49 Ashutosh Dixit
2020-09-04 20:25 Ashutosh Dixit

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.