drivers/gpu/drm/i915/gvt/debugfs.c

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/i915/gvt/debugfs.c
Extension
.c
Size
6379 bytes
Lines
234
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: implementation source
Status
source 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

struct mmio_diff_param {
	struct intel_vgpu *vgpu;
	int total;
	int diff;
	struct list_head diff_mmio_list;
};

struct diff_mmio {
	struct list_head node;
	u32 offset;
	u32 preg;
	u32 vreg;
};

/* Compare two diff_mmio items. */
static int mmio_offset_compare(void *priv,
	const struct list_head *a, const struct list_head *b)
{
	struct diff_mmio *ma;
	struct diff_mmio *mb;

	ma = container_of(a, struct diff_mmio, node);
	mb = container_of(b, struct diff_mmio, node);
	if (ma->offset < mb->offset)
		return -1;
	else if (ma->offset > mb->offset)
		return 1;
	return 0;
}

static inline int mmio_diff_handler(struct intel_gvt *gvt,
				    u32 offset, void *data)
{
	struct mmio_diff_param *param = data;
	struct diff_mmio *node;
	u32 preg, vreg;

	preg = intel_uncore_read_notrace(gvt->gt->uncore, _MMIO(offset));
	vreg = vgpu_vreg(param->vgpu, offset);

	if (preg != vreg) {
		node = kmalloc_obj(*node, GFP_ATOMIC);
		if (!node)
			return -ENOMEM;

		node->offset = offset;
		node->preg = preg;
		node->vreg = vreg;
		list_add(&node->node, &param->diff_mmio_list);
		param->diff++;
	}
	param->total++;
	return 0;
}

/* Show the all the different values of tracked mmio. */
static int vgpu_mmio_diff_show(struct seq_file *s, void *unused)
{
	struct intel_vgpu *vgpu = s->private;
	struct intel_gvt *gvt = vgpu->gvt;
	struct mmio_diff_param param = {
		.vgpu = vgpu,
		.total = 0,
		.diff = 0,
	};
	struct diff_mmio *node, *next;
	intel_wakeref_t wakeref;

	INIT_LIST_HEAD(&param.diff_mmio_list);

	mutex_lock(&gvt->lock);
	spin_lock_bh(&gvt->scheduler.mmio_context_lock);

	wakeref = mmio_hw_access_pre(gvt->gt);
	/* Recognize all the diff mmios to list. */
	intel_gvt_for_each_tracked_mmio(gvt, mmio_diff_handler, &param);
	mmio_hw_access_post(gvt->gt, wakeref);

	spin_unlock_bh(&gvt->scheduler.mmio_context_lock);
	mutex_unlock(&gvt->lock);

	/* In an ascending order by mmio offset. */
	list_sort(NULL, &param.diff_mmio_list, mmio_offset_compare);

	seq_printf(s, "%-8s %-8s %-8s %-8s\n", "Offset", "HW", "vGPU", "Diff");
	list_for_each_entry_safe(node, next, &param.diff_mmio_list, node) {
		u32 diff = node->preg ^ node->vreg;

		seq_printf(s, "%08x %08x %08x %*pbl\n",
			   node->offset, node->preg, node->vreg,

Annotation

Implementation Notes