drivers/gpu/drm/xe/xe_gt_throttle.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/xe/xe_gt_throttle.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/xe/xe_gt_throttle.c
Extension
.c
Size
8070 bytes
Lines
268
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 throttle_attribute {
	struct kobj_attribute attr;
	u32 mask;
};

static struct xe_gt *dev_to_gt(struct device *dev)
{
	return kobj_to_gt(dev->kobj.parent);
}

static struct xe_gt *throttle_to_gt(struct kobject *kobj)
{
	return dev_to_gt(kobj_to_dev(kobj));
}

static struct throttle_attribute *kobj_attribute_to_throttle(struct kobj_attribute *attr)
{
	return container_of(attr, struct throttle_attribute, attr);
}

u32 xe_gt_throttle_get_limit_reasons(struct xe_gt *gt)
{
	struct xe_device *xe = gt_to_xe(gt);
	struct xe_reg reg;
	u32 mask;

	if (xe_gt_is_media_type(gt))
		reg = MTL_MEDIA_PERF_LIMIT_REASONS;
	else
		reg = GT0_PERF_LIMIT_REASONS;

	if (xe->info.platform == XE_CRESCENTISLAND)
		mask = CRI_PERF_LIMIT_REASONS_MASK;
	else
		mask = GT0_PERF_LIMIT_REASONS_MASK;

	guard(xe_pm_runtime)(xe);
	return xe_mmio_read32(&gt->mmio, reg) & mask;
}

static bool is_throttled_by(struct xe_gt *gt, u32 mask)
{
	return xe_gt_throttle_get_limit_reasons(gt) & mask;
}

static ssize_t reason_show(struct kobject *kobj,
			   struct kobj_attribute *attr, char *buff)
{
	struct throttle_attribute *ta = kobj_attribute_to_throttle(attr);
	struct xe_gt *gt = throttle_to_gt(kobj);

	return sysfs_emit(buff, "%u\n", is_throttled_by(gt, ta->mask));
}

static const struct attribute_group *get_platform_throttle_group(struct xe_device *xe);

static ssize_t reasons_show(struct kobject *kobj,
			    struct kobj_attribute *attr, char *buff)
{
	struct xe_gt *gt = throttle_to_gt(kobj);
	struct xe_device *xe = gt_to_xe(gt);
	const struct attribute_group *group;
	struct attribute **pother;
	ssize_t ret = 0;
	u32 reasons;

	reasons = xe_gt_throttle_get_limit_reasons(gt);
	if (!reasons)
		goto ret_none;

	group = get_platform_throttle_group(xe);
	for (pother = group->attrs; *pother; pother++) {
		struct kobj_attribute *kattr = container_of(*pother, struct kobj_attribute, attr);
		struct throttle_attribute *other_ta = kobj_attribute_to_throttle(kattr);

		if (other_ta->mask != U32_MAX && reasons & other_ta->mask)
			ret += sysfs_emit_at(buff, ret, "%s ", (*pother)->name + strlen("reason_"));
	}

	if (drm_WARN_ONCE(&xe->drm, !ret, "Unknown reason: %#x\n", reasons))
		goto ret_none;

	/* Drop extra space from last iteration above */
	ret--;
	ret += sysfs_emit_at(buff, ret, "\n");

	return ret;

ret_none:
	return sysfs_emit(buff, "none\n");

Annotation

Implementation Notes