[Intel-gfx] [PATCH] drm/i915: optionally ban context on first hang

Mika Kuoppala mika.kuoppala at linux.intel.com
Tue Sep 10 15:16:50 CEST 2013


Current policy is to ban context if it manages to hang
gpu in a certain time windows. Paul Berry asked if more
strict policy could be available for use cases where
the application doesn't know if the rendering command stream
sent to gpu is valid or not.

Provide an option, flag on context creation time, to let
userspace to set more strict policy for handling gpu hangs for
this context. If context with this flag set ever hangs the gpu,
it will be permanently banned from accessing the GPU.
All subsequent batch submissions will return -EIO.

Requested-by: Paul Berry <stereotype441 at gmail.com>
Cc: Paul Berry <stereotype441 at gmail.com>
Cc: Ben Widawsky <ben at bwidawsk.net>
Signed-off-by: Mika Kuoppala <mika.kuoppala at intel.com>
---
 drivers/gpu/drm/i915/i915_dma.c         |    3 +++
 drivers/gpu/drm/i915/i915_drv.h         |    3 +++
 drivers/gpu/drm/i915/i915_gem.c         |    9 ++++++++-
 drivers/gpu/drm/i915/i915_gem_context.c |   12 +++++++++---
 include/uapi/drm/i915_drm.h             |    5 +++++
 5 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 3de6050..4353458 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -1003,6 +1003,9 @@ static int i915_getparam(struct drm_device *dev, void *data,
 	case I915_PARAM_HAS_EXEC_HANDLE_LUT:
 		value = 1;
 		break;
+	case I915_PARAM_HAS_CONTEXT_BAN:
+		value = 1;
+		break;
 	default:
 		DRM_DEBUG("Unknown parameter %d\n", param->param);
 		return -EINVAL;
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 81ba5bb..9cf7050 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -594,6 +594,9 @@ struct i915_ctx_hang_stats {
 
 	/* This context is banned to submit more work */
 	bool banned;
+
+	/* Instead of default period based ban policy, ban on first hang */
+	bool ban_on_first;
 };
 
 /* This must match up with the value previously used for execbuf2.rsvd1. */
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 04e810c..9feaafd2 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2190,11 +2190,18 @@ static bool i915_request_guilty(struct drm_i915_gem_request *request,
 
 static bool i915_context_is_banned(const struct i915_ctx_hang_stats *hs)
 {
-	const unsigned long elapsed = get_seconds() - hs->guilty_ts;
+	unsigned long elapsed;
 
 	if (hs->banned)
 		return true;
 
+	if (hs->ban_on_first) {
+		DRM_ERROR("context banned on first hang!\n");
+		return true;
+	}
+
+	elapsed = get_seconds() - hs->guilty_ts;
+
 	if (elapsed <= DRM_I915_CTX_BAN_PERIOD) {
 		DRM_ERROR("context hanging too fast, declaring banned!\n");
 		return true;
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index 26c3fcc..8baa1d0 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -135,7 +135,8 @@ void i915_gem_context_free(struct kref *ctx_ref)
 
 static struct i915_hw_context *
 create_hw_context(struct drm_device *dev,
-		  struct drm_i915_file_private *file_priv)
+		  struct drm_i915_file_private *file_priv,
+		  const u64 flags)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct i915_hw_context *ctx;
@@ -178,6 +179,7 @@ create_hw_context(struct drm_device *dev,
 
 	ctx->file_priv = file_priv;
 	ctx->id = ret;
+	ctx->hang_stats.ban_on_first = !!(flags & I915_CONTEXT_BAN_ON_HANG);
 
 	return ctx;
 
@@ -203,7 +205,7 @@ static int create_default_context(struct drm_i915_private *dev_priv)
 
 	BUG_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex));
 
-	ctx = create_hw_context(dev_priv->dev, NULL);
+	ctx = create_hw_context(dev_priv->dev, NULL, 0);
 	if (IS_ERR(ctx))
 		return PTR_ERR(ctx);
 
@@ -520,11 +522,15 @@ int i915_gem_context_create_ioctl(struct drm_device *dev, void *data,
 	if (dev_priv->hw_contexts_disabled)
 		return -ENODEV;
 
+	if (args->flags & __I915_CONTEXT_UNKNOWN_FLAGS)
+		return -EINVAL;
+
 	ret = i915_mutex_lock_interruptible(dev);
 	if (ret)
 		return ret;
 
-	ctx = create_hw_context(dev, file_priv);
+	ctx = create_hw_context(dev, file_priv, args->flags);
+
 	mutex_unlock(&dev->struct_mutex);
 	if (IS_ERR(ctx))
 		return PTR_ERR(ctx);
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index 55bb572..a020454 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -335,6 +335,7 @@ typedef struct drm_i915_irq_wait {
 #define I915_PARAM_HAS_EXEC_NO_RELOC	 25
 #define I915_PARAM_HAS_EXEC_HANDLE_LUT   26
 #define I915_PARAM_HAS_WT     	 	 27
+#define I915_PARAM_HAS_CONTEXT_BAN	 28
 
 typedef struct drm_i915_getparam {
 	int param;
@@ -1015,10 +1016,14 @@ struct drm_i915_gem_wait {
 	__s64 timeout_ns;
 };
 
+#define I915_CONTEXT_BAN_ON_HANG  (1 << 0)
+#define __I915_CONTEXT_UNKNOWN_FLAGS -(I915_CONTEXT_BAN_ON_HANG<<1)
+
 struct drm_i915_gem_context_create {
 	/*  output: id of new context*/
 	__u32 ctx_id;
 	__u32 pad;
+	__u64 flags;
 };
 
 struct drm_i915_gem_context_destroy {
-- 
1.7.9.5




More information about the Intel-gfx mailing list