[PATCH 39/54] fast-busy-ioctl
Chris Wilson
chris at chris-wilson.co.uk
Sun Jun 4 12:08:22 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 | 57 +++++++++++++++++++++++++++--------------
3 files changed, 42 insertions(+), 22 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 02aa34470531..3efba9ccb0dc 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -2549,7 +2549,7 @@ static const struct drm_ioctl_desc i915_ioctls[] = {
DRM_IOCTL_DEF_DRV(I915_GEM_EXECBUFFER2_WR, i915_gem_execbuffer2, DRM_AUTH|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(I915_GEM_PIN, i915_gem_reject_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY),
DRM_IOCTL_DEF_DRV(I915_GEM_UNPIN, i915_gem_reject_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF_DRV(I915_GEM_BUSY, i915_gem_busy_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
+ DRM_DRIVER_IOCTL_DEF(I915_GEM_BUSY, i915_gem_busy_ioctl, DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(I915_GEM_SET_CACHING, i915_gem_set_caching_ioctl, DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(I915_GEM_GET_CACHING, i915_gem_get_caching_ioctl, DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(I915_GEM_THROTTLE, i915_gem_throttle_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 2784592384a2..f93312e830c9 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -3206,8 +3206,9 @@ int i915_gem_execbuffer(struct drm_device *dev, void *data,
struct drm_file *file_priv);
int i915_gem_execbuffer2(struct drm_device *dev, void *data,
struct drm_file *file_priv);
-int i915_gem_busy_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv);
+long i915_gem_busy_ioctl(struct file *filp,
+ unsigned int cmd,
+ unsigned long arg);
int i915_gem_get_caching_ioctl(struct drm_device *dev, void *data,
struct drm_file *file);
int i915_gem_set_caching_ioctl(struct drm_device *dev, void *data,
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index d2b75f91554e..4ddfee765e2f 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -4138,21 +4138,31 @@ busy_check_writer(const struct dma_fence *fence)
return __busy_set_if_active(fence, __busy_write_id);
}
-int
-i915_gem_busy_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file)
+long i915_gem_busy_ioctl(struct file *filp,
+ unsigned int cmd,
+ unsigned long iarg)
{
- struct drm_i915_gem_busy *args = data;
+ struct drm_i915_gem_busy __user *arg = (typeof(arg))iarg;
struct drm_i915_gem_object *obj;
+ struct reservation_object *resv;
struct reservation_object_list *list;
unsigned int seq;
- int err;
+ u32 handle;
+ u32 busy;
+
+ if (unlikely(!access_ok(VERIFY_WRITE, arg, sizeof(*arg))))
+ goto err_user;
+
+ user_access_begin();
+ unsafe_get_user(handle, &arg->handle, err_user);
+ user_access_end();
- err = -ENOENT;
rcu_read_lock();
- obj = i915_gem_object_lookup_rcu(file, args->handle);
- if (!obj)
- goto out;
+ obj = i915_gem_object_lookup_rcu(filp->private_data, handle);
+ if (unlikely(!obj))
+ goto err_obj;
+
+ resv = obj->resv;
/* A discrepancy here is that we do not report the status of
* non-i915 fences, i.e. even though we may report the object as idle,
@@ -4165,19 +4175,18 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data,
*
* Alternatively, we can trade that extra information on read/write
* activity with
- * args->busy =
- * !reservation_object_test_signaled_rcu(obj->resv, true);
+ * busy = !reservation_object_test_signaled_rcu(obj->resv, true);
* to report the overall busyness. This is what the wait-ioctl does.
*
*/
retry:
- seq = raw_read_seqcount(&obj->resv->seq);
+ seq = raw_read_seqcount(&resv->seq);
/* Translate the exclusive fence to the READ *and* WRITE engine */
- args->busy = busy_check_writer(rcu_dereference(obj->resv->fence_excl));
+ busy = busy_check_writer(rcu_dereference(resv->fence_excl));
/* Translate shared fences to READ set of engines */
- list = rcu_dereference(obj->resv->fence);
+ list = rcu_dereference(resv->fence);
if (list) {
unsigned int shared_count = list->shared_count, i;
@@ -4185,17 +4194,27 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data,
struct dma_fence *fence =
rcu_dereference(list->shared[i]);
- args->busy |= busy_check_reader(fence);
+ busy |= busy_check_reader(fence);
}
}
- if (args->busy && read_seqcount_retry(&obj->resv->seq, seq))
+ if (busy && read_seqcount_retry(&resv->seq, seq))
goto retry;
- err = 0;
-out:
rcu_read_unlock();
- return err;
+
+ user_access_begin();
+ unsafe_put_user(busy, &arg->busy, err_user);
+ user_access_end();
+ return 0;
+
+err_user:
+ user_access_end();
+ return -EFAULT;
+
+err_obj:
+ rcu_read_unlock();
+ return -ENOENT;
}
int
--
2.11.0
More information about the Intel-gfx-trybot
mailing list