[PATCH 40/54] fast-context-get-stats

Chris Wilson chris at chris-wilson.co.uk
Sun Jun 4 12:08:23 UTC 2017


---
 drivers/gpu/drm/i915/i915_drv.c         |  2 +-
 drivers/gpu/drm/i915/i915_gem_context.c | 61 +++++++++++++++++++++------------
 drivers/gpu/drm/i915/i915_gem_context.h |  5 +--
 3 files changed, 44 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 3efba9ccb0dc..fe22c71c9c6a 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -2575,7 +2575,7 @@ static const struct drm_ioctl_desc i915_ioctls[] = {
 	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),
-	DRM_IOCTL_DEF_DRV(I915_GET_RESET_STATS, i915_gem_context_reset_stats_ioctl, DRM_RENDER_ALLOW),
+	DRM_DRIVER_IOCTL_DEF(I915_GET_RESET_STATS, i915_gem_context_reset_stats_ioctl, DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF_DRV(I915_GEM_USERPTR, i915_gem_userptr_ioctl, DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_GETPARAM, i915_gem_context_getparam_ioctl, DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_SETPARAM, i915_gem_context_setparam_ioctl, DRM_RENDER_ALLOW),
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index 9df86b94d052..7dcab1f51316 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -1157,25 +1157,32 @@ int i915_gem_context_setparam_ioctl(struct drm_device *dev, void *data,
 	return ret;
 }
 
-int i915_gem_context_reset_stats_ioctl(struct drm_device *dev,
-				       void *data, struct drm_file *file)
+long i915_gem_context_reset_stats_ioctl(struct file *filp,
+					unsigned int cmd,
+					unsigned long data)
 {
-	struct drm_i915_private *dev_priv = to_i915(dev);
-	struct drm_i915_reset_stats *args = data;
+	struct drm_i915_reset_stats __user *user = (typeof(user))data;
+	struct drm_file *file = filp->private_data;
+	struct drm_i915_reset_stats stats;
 	struct i915_gem_context *ctx;
-	int ret;
 
-	if (args->flags || args->pad)
-		return -EINVAL;
+	if (unlikely(!access_ok(VERIFY_WRITE, user, sizeof(*user))))
+		return -EFAULT;
+
+	user_access_begin();
+	unsafe_get_user(stats.flags, &user->flags, err_user);
+	unsafe_get_user(stats.pad, &user->pad, err_user);
+	unsafe_get_user(stats.ctx_id, &user->ctx_id, err_user);
+	user_access_end();
 
-	if (args->ctx_id == DEFAULT_CONTEXT_HANDLE && !capable(CAP_SYS_ADMIN))
-		return -EPERM;
+	if (unlikely(stats.flags | stats.pad))
+		goto err_invalid;
 
-	ret = -ENOENT;
 	rcu_read_lock();
-	ctx = __i915_gem_context_lookup_rcu(file->driver_priv, args->ctx_id);
-	if (!ctx)
-		goto out;
+
+	ctx = __i915_gem_context_lookup_rcu(file->driver_priv, stats.ctx_id);
+	if (unlikely(!ctx))
+		goto err_ctx;
 
 	/*
 	 * We opt for unserialised reads here. This may result in tearing
@@ -1184,18 +1191,30 @@ int i915_gem_context_reset_stats_ioctl(struct drm_device *dev,
 	 * we should wrap the hangstats with a seqlock.
 	 */
 
+	stats.reset_count = 0;
 	if (capable(CAP_SYS_ADMIN))
-		args->reset_count = i915_reset_count(&dev_priv->gpu_error);
-	else
-		args->reset_count = 0;
+		stats.reset_count = i915_reset_count(&ctx->i915->gpu_error);
+	stats.batch_active = READ_ONCE(ctx->guilty_count);
+	stats.batch_pending = READ_ONCE(ctx->active_count);
 
-	args->batch_active = READ_ONCE(ctx->guilty_count);
-	args->batch_pending = READ_ONCE(ctx->active_count);
+	rcu_read_unlock();
 
-	ret = 0;
-out:
+	user_access_begin();
+	unsafe_put_user(stats.reset_count, &user->reset_count, err_user);
+	unsafe_put_user(stats.batch_active, &user->batch_active, err_user);
+	unsafe_put_user(stats.batch_pending, &user->batch_pending, err_user);
+	user_access_end();
+	return 0;
+
+err_ctx:
 	rcu_read_unlock();
-	return ret;
+	return -ENOENT;
+err_user:
+	user_access_end();
+	return -EFAULT;
+err_invalid:
+	user_access_end();
+	return -EINVAL;
 }
 
 #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
diff --git a/drivers/gpu/drm/i915/i915_gem_context.h b/drivers/gpu/drm/i915/i915_gem_context.h
index 162125977b11..f2b3ef742734 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.h
+++ b/drivers/gpu/drm/i915/i915_gem_context.h
@@ -285,8 +285,9 @@ int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data,
 				    struct drm_file *file_priv);
 int i915_gem_context_setparam_ioctl(struct drm_device *dev, void *data,
 				    struct drm_file *file_priv);
-int i915_gem_context_reset_stats_ioctl(struct drm_device *dev, void *data,
-				       struct drm_file *file);
+long i915_gem_context_reset_stats_ioctl(struct file *filp,
+					unsigned int cmd,
+					unsigned long arg);
 
 static inline struct i915_gem_context *
 i915_gem_context_get(struct i915_gem_context *ctx)
-- 
2.11.0



More information about the Intel-gfx-trybot mailing list