mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-01-19 02:56:15 +07:00
drm/i915: add error_state sysfs entry
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> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> [danvet: Apply Chris' s/error_state/error/ bikeshed on the sysfs name. Also update the dmesg message, spotted by Chris.] Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This commit is contained in:
parent
4dc955f7f5
commit
ef86ddced7
@ -1921,8 +1921,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\n", dev->primary->index);
|
||||
|
||||
kref_init(&error->ref);
|
||||
error->eir = I915_READ(EIR);
|
||||
|
@ -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",
|
||||
.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
|
||||
|
Loading…
Reference in New Issue
Block a user