diff mbox

[4/4] drm/i915: add error_state sysfs entry

Message ID 1370529534-4573-1-git-send-email-mika.kuoppala@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Mika Kuoppala June 6, 2013, 2:38 p.m. UTC
As getting error state doesn't anymore require big kmallocs,
make error state accessible also from sysfs.

v2: - error state clearing (Chris Wilson)
    - user hint, proper access mode bits and name (Daniel Vetter)

v3: release resources in proper order (Chris Wilson)

Suggested-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com>
---
 drivers/gpu/drm/i915/i915_irq.c   |    3 +-
 drivers/gpu/drm/i915/i915_sysfs.c |   71 +++++++++++++++++++++++++++++++++++++
 2 files changed, 72 insertions(+), 2 deletions(-)

Comments

Chris Wilson July 1, 2013, 4:19 p.m. UTC | #1
On Thu, Jun 06, 2013 at 05:38:54PM +0300, Mika Kuoppala wrote:
> As getting error state doesn't anymore require big kmallocs,
> make error state accessible also from sysfs.
> 
> v2: - error state clearing (Chris Wilson)
>     - user hint, proper access mode bits and name (Daniel Vetter)
> 
> v3: release resources in proper order (Chris Wilson)
> 
> Suggested-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com>

I am happy overall here. We could take the plunge and use this as an
excuse to move all the error-state string handling into a new file,
which would be useful for when we pull the hangcheck mechanism out of
i915_irq.c.

Perhaps the more pressing bikeshed is that after years of
i915_error_state, I'm tired of the name and think that the 'state' was
just redundant, so perhaps '/sys/class/drm/card0/error' is a nice
minimalist and modern looking name.
-Chris
Daniel Vetter July 1, 2013, 4:56 p.m. UTC | #2
On Mon, Jul 01, 2013 at 05:19:59PM +0100, Chris Wilson wrote:
> On Thu, Jun 06, 2013 at 05:38:54PM +0300, Mika Kuoppala wrote:
> > As getting error state doesn't anymore require big kmallocs,
> > make error state accessible also from sysfs.
> > 
> > v2: - error state clearing (Chris Wilson)
> >     - user hint, proper access mode bits and name (Daniel Vetter)
> > 
> > v3: release resources in proper order (Chris Wilson)
> > 
> > Suggested-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> > Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com>
> 
> I am happy overall here. We could take the plunge and use this as an
> excuse to move all the error-state string handling into a new file,
> which would be useful for when we pull the hangcheck mechanism out of
> i915_irq.c.
> 
> Perhaps the more pressing bikeshed is that after years of
> i915_error_state, I'm tired of the name and think that the 'state' was
> just redundant, so perhaps '/sys/class/drm/card0/error' is a nice
> minimalist and modern looking name.

Series merged with this bikeshed applied and your r-b from irc added.

Thanks, Daniel
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 63996aa..22ed519 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -1881,8 +1881,7 @@  static void i915_capture_error_state(struct drm_device *dev)
 	}
 
 	DRM_INFO("capturing error event; look for more information in "
-		 "/sys/kernel/debug/dri/%d/i915_error_state\n",
-		 dev->primary->index);
+		 "/sys/class/drm/card%d/error_state\n", dev->primary->index);
 
 	kref_init(&error->ref);
 	error->eir = I915_READ(EIR);
diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c
index 6875b56..ffaf5da 100644
--- a/drivers/gpu/drm/i915/i915_sysfs.c
+++ b/drivers/gpu/drm/i915/i915_sysfs.c
@@ -409,6 +409,71 @@  static const struct attribute *gen6_attrs[] = {
 	NULL,
 };
 
+static ssize_t error_state_read(struct file *filp, struct kobject *kobj,
+				struct bin_attribute *attr, char *buf,
+				loff_t off, size_t count)
+{
+
+	struct device *kdev = container_of(kobj, struct device, kobj);
+	struct drm_minor *minor = container_of(kdev, struct drm_minor, kdev);
+	struct drm_device *dev = minor->dev;
+	struct i915_error_state_file_priv error_priv;
+	struct drm_i915_error_state_buf error_str;
+	ssize_t ret_count = 0;
+	int ret;
+
+	memset(&error_priv, 0, sizeof(error_priv));
+
+	ret = i915_error_state_buf_init(&error_str, count, off);
+	if (ret)
+		return ret;
+
+	error_priv.dev = dev;
+	i915_error_state_get(dev, &error_priv);
+
+	ret = i915_error_state_to_str(&error_str, &error_priv);
+	if (ret)
+		goto out;
+
+	ret_count = count < error_str.bytes ? count : error_str.bytes;
+
+	memcpy(buf, error_str.buf, ret_count);
+out:
+	i915_error_state_put(&error_priv);
+	i915_error_state_buf_release(&error_str);
+
+	return ret ?: ret_count;
+}
+
+static ssize_t error_state_write(struct file *file, struct kobject *kobj,
+				 struct bin_attribute *attr, char *buf,
+				 loff_t off, size_t count)
+{
+	struct device *kdev = container_of(kobj, struct device, kobj);
+	struct drm_minor *minor = container_of(kdev, struct drm_minor, kdev);
+	struct drm_device *dev = minor->dev;
+	int ret;
+
+	DRM_DEBUG_DRIVER("Resetting error state\n");
+
+	ret = mutex_lock_interruptible(&dev->struct_mutex);
+	if (ret)
+		return ret;
+
+	i915_destroy_error_state(dev);
+	mutex_unlock(&dev->struct_mutex);
+
+	return count;
+}
+
+static struct bin_attribute error_state_attr = {
+	.attr.name = "error_state",
+	.attr.mode = S_IRUSR | S_IWUSR,
+	.size = 0,
+	.read = error_state_read,
+	.write = error_state_write,
+};
+
 void i915_setup_sysfs(struct drm_device *dev)
 {
 	int ret;
@@ -432,10 +497,16 @@  void i915_setup_sysfs(struct drm_device *dev)
 		if (ret)
 			DRM_ERROR("gen6 sysfs setup failed\n");
 	}
+
+	ret = sysfs_create_bin_file(&dev->primary->kdev.kobj,
+				    &error_state_attr);
+	if (ret)
+		DRM_ERROR("error_state sysfs setup failed\n");
 }
 
 void i915_teardown_sysfs(struct drm_device *dev)
 {
+	sysfs_remove_bin_file(&dev->primary->kdev.kobj, &error_state_attr);
 	sysfs_remove_files(&dev->primary->kdev.kobj, gen6_attrs);
 	device_remove_bin_file(&dev->primary->kdev,  &dpf_attrs);
 #ifdef CONFIG_PM