[PATCH v4 19/19] drm/i915: Add fault injection support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Add support for forcing an error at selected places in the driver. As an
example add 4 options to fail during driver loading.

Requested by Chris.

v2:
- Add fault point for modeset initialization
- Print debug message when injecting an error
v3:
- Rename inject_fault to inject_load_failure, rename the related macros
  and helper accordingly (Chris)
- Use a counter instead of a mask to identify the failure point (Daniel)
- Mark the module option as _unsafe and keep i915_params ordered (Joonas)
v4:
- Rebase on latest -nightly

CC: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx>
CC: Daniel Vetter <daniel.vetter@xxxxxxxx>
CC: Joonas Lahtinen <joonas.lahtinen@xxxxxxxxxxxxxxx>
Signed-off-by: Imre Deak <imre.deak@xxxxxxxxx>
---
 drivers/gpu/drm/i915/i915_dma.c    | 27 +++++++++++++++++++++++++++
 drivers/gpu/drm/i915/i915_drv.h    |  4 ++++
 drivers/gpu/drm/i915/i915_params.c |  4 ++++
 drivers/gpu/drm/i915/i915_params.h |  1 +
 4 files changed, 36 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index cbbcada..8b9ac44 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -50,6 +50,21 @@
 #include <linux/pm_runtime.h>
 #include <linux/oom.h>
 
+static unsigned int i915_load_fail_count;
+
+bool __i915_inject_load_failure(const char *func, int line)
+{
+	if (i915_load_fail_count >= i915.inject_load_failure)
+		return false;
+
+	if (++i915_load_fail_count == i915.inject_load_failure) {
+		DRM_DEBUG_DRIVER("Injecting failure at checkpoint %u [%s:%d]\n",
+				 i915.inject_load_failure, func, line);
+		return true;
+	}
+
+	return false;
+}
 
 static int i915_getparam(struct drm_device *dev, void *data,
 			 struct drm_file *file_priv)
@@ -370,6 +385,9 @@ static int i915_load_modeset_init(struct drm_device *dev)
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	int ret;
 
+	if (i915_inject_load_failure())
+		return -ENODEV;
+
 	ret = intel_bios_init(dev_priv);
 	if (ret)
 		DRM_INFO("failed to find VBIOS tables\n");
@@ -951,6 +969,9 @@ static int i915_driver_init_early(struct drm_i915_private *dev_priv,
 	struct intel_device_info *device_info;
 	int ret = 0;
 
+	if (i915_inject_load_failure())
+		return -ENODEV;
+
 	dev_priv->dev = dev;
 
 	/* Setup the write-once "constant" device info */
@@ -1065,6 +1086,9 @@ static int i915_driver_init_mmio(struct drm_i915_private *dev_priv)
 	struct drm_device *dev = dev_priv->dev;
 	int ret;
 
+	if (i915_inject_load_failure())
+		return -ENODEV;
+
 	if (i915_get_bridge_dev(dev))
 		return -EIO;
 
@@ -1108,6 +1132,9 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv)
 	uint32_t aperture_size;
 	int ret;
 
+	if (i915_inject_load_failure())
+		return -ENODEV;
+
 	intel_device_info_runtime_init(dev);
 
 	ret = i915_gem_gtt_init(dev);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 180cae0..a518525 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -98,6 +98,10 @@
 #define I915_STATE_WARN_ON(x)						\
 	I915_STATE_WARN((x), "%s", "WARN_ON(" __stringify(x) ")")
 
+bool __i915_inject_load_failure(const char *func, int line);
+#define i915_inject_load_failure() \
+	__i915_inject_load_failure(__func__, __LINE__)
+
 static inline const char *yesno(bool v)
 {
 	return v ? "yes" : "no";
diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c
index 97691f1..1779f02 100644
--- a/drivers/gpu/drm/i915/i915_params.c
+++ b/drivers/gpu/drm/i915/i915_params.c
@@ -57,6 +57,7 @@ struct i915_params i915 __read_mostly = {
 	.enable_guc_submission = false,
 	.guc_log_level = -1,
 	.enable_dp_mst = true,
+	.inject_load_failure = 0,
 };
 
 module_param_named(modeset, i915.modeset, int, 0400);
@@ -206,3 +207,6 @@ MODULE_PARM_DESC(guc_log_level,
 module_param_named_unsafe(enable_dp_mst, i915.enable_dp_mst, bool, 0600);
 MODULE_PARM_DESC(enable_dp_mst,
 	"Enable multi-stream transport (MST) for new DisplayPort sinks. (default: true)");
+module_param_named_unsafe(inject_load_failure, i915.inject_load_failure, uint, 0400);
+MODULE_PARM_DESC(inject_load_failure,
+	"Force an error after a number of failure check points (0:disabled (default), N:force failure at the Nth failure check point)");
diff --git a/drivers/gpu/drm/i915/i915_params.h b/drivers/gpu/drm/i915/i915_params.h
index 87153b0..02bc278 100644
--- a/drivers/gpu/drm/i915/i915_params.h
+++ b/drivers/gpu/drm/i915/i915_params.h
@@ -49,6 +49,7 @@ struct i915_params {
 	int use_mmio_flip;
 	int mmio_debug;
 	int edp_vswing;
+	unsigned int inject_load_failure;
 	/* leave bools at the end to not create holes */
 	bool enable_hangcheck;
 	bool fastboot;
-- 
2.5.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@xxxxxxxxxxxxxxxxxxxxx
https://lists.freedesktop.org/mailman/listinfo/intel-gfx




[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]
  Powered by Linux