[PATCH 61/74] fast-busy-ioctl

Chris Wilson chris at chris-wilson.co.uk
Thu Sep 14 17:34:35 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 c4b00a883d5f..04eaa7891116 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -2653,7 +2653,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 b0c752c59c46..47d3dafe0019 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -3414,8 +3414,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 cd2f81ac7380..79cd8ce54665 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -4279,21 +4279,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,
@@ -4306,19 +4316,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;
 
@@ -4326,17 +4335,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.14.1



More information about the Intel-gfx-trybot mailing list