Re: [Intel-gfx] [PATCH] drm/i915/selftests: Wrap vm_mmap() around GEM objects

2019-11-07 Thread Abdiel Janulgue


On 06/11/2019 10.26, Chris Wilson wrote:
> Provide a utility function to create a vma corresponding to an mmap() of
> our device. And use it to exercise the equivalent of userspace
> performing a GTT mmap of our objects.
> 
> Signed-off-by: Chris Wilson 
> Cc: Abdiel Janulgue 

Reviewed-by: Abdiel Janulgue 
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

[Intel-gfx] [PATCH] drm/i915/selftests: Wrap vm_mmap() around GEM objects

2019-11-06 Thread Chris Wilson
Provide a utility function to create a vma corresponding to an mmap() of
our device. And use it to exercise the equivalent of userspace
performing a GTT mmap of our objects.

Signed-off-by: Chris Wilson 
Cc: Abdiel Janulgue 
---
 drivers/gpu/drm/drm_file.c|  2 +
 drivers/gpu/drm/i915/Makefile |  2 +
 .../drm/i915/gem/selftests/i915_gem_mman.c| 98 +++
 drivers/gpu/drm/i915/selftests/igt_mmap.c | 65 
 drivers/gpu/drm/i915/selftests/igt_mmap.h | 19 
 include/drm/drm_file.h|  3 +
 6 files changed, 189 insertions(+)
 create mode 100644 drivers/gpu/drm/i915/selftests/igt_mmap.c
 create mode 100644 drivers/gpu/drm/i915/selftests/igt_mmap.h

diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c
index ea34bc991858..33d9c6ec5636 100644
--- a/drivers/gpu/drm/drm_file.c
+++ b/drivers/gpu/drm/drm_file.c
@@ -168,6 +168,7 @@ struct drm_file *drm_file_alloc(struct drm_minor *minor)
 
return ERR_PTR(ret);
 }
+EXPORT_SYMBOL(drm_file_alloc);
 
 static void drm_events_release(struct drm_file *file_priv)
 {
@@ -258,6 +259,7 @@ void drm_file_free(struct drm_file *file)
put_pid(file->pid);
kfree(file);
 }
+EXPORT_SYMBOL(drm_file_free);
 
 static void drm_close_helper(struct file *filp)
 {
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 90dcf09f52cc..ea704be22cea 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -253,12 +253,14 @@ i915-y += i915_perf.o
 
 # Post-mortem debug and GPU hang state capture
 i915-$(CONFIG_DRM_I915_CAPTURE_ERROR) += i915_gpu_error.o
+
 i915-$(CONFIG_DRM_I915_SELFTEST) += \
gem/selftests/igt_gem_utils.o \
selftests/i915_random.o \
selftests/i915_selftest.o \
selftests/igt_flush_test.o \
selftests/igt_live_test.o \
+   selftests/igt_mmap.o \
selftests/igt_reset.o \
selftests/igt_spinner.o
 
diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
index 29b2077b73d2..af2e44b65791 100644
--- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
@@ -12,6 +12,7 @@
 #include "i915_selftest.h"
 #include "selftests/i915_random.h"
 #include "selftests/igt_flush_test.h"
+#include "selftests/igt_mmap.h"
 
 struct tile {
unsigned int width;
@@ -694,12 +695,109 @@ static int igt_mmap_offset_exhaustion(void *arg)
goto out;
 }
 
+#define expand32(x) (((x) << 0) | ((x) << 8) | ((x) << 16) | ((x) << 24))
+static int igt_mmap_gtt(void *arg)
+{
+   struct drm_i915_private *i915 = arg;
+   struct drm_i915_gem_object *obj;
+   struct vm_area_struct *area;
+   unsigned long addr;
+   void *vaddr;
+   int err, i;
+
+   obj = i915_gem_object_create_internal(i915, PAGE_SIZE);
+   if (IS_ERR(obj))
+   return PTR_ERR(obj);
+
+   vaddr = i915_gem_object_pin_map(obj, I915_MAP_WB);
+   if (IS_ERR(vaddr)) {
+   err = PTR_ERR(vaddr);
+   goto out;
+   }
+   memset(vaddr, POISON_INUSE, PAGE_SIZE);
+   i915_gem_object_flush_map(obj);
+   i915_gem_object_unpin_map(obj);
+
+   err = create_mmap_offset(obj);
+   if (err) {
+   pr_err("Unable to insert object into reclaimed hole\n");
+   goto out;
+   }
+
+   addr = igt_mmap(i915, >base.vma_node, 0, PROT_WRITE, MAP_SHARED);
+   if (IS_ERR_VALUE(addr)) {
+   err = addr;
+   goto out;
+   }
+
+   pr_info("igt_mmap(obj:gtt) @ %lx\n", addr);
+
+   area = find_vma(current->mm, addr);
+   if (!area) {
+   pr_err("Did not create a vm_area_struct for the mmap\n");
+   err = -EINVAL;
+   goto out_unmap;
+   }
+
+   if (area->vm_private_data != obj) {
+   pr_err("vm_area_struct did not point back to our object!\n");
+   err = -EINVAL;
+   goto out_unmap;
+   }
+
+   for (i = 0; i < PAGE_SIZE / sizeof(u32); i++) {
+   u32 __user *ux = u64_to_user_ptr((u64)(addr + i * sizeof*(ux)));
+   u32 x;
+
+   if (get_user(x, ux)) {
+   pr_err("Unable to read from GTT mmap, offset:%zd\n",
+  i * sizeof(x));
+   err = -EFAULT;
+   break;
+   }
+
+   if (x != expand32(POISON_INUSE)) {
+   pr_err("Read incorrect value from GTT mmap, offset:%zd, 
found:%x, expected:%x\n",
+  i * sizeof(x), x, expand32(POISON_INUSE));
+   err = -EINVAL;
+   break;
+   }
+
+   x = expand32(POISON_FREE);
+   if (put_user(x, ux)) {
+   pr_err("Unable to write to GTT mmap, offset:%zd\n",
+

[Intel-gfx] [PATCH] drm/i915/selftests: Wrap vm_mmap() around GEM objects

2019-11-05 Thread Chris Wilson
Provide a utility function to create a vma corresponding to an mmap() of
our device.

Signed-off-by: Chris Wilson 
Cc: Abdiel Janulgue 
---
 drivers/gpu/drm/drm_file.c|  2 +
 drivers/gpu/drm/i915/Makefile |  2 +
 .../drm/i915/gem/selftests/i915_gem_mman.c| 33 +++
 drivers/gpu/drm/i915/selftests/igt_mmap.c | 59 +++
 drivers/gpu/drm/i915/selftests/igt_mmap.h | 12 
 include/drm/drm_file.h|  3 +
 6 files changed, 111 insertions(+)
 create mode 100644 drivers/gpu/drm/i915/selftests/igt_mmap.c
 create mode 100644 drivers/gpu/drm/i915/selftests/igt_mmap.h

diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c
index ea34bc991858..33d9c6ec5636 100644
--- a/drivers/gpu/drm/drm_file.c
+++ b/drivers/gpu/drm/drm_file.c
@@ -168,6 +168,7 @@ struct drm_file *drm_file_alloc(struct drm_minor *minor)
 
return ERR_PTR(ret);
 }
+EXPORT_SYMBOL(drm_file_alloc);
 
 static void drm_events_release(struct drm_file *file_priv)
 {
@@ -258,6 +259,7 @@ void drm_file_free(struct drm_file *file)
put_pid(file->pid);
kfree(file);
 }
+EXPORT_SYMBOL(drm_file_free);
 
 static void drm_close_helper(struct file *filp)
 {
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 90dcf09f52cc..ea704be22cea 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -253,12 +253,14 @@ i915-y += i915_perf.o
 
 # Post-mortem debug and GPU hang state capture
 i915-$(CONFIG_DRM_I915_CAPTURE_ERROR) += i915_gpu_error.o
+
 i915-$(CONFIG_DRM_I915_SELFTEST) += \
gem/selftests/igt_gem_utils.o \
selftests/i915_random.o \
selftests/i915_selftest.o \
selftests/igt_flush_test.o \
selftests/igt_live_test.o \
+   selftests/igt_mmap.o \
selftests/igt_reset.o \
selftests/igt_spinner.o
 
diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
index 29b2077b73d2..2a62a945f04f 100644
--- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
@@ -12,6 +12,7 @@
 #include "i915_selftest.h"
 #include "selftests/i915_random.h"
 #include "selftests/igt_flush_test.h"
+#include "selftests/igt_mmap.h"
 
 struct tile {
unsigned int width;
@@ -694,12 +695,44 @@ static int igt_mmap_offset_exhaustion(void *arg)
goto out;
 }
 
+static int igt_mmap_gtt(void *arg)
+{
+   struct drm_i915_private *i915 = arg;
+   struct drm_i915_gem_object *obj;
+   unsigned long addr;
+   int err;
+
+   obj = i915_gem_object_create_internal(i915, PAGE_SIZE);
+   if (IS_ERR(obj))
+   return PTR_ERR(obj);
+
+   err = create_mmap_offset(obj);
+   if (err) {
+   pr_err("Unable to insert object into reclaimed hole\n");
+   goto out;
+   }
+
+   addr = igt_mmap(i915, >base.vma_node, 0, PROT_WRITE, MAP_SHARED);
+   if (IS_ERR_VALUE(addr)) {
+   err = addr;
+   goto out;
+   }
+
+   pr_info("igt_mmap(obj:gtt) @ %lx\n", addr);
+
+   vm_munmap(addr, PAGE_SIZE);
+out:
+   i915_gem_object_put(obj);
+   return err;
+}
+
 int i915_gem_mman_live_selftests(struct drm_i915_private *i915)
 {
static const struct i915_subtest tests[] = {
SUBTEST(igt_partial_tiling),
SUBTEST(igt_smoke_tiling),
SUBTEST(igt_mmap_offset_exhaustion),
+   SUBTEST(igt_mmap_gtt),
};
 
return i915_subtests(tests, i915);
diff --git a/drivers/gpu/drm/i915/selftests/igt_mmap.c 
b/drivers/gpu/drm/i915/selftests/igt_mmap.c
new file mode 100644
index ..c4b01096d330
--- /dev/null
+++ b/drivers/gpu/drm/i915/selftests/igt_mmap.c
@@ -0,0 +1,59 @@
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "i915_drv.h"
+#include "igt_mmap.h"
+
+static struct file *mock_file_open(struct drm_i915_private *i915)
+{
+   struct drm_file *priv;
+   struct file *file;
+
+   priv = drm_file_alloc(i915->drm.primary);
+   if (IS_ERR(priv))
+   return ERR_CAST(priv);
+
+   file = anon_inode_getfile("i915", i915->drm.driver->fops, priv, O_RDWR);
+   if (IS_ERR(file)) {
+   drm_file_free(priv);
+   return file;
+   }
+
+   drm_dev_get(>drm);
+   priv->filp = file;
+
+   return file;
+}
+
+unsigned long igt_mmap(struct drm_i915_private *i915,
+  struct drm_vma_offset_node *node,
+  unsigned long addr,
+  unsigned long prot,
+  unsigned long flags)
+{
+   struct file *file;
+   int err;
+
+   /* Pretend to open("/dev/dri/card0") */
+   file = mock_file_open(i915);
+   if (IS_ERR(file))
+   return PTR_ERR(file);
+
+   err = drm_vma_node_allow(node, file->private_data);
+   if (err) {
+