[PATCH 65/74] fast-wait-ioctl
Chris Wilson
chris at chris-wilson.co.uk
Thu Sep 14 17:34:39 UTC 2017
---
drivers/gpu/drm/i915/i915_drv.c | 2 +-
drivers/gpu/drm/i915/i915_drv.h | 5 ++--
drivers/gpu/drm/i915/i915_gem.c | 52 +++++++++++++++++++++++++++++------------
3 files changed, 41 insertions(+), 18 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 8ce60f1e4ee6..34d188320710 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -2675,7 +2675,7 @@ static const struct drm_ioctl_desc i915_ioctls[] = {
DRM_IOCTL_DEF_DRV(I915_OVERLAY_ATTRS, intel_overlay_attrs_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW),
DRM_IOCTL_DEF_DRV(I915_SET_SPRITE_COLORKEY, intel_sprite_set_colorkey, DRM_MASTER|DRM_CONTROL_ALLOW),
DRM_IOCTL_DEF_DRV(I915_GET_SPRITE_COLORKEY, drm_noop, DRM_MASTER|DRM_CONTROL_ALLOW),
- DRM_IOCTL_DEF_DRV(I915_GEM_WAIT, i915_gem_wait_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
+ DRM_DRIVER_IOCTL_DEF(I915_GEM_WAIT, i915_gem_wait_ioctl, DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_CREATE, i915_gem_context_create_ioctl, DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_DESTROY, i915_gem_context_destroy_ioctl, DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(I915_REG_READ, i915_reg_read_ioctl, DRM_RENDER_ALLOW),
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 02545eb0c07f..52ef3089bb13 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -3437,8 +3437,9 @@ int i915_gem_userptr_ioctl(struct drm_device *dev, void *data,
struct drm_file *file);
int i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
-int i915_gem_wait_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv);
+long i915_gem_wait_ioctl(struct file *filp,
+ unsigned int cmd,
+ unsigned long data);
void i915_gem_sanitize(struct drm_i915_private *i915);
int i915_gem_load_init(struct drm_i915_private *dev_priv);
void i915_gem_load_cleanup(struct drm_i915_private *dev_priv);
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 4264f65fc06c..c0589772e83f 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -3421,32 +3421,45 @@ static unsigned long to_wait_timeout(s64 timeout_ns)
* function completes. A similar but shorter * race condition exists in the busy
* ioctl
*/
-int
-i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
+long
+i915_gem_wait_ioctl(struct file *filp,
+ unsigned int cmd,
+ unsigned long data)
{
- struct drm_i915_gem_wait *args = data;
+ struct drm_i915_gem_wait __user *user = (typeof(user))data;
+ struct drm_file *file = filp->private_data;
struct drm_i915_gem_object *obj;
+ struct drm_i915_gem_wait arg;
ktime_t start;
- long ret;
+ int ret;
+
+ if (unlikely(!access_ok(VERIFY_WRITE, user, sizeof(*user))))
+ return -EFAULT;
- if (args->flags != 0)
+ user_access_begin();
+ unsafe_get_user(arg.bo_handle, &user->bo_handle, err_user);
+ unsafe_get_user(arg.flags, &user->flags, err_user);
+ unsafe_get_user(arg.timeout_ns, &user->timeout_ns, err_user);
+ user_access_end();
+
+ if (unlikely(arg.flags))
return -EINVAL;
- obj = i915_gem_object_lookup(file, args->bo_handle);
- if (!obj)
+ obj = i915_gem_object_lookup(file, arg.bo_handle);
+ if (unlikely(!obj))
return -ENOENT;
start = ktime_get();
ret = i915_gem_object_wait(obj,
I915_WAIT_INTERRUPTIBLE | I915_WAIT_ALL,
- to_wait_timeout(args->timeout_ns),
+ to_wait_timeout(arg.timeout_ns),
to_rps_client(file));
- if (args->timeout_ns > 0) {
- args->timeout_ns -= ktime_to_ns(ktime_sub(ktime_get(), start));
- if (args->timeout_ns < 0)
- args->timeout_ns = 0;
+ if (arg.timeout_ns > 0) {
+ arg.timeout_ns -= ktime_to_ns(ktime_sub(ktime_get(), start));
+ if (arg.timeout_ns < 0)
+ arg.timeout_ns = 0;
/*
* Apparently ktime isn't accurate enough and occasionally has a
@@ -3455,16 +3468,25 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
*
* This is a regression from the timespec->ktime conversion.
*/
- if (ret == -ETIME && !nsecs_to_jiffies(args->timeout_ns))
- args->timeout_ns = 0;
+ if (ret == -ETIME && !nsecs_to_jiffies(arg.timeout_ns))
+ arg.timeout_ns = 0;
/* Asked to wait beyond the jiffie/scheduler precision? */
- if (ret == -ETIME && args->timeout_ns)
+ if (ret == -ETIME && arg.timeout_ns)
ret = -EAGAIN;
}
i915_gem_object_put(obj);
+
+ user_access_begin();
+ unsafe_put_user(arg.timeout_ns, &user->timeout_ns, err_user);
+ user_access_end();
+
return ret;
+
+err_user:
+ user_access_end();
+ return -EFAULT;
}
static int wait_for_timeline(struct i915_gem_timeline *tl, unsigned int flags)
--
2.14.1
More information about the Intel-gfx-trybot
mailing list