drivers/gpu/drm/i915/i915_gpu_error.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/i915/i915_gpu_error.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/i915/i915_gpu_error.c
Extension
.c
Size
66506 bytes
Lines
2623
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

static const struct file_operations i915_gpu_info_fops = {
	.owner = THIS_MODULE,
	.open = i915_gpu_info_open,
	.read = gpu_state_read,
	.llseek = default_llseek,
	.release = gpu_state_release,
};

static ssize_t
i915_error_state_write(struct file *filp,
		       const char __user *ubuf,
		       size_t cnt,
		       loff_t *ppos)
{
	struct i915_gpu_coredump *error = filp->private_data;

	if (!error)
		return 0;

	drm_dbg(&error->i915->drm, "Resetting error state\n");
	i915_reset_error_state(error->i915);

	return cnt;
}

static int i915_error_state_open(struct inode *inode, struct file *file)
{
	struct i915_gpu_coredump *error;

	error = i915_first_error_state(inode->i_private);
	if (IS_ERR(error))
		return PTR_ERR(error);

	file->private_data  = error;
	return 0;
}

static const struct file_operations i915_error_state_fops = {
	.owner = THIS_MODULE,
	.open = i915_error_state_open,
	.read = gpu_state_read,
	.write = i915_error_state_write,
	.llseek = default_llseek,
	.release = gpu_state_release,
};

void i915_gpu_error_debugfs_register(struct drm_i915_private *i915)
{
	struct dentry *debugfs_root = i915->drm.debugfs_root;

	debugfs_create_file("i915_error_state", 0644, debugfs_root, i915,
			    &i915_error_state_fops);
	debugfs_create_file("i915_gpu_info", 0644, debugfs_root, i915,
			    &i915_gpu_info_fops);
}

static ssize_t error_state_read(struct file *filp, struct kobject *kobj,
				const struct bin_attribute *attr, char *buf,
				loff_t off, size_t count)
{

	struct device *kdev = kobj_to_dev(kobj);
	struct drm_i915_private *i915 = kdev_minor_to_i915(kdev);
	struct i915_gpu_coredump *gpu;
	ssize_t ret = 0;

	/*
	 * FIXME: Concurrent clients triggering resets and reading + clearing
	 * dumps can cause inconsistent sysfs reads when a user calls in with a
	 * non-zero offset to complete a prior partial read but the
	 * gpu_coredump has been cleared or replaced.
	 */

	gpu = i915_first_error_state(i915);
	if (IS_ERR(gpu)) {
		ret = PTR_ERR(gpu);
	} else if (gpu) {
		ret = i915_gpu_coredump_copy_to_buffer(gpu, buf, off, count);
		i915_gpu_coredump_put(gpu);
	} else {
		const char *str = "No error state collected\n";
		size_t len = strlen(str);

		if (off < len) {
			ret = min_t(size_t, count, len - off);
			memcpy(buf, str + off, ret);
		}
	}

	return ret;

Annotation

Implementation Notes