drivers/gpu/drm/i915/gt/selftest_engine_pm.c

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/i915/gt/selftest_engine_pm.c
Extension
.c
Size
10029 bytes
Lines
425
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

if (dt > 10000000) {
			pr_err("active wait timed out %lld\n", dt);
			ENGINE_TRACE(engine, "active wait time out %lld\n", dt);
			return -ETIME;
		}
	}

	return 0;
}

static int live_engine_busy_stats(void *arg)
{
	struct intel_gt *gt = arg;
	struct intel_engine_cs *engine;
	enum intel_engine_id id;
	struct igt_spinner spin;
	int err = 0;

	/*
	 * Check that if an engine supports busy-stats, they tell the truth.
	 */

	if (igt_spinner_init(&spin, gt))
		return -ENOMEM;

	GEM_BUG_ON(intel_gt_pm_is_awake(gt));
	for_each_engine(engine, gt, id) {
		struct i915_request *rq;
		ktime_t busyness, dummy;
		ktime_t de, dt;
		ktime_t t[2];

		if (!intel_engine_supports_stats(engine))
			continue;

		if (!intel_engine_can_store_dword(engine))
			continue;

		if (intel_gt_pm_wait_for_idle(gt)) {
			err = -EBUSY;
			break;
		}

		st_engine_heartbeat_disable(engine);

		ENGINE_TRACE(engine, "measuring idle time\n");
		preempt_disable();
		de = intel_engine_get_busy_time(engine, &t[0]);
		udelay(100);
		de = ktime_sub(intel_engine_get_busy_time(engine, &t[1]), de);
		preempt_enable();
		dt = ktime_sub(t[1], t[0]);
		if (de < 0 || de > 10) {
			pr_err("%s: reported %lldns [%d%%] busyness while sleeping [for %lldns]\n",
			       engine->name,
			       de, (int)div64_u64(100 * de, dt), dt);
			GEM_TRACE_DUMP();
			err = -EINVAL;
			goto end;
		}

		/* 100% busy */
		rq = igt_spinner_create_request(&spin,
						engine->kernel_context,
						MI_NOOP);
		if (IS_ERR(rq)) {
			err = PTR_ERR(rq);
			goto end;
		}
		i915_request_add(rq);

		busyness = intel_engine_get_busy_time(engine, &dummy);
		if (!igt_wait_for_spinner(&spin, rq)) {
			intel_gt_set_wedged(engine->gt);
			err = -ETIME;
			goto end;
		}

		err = __spin_until_busier(engine, busyness);
		if (err) {
			GEM_TRACE_DUMP();
			goto end;
		}

		ENGINE_TRACE(engine, "measuring busy time\n");
		preempt_disable();
		de = intel_engine_get_busy_time(engine, &t[0]);
		mdelay(100);
		de = ktime_sub(intel_engine_get_busy_time(engine, &t[1]), de);
		preempt_enable();

Annotation

Implementation Notes