All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] drm/i915/userptr: Probe existence of backing struct pages upon creation
@ 2017-11-08 18:51 Chris Wilson
  2017-11-08 18:51 ` [PATCH 2/2] drm/i915/userptr: Add a flag to populate the userptr on creation Chris Wilson
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Chris Wilson @ 2017-11-08 18:51 UTC (permalink / raw)
  To: intel-gfx

Jason Ekstrand requested a more efficient method than userptr+set-domain
to determine if the userptr object was backed by a complete set of pages
upon creation. To be more efficient than simply populating the userptr
using get_user_pages() (as done by the call to set-domain or execbuf),
we can walk the tree of vm_area_struct and check for gaps or vma not
backed by struct page (VM_PFNMAP). The question is how to handle
VM_MIXEDMAP which may be either struct page or pfn backed...

Testcase: igt/gem_userptr_blits/probe
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Cc: Michał Winiarski <michal.winiarski@intel.com>
Cc: Jason Ekstrand <jason@jlekstrand.net>
---
 drivers/gpu/drm/i915/i915_gem_userptr.c | 38 +++++++++++++++++++++++++++++++++
 include/uapi/drm/i915_drm.h             |  5 +++--
 2 files changed, 41 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c
index e26b23171b56..dbc5818dd28b 100644
--- a/drivers/gpu/drm/i915/i915_gem_userptr.c
+++ b/drivers/gpu/drm/i915/i915_gem_userptr.c
@@ -719,6 +719,33 @@ static const struct drm_i915_gem_object_ops i915_gem_userptr_ops = {
 	.release = i915_gem_userptr_release,
 };
 
+static int
+probe_range(struct mm_struct *mm, unsigned long addr, unsigned long len)
+{
+	const unsigned long end = addr + len;
+	struct vm_area_struct *vma;
+	int ret = -EFAULT;
+
+	down_read(&mm->mmap_sem);
+	for (vma = find_vma(mm, addr); vma; vma = vma->vm_next) {
+		if (vma->vm_start > addr)
+			break;
+
+		if (vma->vm_flags & (VM_PFNMAP | VM_MIXEDMAP))
+			break;
+
+		if (vma->vm_end >= end) {
+			ret = 0;
+			break;
+		}
+
+		addr = vma->vm_end;
+	}
+	up_read(&mm->mmap_sem);
+
+	return ret;
+}
+
 /**
  * Creates a new mm object that wraps some normal memory from the process
  * context - user memory.
@@ -771,6 +798,7 @@ i915_gem_userptr_ioctl(struct drm_device *dev, void *data, struct drm_file *file
 	}
 
 	if (args->flags & ~(I915_USERPTR_READ_ONLY |
+			    I915_USERPTR_PROBE |
 			    I915_USERPTR_UNSYNCHRONIZED))
 		return -EINVAL;
 
@@ -788,6 +816,16 @@ i915_gem_userptr_ioctl(struct drm_device *dev, void *data, struct drm_file *file
 		return -ENODEV;
 	}
 
+	if (args->flags & I915_USERPTR_PROBE) {
+		/*
+		 * Check that the range pointed to represents real struct
+		 * pages and not iomappings (at this moment in time!)
+		 */
+		ret = probe_range(current->mm, args->user_ptr, args->user_size);
+		if (ret)
+			return ret;
+	}
+
 	obj = i915_gem_object_alloc(dev_priv);
 	if (obj == NULL)
 		return -ENOMEM;
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index ac3c6503ca27..392ede2ca63e 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -1352,8 +1352,9 @@ struct drm_i915_gem_userptr {
 	__u64 user_ptr;
 	__u64 user_size;
 	__u32 flags;
-#define I915_USERPTR_READ_ONLY 0x1
-#define I915_USERPTR_UNSYNCHRONIZED 0x80000000
+#define I915_USERPTR_READ_ONLY		0x1
+#define I915_USERPTR_PROBE		0x2
+#define I915_USERPTR_UNSYNCHRONIZED	0x80000000
 	/**
 	 * Returned handle for the object.
 	 *
-- 
2.15.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 2/2] drm/i915/userptr: Add a flag to populate the userptr on creation
  2017-11-08 18:51 [PATCH 1/2] drm/i915/userptr: Probe existence of backing struct pages upon creation Chris Wilson
@ 2017-11-08 18:51 ` Chris Wilson
  2017-11-08 19:05   ` Jason Ekstrand
  2017-11-08 19:25 ` ✓ Fi.CI.BAT: success for series starting with [1/2] drm/i915/userptr: Probe existence of backing struct pages upon creation Patchwork
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 7+ messages in thread
From: Chris Wilson @ 2017-11-08 18:51 UTC (permalink / raw)
  To: intel-gfx

Acquiring the backing struct pages for the userptr range is not free;
the first client for userptr would insist on frequently creating userptr
objects ahead of time and not use them. For that first client, deferring
the cost of populating the userptr (calling get_user_pages()) to the
actual execbuf was a substantial improvement. However, not all clients
are the same, and most would like to validate that the userptr is valid
and backed by struct pages upon creation, so offer a
I915_USERPTR_POPULATE flag to do just that.

Note that big difference between I915_USERPTR_POPULATE and the deferred
scheme is that POPULATE is guaranteed to be synchronous, the result is
known before the ioctl returns (and the handle exposed). However, due to
system memory pressure, the object may be paged out before use,
requiring them to be paged back in on execbuf (as may always happen).

Testcase: igt/gem_userptr_blits/populate
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Cc: Michał Winiarski <michal.winiarski@intel.com>
Cc: Jason Ekstrand <jason@jlekstrand.net>
---
 drivers/gpu/drm/i915/i915_gem_userptr.c | 63 ++++++++++++++++++++++++++++++++-
 include/uapi/drm/i915_drm.h             |  1 +
 2 files changed, 63 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c
index dbc5818dd28b..f05f1322ec27 100644
--- a/drivers/gpu/drm/i915/i915_gem_userptr.c
+++ b/drivers/gpu/drm/i915/i915_gem_userptr.c
@@ -746,6 +746,64 @@ probe_range(struct mm_struct *mm, unsigned long addr, unsigned long len)
 	return ret;
 }
 
+static int populate(struct drm_i915_gem_object *obj)
+{
+	const unsigned long num_pages = obj->base.size >> PAGE_SHIFT;
+	const unsigned long addr = obj->userptr.ptr;
+	struct sg_table *pages;
+	struct page **pvec;
+	int pinned;
+	int ret = 0;
+
+	pvec = kvmalloc_array(num_pages, sizeof(struct page *), GFP_KERNEL);
+	if (!pvec)
+		return -ENOMEM;
+
+	pinned = __get_user_pages_fast(addr, num_pages,
+				       !obj->userptr.read_only,
+				       pvec);
+	if (pinned < 0) {
+		ret = pinned;
+		goto err;
+	}
+
+	if (pinned < num_pages) {
+		unsigned int flags;
+
+		flags = 0;
+		if (!obj->userptr.read_only)
+			flags |= FOLL_WRITE;
+
+		down_read(&current->mm->mmap_sem);
+		do {
+			ret = get_user_pages(addr + pinned * PAGE_SIZE,
+					     num_pages - pinned,
+					     flags,
+					     pvec + pinned, NULL);
+			if (ret < 0)
+				break;
+
+			pinned += ret;
+		} while (pinned < num_pages);
+		up_read(&current->mm->mmap_sem);
+		if (ret < 0)
+			goto err;
+	}
+
+	mutex_lock(&obj->mm.lock);
+	pages = __i915_gem_userptr_alloc_pages(obj, pvec, num_pages);
+	mutex_unlock(&obj->mm.lock);
+	if (!IS_ERR(pages))
+		pinned = 0;
+	else
+		ret = PTR_ERR(pages);
+
+err:
+	release_pages(pvec, pinned, 0);
+	kvfree(pvec);
+	return ret;
+}
+
 /**
  * Creates a new mm object that wraps some normal memory from the process
  * context - user memory.
@@ -799,6 +857,7 @@ i915_gem_userptr_ioctl(struct drm_device *dev, void *data, struct drm_file *file
 
 	if (args->flags & ~(I915_USERPTR_READ_ONLY |
 			    I915_USERPTR_PROBE |
+			    I915_USERPTR_POPULATE |
 			    I915_USERPTR_UNSYNCHRONIZED))
 		return -EINVAL;
 
@@ -816,7 +875,7 @@ i915_gem_userptr_ioctl(struct drm_device *dev, void *data, struct drm_file *file
 		return -ENODEV;
 	}
 
-	if (args->flags & I915_USERPTR_PROBE) {
+	if (args->flags & (I915_USERPTR_PROBE | I915_USERPTR_POPULATE)) {
 		/*
 		 * Check that the range pointed to represents real struct
 		 * pages and not iomappings (at this moment in time!)
@@ -846,6 +905,8 @@ i915_gem_userptr_ioctl(struct drm_device *dev, void *data, struct drm_file *file
 	ret = i915_gem_userptr_init__mm_struct(obj);
 	if (ret == 0)
 		ret = i915_gem_userptr_init__mmu_notifier(obj, args->flags);
+	if (ret == 0 && args->flags & I915_USERPTR_POPULATE)
+		ret = populate(obj);
 	if (ret == 0)
 		ret = drm_gem_handle_create(file, &obj->base, &handle);
 
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index 392ede2ca63e..500c408c912a 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -1354,6 +1354,7 @@ struct drm_i915_gem_userptr {
 	__u32 flags;
 #define I915_USERPTR_READ_ONLY		0x1
 #define I915_USERPTR_PROBE		0x2
+#define I915_USERPTR_POPULATE		0x4
 #define I915_USERPTR_UNSYNCHRONIZED	0x80000000
 	/**
 	 * Returned handle for the object.
-- 
2.15.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 2/2] drm/i915/userptr: Add a flag to populate the userptr on creation
  2017-11-08 18:51 ` [PATCH 2/2] drm/i915/userptr: Add a flag to populate the userptr on creation Chris Wilson
@ 2017-11-08 19:05   ` Jason Ekstrand
  0 siblings, 0 replies; 7+ messages in thread
From: Jason Ekstrand @ 2017-11-08 19:05 UTC (permalink / raw)
  To: Chris Wilson; +Cc: Intel GFX


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

Both of these patches need I915_PARAM_HAS_USERPTR_WHATEVER queries.

On Wed, Nov 8, 2017 at 10:51 AM, Chris Wilson <chris@chris-wilson.co.uk>
wrote:

> Acquiring the backing struct pages for the userptr range is not free;
> the first client for userptr would insist on frequently creating userptr
> objects ahead of time and not use them. For that first client, deferring
> the cost of populating the userptr (calling get_user_pages()) to the
> actual execbuf was a substantial improvement. However, not all clients
> are the same, and most would like to validate that the userptr is valid
> and backed by struct pages upon creation, so offer a
> I915_USERPTR_POPULATE flag to do just that.
>
> Note that big difference between I915_USERPTR_POPULATE and the deferred
> scheme is that POPULATE is guaranteed to be synchronous, the result is
> known before the ioctl returns (and the handle exposed). However, due to
> system memory pressure, the object may be paged out before use,
> requiring them to be paged back in on execbuf (as may always happen).
>
> Testcase: igt/gem_userptr_blits/populate
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
> Cc: Michał Winiarski <michal.winiarski@intel.com>
> Cc: Jason Ekstrand <jason@jlekstrand.net>
> ---
>  drivers/gpu/drm/i915/i915_gem_userptr.c | 63
> ++++++++++++++++++++++++++++++++-
>  include/uapi/drm/i915_drm.h             |  1 +
>  2 files changed, 63 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c
> b/drivers/gpu/drm/i915/i915_gem_userptr.c
> index dbc5818dd28b..f05f1322ec27 100644
> --- a/drivers/gpu/drm/i915/i915_gem_userptr.c
> +++ b/drivers/gpu/drm/i915/i915_gem_userptr.c
> @@ -746,6 +746,64 @@ probe_range(struct mm_struct *mm, unsigned long addr,
> unsigned long len)
>         return ret;
>  }
>
> +static int populate(struct drm_i915_gem_object *obj)
> +{
> +       const unsigned long num_pages = obj->base.size >> PAGE_SHIFT;
> +       const unsigned long addr = obj->userptr.ptr;
> +       struct sg_table *pages;
> +       struct page **pvec;
> +       int pinned;
> +       int ret = 0;
> +
> +       pvec = kvmalloc_array(num_pages, sizeof(struct page *),
> GFP_KERNEL);
> +       if (!pvec)
> +               return -ENOMEM;
> +
> +       pinned = __get_user_pages_fast(addr, num_pages,
> +                                      !obj->userptr.read_only,
> +                                      pvec);
> +       if (pinned < 0) {
> +               ret = pinned;
> +               goto err;
> +       }
> +
> +       if (pinned < num_pages) {
> +               unsigned int flags;
> +
> +               flags = 0;
> +               if (!obj->userptr.read_only)
> +                       flags |= FOLL_WRITE;
> +
> +               down_read(&current->mm->mmap_sem);
> +               do {
> +                       ret = get_user_pages(addr + pinned * PAGE_SIZE,
> +                                            num_pages - pinned,
> +                                            flags,
> +                                            pvec + pinned, NULL);
> +                       if (ret < 0)
> +                               break;
> +
> +                       pinned += ret;
> +               } while (pinned < num_pages);
> +               up_read(&current->mm->mmap_sem);
> +               if (ret < 0)
> +                       goto err;
> +       }
> +
> +       mutex_lock(&obj->mm.lock);
> +       pages = __i915_gem_userptr_alloc_pages(obj, pvec, num_pages);
> +       mutex_unlock(&obj->mm.lock);
> +       if (!IS_ERR(pages))
> +               pinned = 0;
> +       else
> +               ret = PTR_ERR(pages);
> +
> +err:
> +       release_pages(pvec, pinned, 0);
> +       kvfree(pvec);
> +       return ret;
> +}
> +
>  /**
>   * Creates a new mm object that wraps some normal memory from the process
>   * context - user memory.
> @@ -799,6 +857,7 @@ i915_gem_userptr_ioctl(struct drm_device *dev, void
> *data, struct drm_file *file
>
>         if (args->flags & ~(I915_USERPTR_READ_ONLY |
>                             I915_USERPTR_PROBE |
> +                           I915_USERPTR_POPULATE |
>                             I915_USERPTR_UNSYNCHRONIZED))
>                 return -EINVAL;
>
> @@ -816,7 +875,7 @@ i915_gem_userptr_ioctl(struct drm_device *dev, void
> *data, struct drm_file *file
>                 return -ENODEV;
>         }
>
> -       if (args->flags & I915_USERPTR_PROBE) {
> +       if (args->flags & (I915_USERPTR_PROBE | I915_USERPTR_POPULATE)) {
>                 /*
>                  * Check that the range pointed to represents real struct
>                  * pages and not iomappings (at this moment in time!)
> @@ -846,6 +905,8 @@ i915_gem_userptr_ioctl(struct drm_device *dev, void
> *data, struct drm_file *file
>         ret = i915_gem_userptr_init__mm_struct(obj);
>         if (ret == 0)
>                 ret = i915_gem_userptr_init__mmu_notifier(obj,
> args->flags);
> +       if (ret == 0 && args->flags & I915_USERPTR_POPULATE)
> +               ret = populate(obj);
>         if (ret == 0)
>                 ret = drm_gem_handle_create(file, &obj->base, &handle);
>
> diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
> index 392ede2ca63e..500c408c912a 100644
> --- a/include/uapi/drm/i915_drm.h
> +++ b/include/uapi/drm/i915_drm.h
> @@ -1354,6 +1354,7 @@ struct drm_i915_gem_userptr {
>         __u32 flags;
>  #define I915_USERPTR_READ_ONLY         0x1
>  #define I915_USERPTR_PROBE             0x2
> +#define I915_USERPTR_POPULATE          0x4
>  #define I915_USERPTR_UNSYNCHRONIZED    0x80000000
>         /**
>          * Returned handle for the object.
> --
> 2.15.0
>
>

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

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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* ✓ Fi.CI.BAT: success for series starting with [1/2] drm/i915/userptr: Probe existence of backing struct pages upon creation
  2017-11-08 18:51 [PATCH 1/2] drm/i915/userptr: Probe existence of backing struct pages upon creation Chris Wilson
  2017-11-08 18:51 ` [PATCH 2/2] drm/i915/userptr: Add a flag to populate the userptr on creation Chris Wilson
@ 2017-11-08 19:25 ` Patchwork
  2017-11-08 20:49 ` ✓ Fi.CI.IGT: " Patchwork
  2017-11-09 16:10 ` [PATCH 1/2] " Tvrtko Ursulin
  3 siblings, 0 replies; 7+ messages in thread
From: Patchwork @ 2017-11-08 19:25 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

== Series Details ==

Series: series starting with [1/2] drm/i915/userptr: Probe existence of backing struct pages upon creation
URL   : https://patchwork.freedesktop.org/series/33449/
State : success

== Summary ==

Series 33449v1 series starting with [1/2] drm/i915/userptr: Probe existence of backing struct pages upon creation
https://patchwork.freedesktop.org/api/1.0/series/33449/revisions/1/mbox/

Test gem_ringfill:
        Subgroup basic-default-hang:
                dmesg-warn -> INCOMPLETE (fi-pnv-d510) fdo#101600

fdo#101600 https://bugs.freedesktop.org/show_bug.cgi?id=101600

fi-bdw-5557u     total:289  pass:268  dwarn:0   dfail:0   fail:0   skip:21  time:447s
fi-bdw-gvtdvm    total:289  pass:265  dwarn:0   dfail:0   fail:0   skip:24  time:449s
fi-blb-e6850     total:289  pass:223  dwarn:1   dfail:0   fail:0   skip:65  time:383s
fi-bsw-n3050     total:289  pass:243  dwarn:0   dfail:0   fail:0   skip:46  time:546s
fi-bwr-2160      total:289  pass:183  dwarn:0   dfail:0   fail:0   skip:106 time:277s
fi-bxt-dsi       total:289  pass:259  dwarn:0   dfail:0   fail:0   skip:30  time:501s
fi-bxt-j4205     total:289  pass:260  dwarn:0   dfail:0   fail:0   skip:29  time:508s
fi-byt-j1900     total:289  pass:254  dwarn:0   dfail:0   fail:0   skip:35  time:503s
fi-byt-n2820     total:289  pass:250  dwarn:0   dfail:0   fail:0   skip:39  time:495s
fi-elk-e7500     total:289  pass:229  dwarn:0   dfail:0   fail:0   skip:60  time:426s
fi-gdg-551       total:289  pass:178  dwarn:1   dfail:0   fail:1   skip:109 time:265s
fi-glk-1         total:289  pass:261  dwarn:0   dfail:0   fail:0   skip:28  time:544s
fi-hsw-4770      total:289  pass:262  dwarn:0   dfail:0   fail:0   skip:27  time:432s
fi-hsw-4770r     total:289  pass:262  dwarn:0   dfail:0   fail:0   skip:27  time:441s
fi-ilk-650       total:289  pass:228  dwarn:0   dfail:0   fail:0   skip:61  time:433s
fi-ivb-3520m     total:289  pass:260  dwarn:0   dfail:0   fail:0   skip:29  time:496s
fi-ivb-3770      total:289  pass:260  dwarn:0   dfail:0   fail:0   skip:29  time:464s
fi-kbl-7500u     total:289  pass:264  dwarn:1   dfail:0   fail:0   skip:24  time:491s
fi-kbl-7560u     total:289  pass:270  dwarn:0   dfail:0   fail:0   skip:19  time:531s
fi-kbl-7567u     total:289  pass:269  dwarn:0   dfail:0   fail:0   skip:20  time:479s
fi-kbl-r         total:289  pass:262  dwarn:0   dfail:0   fail:0   skip:27  time:532s
fi-pnv-d510      total:156  pass:113  dwarn:0   dfail:0   fail:0   skip:42 
fi-skl-6260u     total:289  pass:269  dwarn:0   dfail:0   fail:0   skip:20  time:458s
fi-skl-6600u     total:289  pass:262  dwarn:0   dfail:0   fail:0   skip:27  time:544s
fi-skl-6700hq    total:289  pass:263  dwarn:0   dfail:0   fail:0   skip:26  time:566s
fi-skl-6700k     total:289  pass:265  dwarn:0   dfail:0   fail:0   skip:24  time:524s
fi-skl-6770hq    total:289  pass:269  dwarn:0   dfail:0   fail:0   skip:20  time:493s
fi-skl-gvtdvm    total:289  pass:266  dwarn:0   dfail:0   fail:0   skip:23  time:465s
fi-snb-2520m     total:289  pass:250  dwarn:0   dfail:0   fail:0   skip:39  time:559s
fi-snb-2600      total:289  pass:249  dwarn:0   dfail:0   fail:0   skip:40  time:425s
Blacklisted hosts:
fi-cnl-y         total:289  pass:262  dwarn:0   dfail:0   fail:0   skip:27  time:572s

087c404bd6d56a52e0656ac7c79faa376c25b796 drm-tip: 2017y-11m-08d-15h-44m-06s UTC integration manifest
07487e664018 drm/i915/userptr: Add a flag to populate the userptr on creation
369db28de782 drm/i915/userptr: Probe existence of backing struct pages upon creation

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_7017/
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* ✓ Fi.CI.IGT: success for series starting with [1/2] drm/i915/userptr: Probe existence of backing struct pages upon creation
  2017-11-08 18:51 [PATCH 1/2] drm/i915/userptr: Probe existence of backing struct pages upon creation Chris Wilson
  2017-11-08 18:51 ` [PATCH 2/2] drm/i915/userptr: Add a flag to populate the userptr on creation Chris Wilson
  2017-11-08 19:25 ` ✓ Fi.CI.BAT: success for series starting with [1/2] drm/i915/userptr: Probe existence of backing struct pages upon creation Patchwork
@ 2017-11-08 20:49 ` Patchwork
  2017-11-09 16:10 ` [PATCH 1/2] " Tvrtko Ursulin
  3 siblings, 0 replies; 7+ messages in thread
From: Patchwork @ 2017-11-08 20:49 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

== Series Details ==

Series: series starting with [1/2] drm/i915/userptr: Probe existence of backing struct pages upon creation
URL   : https://patchwork.freedesktop.org/series/33449/
State : success

== Summary ==

Test perf:
        Subgroup polling:
                fail       -> PASS       (shard-hsw) fdo#102252 +1

fdo#102252 https://bugs.freedesktop.org/show_bug.cgi?id=102252

shard-hsw        total:2540 pass:1432 dwarn:1   dfail:0   fail:10  skip:1097 time:9310s

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_7017/shards.html
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 1/2] drm/i915/userptr: Probe existence of backing struct pages upon creation
  2017-11-08 18:51 [PATCH 1/2] drm/i915/userptr: Probe existence of backing struct pages upon creation Chris Wilson
                   ` (2 preceding siblings ...)
  2017-11-08 20:49 ` ✓ Fi.CI.IGT: " Patchwork
@ 2017-11-09 16:10 ` Tvrtko Ursulin
  2017-11-09 16:22   ` Chris Wilson
  3 siblings, 1 reply; 7+ messages in thread
From: Tvrtko Ursulin @ 2017-11-09 16:10 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx


On 08/11/2017 18:51, Chris Wilson wrote:
> Jason Ekstrand requested a more efficient method than userptr+set-domain
> to determine if the userptr object was backed by a complete set of pages
> upon creation. To be more efficient than simply populating the userptr
> using get_user_pages() (as done by the call to set-domain or execbuf),
> we can walk the tree of vm_area_struct and check for gaps or vma not
> backed by struct page (VM_PFNMAP). The question is how to handle
> VM_MIXEDMAP which may be either struct page or pfn backed...

First reaction is that it sounds like a bad idea. Well maybe not bad, 
but a bit questionable since if the userspace doesn't know, then there 
are no guarantees the result of probe will remain valid until the time 
to actually instantiate the backing store comes.

The populate idea from the next patch sounds okay on the other hand. So 
is there an use case where extremely controlling userspace would benefit 
from probe rather than just using populate?

Regards,

Tvrtko

> 
> Testcase: igt/gem_userptr_blits/probe
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
> Cc: Michał Winiarski <michal.winiarski@intel.com>
> Cc: Jason Ekstrand <jason@jlekstrand.net>
> ---
>   drivers/gpu/drm/i915/i915_gem_userptr.c | 38 +++++++++++++++++++++++++++++++++
>   include/uapi/drm/i915_drm.h             |  5 +++--
>   2 files changed, 41 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c
> index e26b23171b56..dbc5818dd28b 100644
> --- a/drivers/gpu/drm/i915/i915_gem_userptr.c
> +++ b/drivers/gpu/drm/i915/i915_gem_userptr.c
> @@ -719,6 +719,33 @@ static const struct drm_i915_gem_object_ops i915_gem_userptr_ops = {
>   	.release = i915_gem_userptr_release,
>   };
>   
> +static int
> +probe_range(struct mm_struct *mm, unsigned long addr, unsigned long len)
> +{
> +	const unsigned long end = addr + len;
> +	struct vm_area_struct *vma;
> +	int ret = -EFAULT;
> +
> +	down_read(&mm->mmap_sem);
> +	for (vma = find_vma(mm, addr); vma; vma = vma->vm_next) {
> +		if (vma->vm_start > addr)
> +			break;
> +
> +		if (vma->vm_flags & (VM_PFNMAP | VM_MIXEDMAP))
> +			break;
> +
> +		if (vma->vm_end >= end) {
> +			ret = 0;
> +			break;
> +		}
> +
> +		addr = vma->vm_end;
> +	}
> +	up_read(&mm->mmap_sem);
> +
> +	return ret;
> +}
> +
>   /**
>    * Creates a new mm object that wraps some normal memory from the process
>    * context - user memory.
> @@ -771,6 +798,7 @@ i915_gem_userptr_ioctl(struct drm_device *dev, void *data, struct drm_file *file
>   	}
>   
>   	if (args->flags & ~(I915_USERPTR_READ_ONLY |
> +			    I915_USERPTR_PROBE |
>   			    I915_USERPTR_UNSYNCHRONIZED))
>   		return -EINVAL;
>   
> @@ -788,6 +816,16 @@ i915_gem_userptr_ioctl(struct drm_device *dev, void *data, struct drm_file *file
>   		return -ENODEV;
>   	}
>   
> +	if (args->flags & I915_USERPTR_PROBE) {
> +		/*
> +		 * Check that the range pointed to represents real struct
> +		 * pages and not iomappings (at this moment in time!)
> +		 */
> +		ret = probe_range(current->mm, args->user_ptr, args->user_size);
> +		if (ret)
> +			return ret;
> +	}
> +
>   	obj = i915_gem_object_alloc(dev_priv);
>   	if (obj == NULL)
>   		return -ENOMEM;
> diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
> index ac3c6503ca27..392ede2ca63e 100644
> --- a/include/uapi/drm/i915_drm.h
> +++ b/include/uapi/drm/i915_drm.h
> @@ -1352,8 +1352,9 @@ struct drm_i915_gem_userptr {
>   	__u64 user_ptr;
>   	__u64 user_size;
>   	__u32 flags;
> -#define I915_USERPTR_READ_ONLY 0x1
> -#define I915_USERPTR_UNSYNCHRONIZED 0x80000000
> +#define I915_USERPTR_READ_ONLY		0x1
> +#define I915_USERPTR_PROBE		0x2
> +#define I915_USERPTR_UNSYNCHRONIZED	0x80000000
>   	/**
>   	 * Returned handle for the object.
>   	 *
> 
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 1/2] drm/i915/userptr: Probe existence of backing struct pages upon creation
  2017-11-09 16:10 ` [PATCH 1/2] " Tvrtko Ursulin
@ 2017-11-09 16:22   ` Chris Wilson
  0 siblings, 0 replies; 7+ messages in thread
From: Chris Wilson @ 2017-11-09 16:22 UTC (permalink / raw)
  To: Tvrtko Ursulin, intel-gfx

Quoting Tvrtko Ursulin (2017-11-09 16:10:47)
> 
> On 08/11/2017 18:51, Chris Wilson wrote:
> > Jason Ekstrand requested a more efficient method than userptr+set-domain
> > to determine if the userptr object was backed by a complete set of pages
> > upon creation. To be more efficient than simply populating the userptr
> > using get_user_pages() (as done by the call to set-domain or execbuf),
> > we can walk the tree of vm_area_struct and check for gaps or vma not
> > backed by struct page (VM_PFNMAP). The question is how to handle
> > VM_MIXEDMAP which may be either struct page or pfn backed...
> 
> First reaction is that it sounds like a bad idea. Well maybe not bad, 
> but a bit questionable since if the userspace doesn't know, then there 
> are no guarantees the result of probe will remain valid until the time 
> to actually instantiate the backing store comes.
> 
> The populate idea from the next patch sounds okay on the other hand. So 
> is there an use case where extremely controlling userspace would benefit 
> from probe rather than just using populate?

Populate has exactly the same inconsistency as probe. Neither is
absolute and the answer may change before use. The advantage for
userspace is in the question of whether it can reject bad calls before
committing itself. For which it currently uses set-domain after userptr.

From the pov of the code, doing the populate early is a synchronous
operations, but a late populate can be done asynchronously in parallel
to the client preparing the next request.

However, since userspace already has the controls to do a populate
itself, the only real improvement here is in a cheap probe.
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

end of thread, other threads:[~2017-11-09 16:22 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-11-08 18:51 [PATCH 1/2] drm/i915/userptr: Probe existence of backing struct pages upon creation Chris Wilson
2017-11-08 18:51 ` [PATCH 2/2] drm/i915/userptr: Add a flag to populate the userptr on creation Chris Wilson
2017-11-08 19:05   ` Jason Ekstrand
2017-11-08 19:25 ` ✓ Fi.CI.BAT: success for series starting with [1/2] drm/i915/userptr: Probe existence of backing struct pages upon creation Patchwork
2017-11-08 20:49 ` ✓ Fi.CI.IGT: " Patchwork
2017-11-09 16:10 ` [PATCH 1/2] " Tvrtko Ursulin
2017-11-09 16:22   ` Chris Wilson

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.