Commit 301e2772 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'drm-intel-gt-next-2024-12-18' of...

Merge tag 'drm-intel-gt-next-2024-12-18' of https://gitlab.freedesktop.org/drm/i915/kernel

 into drm-next

Driver Changes:

- More accurate engine busyness metrics with GuC submission (Umesh)
- Ensure partial BO segment offset never exceeds allowed max (Krzysztof)
- Flush GuC CT receive tasklet during reset preparation (Zhanjun)

- Code cleanups and refactoring (David, Lucas)
- Debugging improvements (Jesus)
- Selftest improvements (Sk)

Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
From: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/Z2KadNXgumx1aQMP@jlahtine-mobl.ger.corp.intel.com
parents bdecb30d f373ebec
Loading
Loading
Loading
Loading
+0 −3
Original line number Diff line number Diff line
@@ -126,9 +126,6 @@ execlists_active(const struct intel_engine_execlists *execlists)
	return active;
}

struct i915_request *
execlists_unwind_incomplete_requests(struct intel_engine_execlists *execlists);

static inline u32
intel_read_status_page(const struct intel_engine_cs *engine, int reg)
{
+5 −0
Original line number Diff line number Diff line
@@ -343,6 +343,11 @@ struct intel_engine_guc_stats {
	 * @start_gt_clk: GT clock time of last idle to active transition.
	 */
	u64 start_gt_clk;

	/**
	 * @total: The last value of total returned
	 */
	u64 total;
};

union intel_engine_tlb_inv_reg {
+0 −9
Original line number Diff line number Diff line
@@ -405,15 +405,6 @@ __unwind_incomplete_requests(struct intel_engine_cs *engine)
	return active;
}

struct i915_request *
execlists_unwind_incomplete_requests(struct intel_engine_execlists *execlists)
{
	struct intel_engine_cs *engine =
		container_of(execlists, typeof(*engine), execlists);

	return __unwind_incomplete_requests(engine);
}

static void
execlists_context_status_change(struct i915_request *rq, unsigned long status)
{
+1 −0
Original line number Diff line number Diff line
@@ -1125,6 +1125,7 @@ static u64 measure_power(struct intel_rps *rps, int *freq)
static u64 measure_power_at(struct intel_rps *rps, int *freq)
{
	*freq = rps_set_check(rps, *freq);
	msleep(100);
	return measure_power(rps, freq);
}

+49 −4
Original line number Diff line number Diff line
@@ -1243,6 +1243,21 @@ static void __get_engine_usage_record(struct intel_engine_cs *engine,
	} while (++i < 6);
}

static void __set_engine_usage_record(struct intel_engine_cs *engine,
				      u32 last_in, u32 id, u32 total)
{
	struct iosys_map rec_map = intel_guc_engine_usage_record_map(engine);

#define record_write(map_, field_, val_) \
	iosys_map_wr_field(map_, 0, struct guc_engine_usage_record, field_, val_)

	record_write(&rec_map, last_switch_in_stamp, last_in);
	record_write(&rec_map, current_context_index, id);
	record_write(&rec_map, total_runtime, total);

#undef record_write
}

static void guc_update_engine_gt_clks(struct intel_engine_cs *engine)
{
	struct intel_engine_guc_stats *stats = &engine->stats.guc;
@@ -1363,9 +1378,12 @@ static ktime_t guc_engine_busyness(struct intel_engine_cs *engine, ktime_t *now)
		total += intel_gt_clock_interval_to_ns(gt, clk);
	}

	if (total > stats->total)
		stats->total = total;

	spin_unlock_irqrestore(&guc->timestamp.lock, flags);

	return ns_to_ktime(total);
	return ns_to_ktime(stats->total);
}

static void guc_enable_busyness_worker(struct intel_guc *guc)
@@ -1431,8 +1449,21 @@ static void __reset_guc_busyness_stats(struct intel_guc *guc)

	guc_update_pm_timestamp(guc, &unused);
	for_each_engine(engine, gt, id) {
		struct intel_engine_guc_stats *stats = &engine->stats.guc;

		guc_update_engine_gt_clks(engine);
		engine->stats.guc.prev_total = 0;

		/*
		 * If resetting a running context, accumulate the active
		 * time as well since there will be no context switch.
		 */
		if (stats->running) {
			u64 clk = guc->timestamp.gt_stamp - stats->start_gt_clk;

			stats->total_gt_clks += clk;
		}
		stats->prev_total = 0;
		stats->running = 0;
	}

	spin_unlock_irqrestore(&guc->timestamp.lock, flags);
@@ -1543,6 +1574,9 @@ static void guc_timestamp_ping(struct work_struct *wrk)

static int guc_action_enable_usage_stats(struct intel_guc *guc)
{
	struct intel_gt *gt = guc_to_gt(guc);
	struct intel_engine_cs *engine;
	enum intel_engine_id id;
	u32 offset = intel_guc_engine_usage_offset(guc);
	u32 action[] = {
		INTEL_GUC_ACTION_SET_ENG_UTIL_BUFF,
@@ -1550,6 +1584,9 @@ static int guc_action_enable_usage_stats(struct intel_guc *guc)
		0,
	};

	for_each_engine(engine, gt, id)
		__set_engine_usage_record(engine, 0, 0xffffffff, 0);

	return intel_guc_send(guc, action, ARRAY_SIZE(action));
}

@@ -1688,6 +1725,10 @@ void intel_guc_submission_reset_prepare(struct intel_guc *guc)
	spin_lock_irq(guc_to_gt(guc)->irq_lock);
	spin_unlock_irq(guc_to_gt(guc)->irq_lock);

	/* Flush tasklet */
	tasklet_disable(&guc->ct.receive_tasklet);
	tasklet_enable(&guc->ct.receive_tasklet);

	guc_flush_submissions(guc);
	guc_flush_destroyed_contexts(guc);
	flush_work(&guc->ct.requests.worker);
@@ -2005,6 +2046,8 @@ void intel_guc_submission_cancel_requests(struct intel_guc *guc)

void intel_guc_submission_reset_finish(struct intel_guc *guc)
{
	int outstanding;

	/* Reset called during driver load or during wedge? */
	if (unlikely(!guc_submission_initialized(guc) ||
		     !intel_guc_is_fw_running(guc) ||
@@ -2018,8 +2061,10 @@ void intel_guc_submission_reset_finish(struct intel_guc *guc)
	 * see in CI if this happens frequently / a precursor to taking down the
	 * machine.
	 */
	if (atomic_read(&guc->outstanding_submission_g2h))
		guc_err(guc, "Unexpected outstanding GuC to Host in reset finish\n");
	outstanding = atomic_read(&guc->outstanding_submission_g2h);
	if (outstanding)
		guc_err(guc, "Unexpected outstanding GuC to Host response(s) in reset finish: %d\n",
			outstanding);
	atomic_set(&guc->outstanding_submission_g2h, 0);

	intel_guc_global_policies_update(guc);
Loading